史上最簡單的推薦系統設計

發表於2019-05-11

[img=推薦系統,設計]https://jf-bucket-public.oss-cn-qingdao.aliyuncs.com/jfperiodical/attached/image/20150911/-1310978209.jpg[/img]

推薦系統聽上去是高大上的東西,在網際網路多個場景中有廣泛應用
 
場景1:你在google或百度的廣告後臺,輸入一個關鍵詞提交競價,那麼系統就會推薦很多認為你可能需要的關鍵詞。

場景2:你在小遊戲網站玩一款小遊戲,旁邊會提示你可能喜歡玩的其他小遊戲。

場景3:你在電子商務網站下訂單完成購物,底下有一欄推薦你購買的其他產品。

類似場景是不是很熟悉?
 
現在推薦系統也被定義為大資料的一種典型應用,很多公司給出高薪,不惜代價,要挖能實現推薦系統,機器學習的演算法達人。
 
聽上去很動心是不是,然而,抱歉,我教不了你出去混高薪的那些招,原因很簡單,我也不會。 我的水平很low,沒辦法在演算法上和資料探勘技巧上指導別人,但我有很low的方法,而且在使用中,居然是管用的,如果你已經研究過多款成功的推薦系統,或者自己在以前的學習過程中掌握了非常強大的推薦演算法,請忽略此文,以免耽誤您的時間;但換過來,如果您是一個小公司的創業者,一個正在努力提升的基礎程式設計師,一個公司還沒有搭建推薦系統並且給出了很高的條件找不到合適人才正在發愁的老闆,也許這篇文章可以幫到你。
 
應該是2005年的時候,我對十年前的具體時間記得不是很準確,也許是2006,反正就是那段日子裡,百度當時還很弱小,公司內的系統也不復雜,很多東西做的也不是很高大上,嗯,也正是因此,我才有機會去嘗試一些很low但是有用的東西。 當時想試著把商業關鍵詞聚合起來,把關鍵詞的關聯和分類做出來,但是我完全沒經驗,就去請教與我配合的工程師,張懷亭(現在是跟誰學的聯合創始人,CTO)。他說他以前研究生課題就是這個,然後給我看了一篇他寫的論文,然後,我發現,我完全看不懂! 只好死皮賴臉的去請教,雖然演算法看不懂,又聽不懂,但不斷追問下好歹明白了幾個最基本的概念,第一,相關推薦的資料基礎是共同推舉數,所謂共同推舉數就是,有多少人共同選擇了A和B,共同推舉越高,顯然相關性越高。第二,如果單純以共同推舉數為推薦的依據,可能會出現一些非常不合理的結果,比如推薦關鍵詞時,相關度未必很高的熱門詞會佔主要位置,推薦遊戲時也會出現一水的熱門遊戲,而不是高度關聯的遊戲。所以不能完全依賴於推舉數。基於這些粗淺的理解,我忽略了其他不懂的部分,用簡單粗暴,毫無技術含量的方式做了一套關鍵詞的關聯和推薦模型,跑出來看結果還可以,程式碼量,哦,一個下午。
 
我們以商業關鍵詞的關聯為例來說明,每個廣告主會選擇多個關鍵詞,我認為這是我們的資料來源,資料結構只取最簡單的,廣告主id,關鍵詞。   當然,如果我們做電商,可以用消費者購買清單,如果做遊戲,可以用玩家玩過的遊戲清單,其思路完全一致。
 
第一步,資料準備

資料來源 廣告主的競價記錄資料表,忽略價格等其他因素,只取廣告主id,關鍵詞 兩個欄位。

遍歷該資料,整理出兩個新的結構

結構1:關鍵詞熱度表

關鍵詞,總推舉數

結構2:廣告主熱度表

廣告主,總提交詞數
 
第二步 關聯度計算
 
遍歷廣告主表,

        將該廣告主的所有提交關鍵詞拿出來,做彼此的加權累加。

       (這個地方我簡單解釋一下,如果一個廣告主提交了100個關鍵詞,就是100*99的迴圈,讓每兩個關鍵詞都進行關聯度權值的計算,這個程式設計師應該都會吧)

         (權值的計算,我承認我是拍腦袋的,根據實際,通過對結果的檢查和反思,這裡可以改,我們假設目前計算關鍵詞A和關鍵詞B的權值,在每個自迴圈最內進行權值的累加計算, 權值(A,B)=權值(A,B)+1/(B的共同推舉數開方*當前廣告主提交詞數的開方), 也就是降低熱門詞的權值,以及,一個廣告主如果提交了太多關鍵詞,也降低相關權值。請注意這裡還有一個權值(B,A)=權值(B,A)+(1/A的共同推舉數開方*當前廣告主提交詞數的開方),權值(A,B)並不等於權值(B,A),這裡需要特別說明一下。)
 
第三步,結果彙總並優化

資料結構為,關鍵詞1,關鍵詞2,權值。
 
一對關鍵詞會出現A,B,權值(A,B)和 B,A,權值(B,A),這是有意義的。
 
下面說幾個問題
 
第一,遍歷迴圈會不會太大,比如一個廣告主提交了5萬個關鍵詞,是不是要執行25億次的迴圈? 對不起,一個廣告主如果提交了太多關鍵詞,我認為這些詞彼此關聯性並不大,如上面公式所示,所以,提交超過1000詞的直接忽略掉,算都不算。這樣計算量就極大降低了。 嗯,偷懶就是這麼有藉口。
 
第二,最後結果及中間陣列內容會不會太大,會的! 這裡我要提及一個特別重要的原則,那就是,實際我們並不需要完全保留每兩個詞之間的相關性,當我去看特定詞的時候,系統給出推薦幾十個已經足夠了,所以,我其實只要儲存 每個關鍵詞的top100相關詞就可以,不用所有的結果都存下來。而中間資料,我用了一個簡單粗暴的方法,就是每執行一些記錄,就把當前的所有關鍵詞的top詞表記錄到一個臨時表,然後清空記憶體重新統計,到最後把這些top相關詞的臨時表按照關鍵詞排序再跑一遍做累加就可以了。
 
so,其實就是這麼簡單。
 
沒有演算法,沒有高逼格的技術,就是最基本的迴圈,計算,然後寫入資料表。

下面留一下思考題,都是之前我處理過的,當然,都是用比較簡單粗暴的方式處理完的,有興趣的童鞋可以想想
1、以小遊戲網站為例

資料結構如下

遊戲A,遊戲B,相關權值
 
目前已知有5萬款小遊戲,平均每款有50條記錄,也就是資料表有250萬條記錄。

使用者中心,某玩家登陸後,檢索出他歷史玩過的小遊戲清單,取最新的20條,基於這20條他玩過的最新小遊戲,系統推薦一些其他遊戲給他。
SQL 如下
完整內容點此檢視
回覆

相關文章