1. 程式人生 > >推薦引擎的離線演算法和線上演算法初探

推薦引擎的離線演算法和線上演算法初探

推薦引擎是阿里雲的一套推薦服務框架。大家可能在淘寶上很早就聽過“個性化推薦”、“千人千面”一類的詞,對於為什麼能把喜歡的寶貝準確得推給不同的買家感到好奇,希望自己也能有這樣一套推薦系統吧。這篇帖子,就以推薦引擎產品上的離線演算法和線上演算法給大家說明下,並且方便後續如果在產品使用中如果發現通用的計算規則不符合自己的場景的時候,需要做一些優化的時候,也能更好地指導怎麼調。
如果是最開始的怎麼使用產品,可以看產品文件,和視訊

系統架構

推薦引擎是怎麼工作的,為什麼只需要提供一些使用者、商品、行為資料,就知道誰誰喜歡什麼呢?我們可以一起來看下文件裡的一個圖,推薦引擎的框架大概是這樣:
screenshot
咱們先不討論API寫入和實時修正一段。資料從MaxCompute準備好,到最後能被呼叫,實時地生成推薦結果,需要經過2個步驟:要先在離線計算裡計算出推薦結果,離線計算的結果會被儲存到表格儲存裡。第二步會通過線上演算法,對推薦結果進行加工並展示。所以,如果算的結果不對,比如推薦了個完全不相干的商品,那就查離線演算法。比如召回個數要調整,或如果召回數量過少用預設值去填充一類的需求,就要在線上演算法上下功夫(當然預設值的生成可能需要用到離線計算)。線上演算法和離線演算法是配合使用的,所以可以看到模板裡也是配套的。

離線計算

我們從預設detail模板(detail_ofl)去了解離線演算法。開啟這個演算法,可以看到這個演算法的流程圖是這樣:
screenshot
這個圖裡的每個線表示任務的依賴。這樣看起來還不直觀,我做了下修改:
screenshot
可以看到detail_ofl模板的離線計算其實是有2條主線,一條是通過crs_04和crs_02各自生成item_item_rec_list,最後通過st_cb_01整理成一張對外輸出的結果。另外一條是crs_05和crs_03生成user_item_rec_list,最後通過st_cb_02整理成一張結果表。item_item_rec_list表裡記錄了根據item來進行推薦的結果,可以理解成這兩個商品比較接近,比如啤酒和尿布的例子就是典型的item_item_rec的例子。而user_item_rec_list是針對使用者進行推薦的,比如說系統發現我和你都是跑步愛好者。有一天我買了雙不錯的鞋子,然後可以猜你可能也會喜歡。

線上計算

我們來看下detail_ofl配套的線上演算法,流程圖是:
screenshot
這個圖比較簡單,先用mg_usr_itm_reclist把離線演算法的item-base和user-base推薦結果。item_item_rec_list的資料被放在前面,因為一般來說,根據item召回的結果數量會比較少但是相對比較準確。鑑於兩個union all後可能出現走item-base和user-base都會推薦同一個商品,於是接著做了個uniq_reclist進行去重。最後用一個get_top來設定召回個數(也就是最開始我們提到的問題)。

其他演算法

看好了detail模板,我們再來對比一下main模板,會發現更加簡單了。首頁推薦就是根據人進行推薦,沒有item的部分,所以其實就是detail模板的st_cb_02,計算user_item_rec_list線。對應的線上演算法裡,沒有兩個表的結果的聚合去重,只有get_usr_based_rec來獲得user的召回結果,再過一下topn就好了。

然後我們再看下detail_dft,其實就是在detail_ofl基礎上,用simple_default_list計算預設的推薦列表。然後用對應的線上模板裡的get_default_rec來補足。

最後我們再來看個演算法,就是快速入門裡的用電影資料進行電影推薦的例子,例子裡針對對電影的評分,來篩選出每個人對電影的喜愛程度,這個資料需要用的是spl_grd_svd。而如果用了detail_ofl來算的話,會在資料離線計算的時候報錯。對比一下兩個模板,可以發現spl_grd_svd開始用的是grade_based_sm,而detail_ofl用的是ig_sm_02。ig_sm_02用的是'click','search_click','consume','use','read','collect','comment','share','like','view',而grade_based_sm只選擇bhv_type='grade'對應的bhv_amt作為評分進行計算。如果針對電影資料使用detail_ofl,發現裡面只有grade的操作,沒有其他的行為,會因為沒有找到使用者行為資料而報錯。

演算法類目

可以看到演算法的框架是定的,如果後面需要修改,也不是完全推翻重頭做起。可以選一個模板在其基礎上做修改。每個演算法都有各自的資料輸入、輸出,有一些演算法其實只是演算法的內部不一樣,輸入輸出,用在什麼上下游一樣。所以後面如果要根據自己的實際資料寫自定義演算法,可以先根據前面提到的,找到其中哪個步驟覺得演算法還可優化的,然後針對地寫個演算法替換。是不是看起來很像是在搭積木,用一個同樣形狀的積木來代替以前的元件。這樣一個個相同的積木,就叫做一個類目。在自定義演算法的時候,需要設定演算法的類目,也正是這個意思。

經過以上的介紹,大家應該對推薦引擎的計算邏輯有一個大致的理解。不過實踐出真知,紙上談兵不如動手做一個,你說呢~

閱讀原文:

http://click.aliyun.com/m/13855/