做爲一個推薦系統業餘愛好者,在機器學習領域的鄙視鏈中,我感受一直地位不高,時常被搞NLP CV語音等高科技技術的朋友鄙視。python
最近甚至被人問,推薦算法開源包多如牛毛,咱們爲何還要專門的推薦算法工程師?(難道想要辭退我!?驚)程序員
不得不說,我想吐槽這個觀點好久了。事實上搞推薦的工做不等於 import IBCF 或者 import time SVD++ import tensor啊摔!算法
因而找回賬號打開N年不用的博客,寫一篇隨想,其中含有大量主觀臆斷以及學術錯誤,儘可能不中英夾雜術語以外的英文,若是有不一樣意見,歡迎回復指正。多線程
說實在如今推薦包太多了,單機小規模實驗的R包recommenderlab;慢的不行可是可以hadoop擴展的mahout;C++的eigen也給你們指明瞭一條矩陣運算的活路;matlab裏各類memory based、model based、learning to rank算法包更是漫天飛;拿到風投的graphlab更是打出了號稱五行代碼動手寫推薦系統的口號,還附帶各類FM模型以及一健運行deep learning的套餐供你們玩耍;想要本身感覺DIY的快樂,還有libFM;嫌慢可使用SVDfeature簡化套餐,還支持多線程硬盤計算,2G筆記本就能夠建模2T數據。架構
(五行實現一個推薦系統,你怕不怕)app
那作一個推薦系統,看來確實不須要專門的推薦算法工程師了,import xx便可。機器學習
事實上並非這樣,其問題在於幾個方面:1.業務轉化數學問題 2.數據特性定義active function 3.根據業務定義合理損失函數 4.損失函數求解調優 5.計算量太大的離線算法優化和線上算法優化。分佈式
咱們能夠看到,一個完整的推薦系統項目不能靠import xx實現的至少有上述幾點。可以把這5點走通玩好,纔是老闆養這樣幾個工資萬兒八千每天看起來整天只會看動畫無所事事的推薦算法工程師的緣由。函數
1.業務轉化數學問題oop
通常一個項目啓動都是老闆說,咱們公司的如今電話銷售(app下載、商品銷售、淘寶客收入等等)挺不錯的,可是推薦欄的那個IBCF算法太搓,或者人工運營太累,大家能不能搞個推薦提升下轉化率?
和作學術以及競賽不同,咱們並不知道有哪些數據,也不知道要作成什麼形式,推薦位放在哪,UI怎麼搞比較好,這些都是須要和業務方一塊兒磋商定稿的。
以電話銷售爲例,咱們須要給電話銷售人員一個列表,告訴他你今天給這樣幾我的推銷這樣幾個商品會比較好。而後開工了,咱們須要跟業務人員在一塊兒商量,到底用什麼數據可以完整的體現一個銷售人員給特定的客戶推銷什麼商品會成功?以此爲依據決定收集什麼樣的數據,而非通常書籍裏講述的,僅僅使用用戶商品矩陣這麼清爽明快的事情。
以這個特定問題爲例,咱們須要的是銷售人員數據,用戶數據,商品數據,用戶商品交互數據,銷售人員商品交互數據,銷售人員用戶交互數據。其中用戶商品交互數據中的很小一塊即是不少開源包可用的UI矩陣。
數據收集來了以後對數據作統計,消除特殊活動以及廣告引流等影響,搞定缺失值、默認值、異常值等問題。裏面還常常會遇到一些機器學習的子問題要處理,好比垃圾用戶怎麼排除(基於強規則弱規則構造特徵作一個小分類器之類的)。
填完這些坑,每每半個月一個月過去了,還很是辛苦(個人感受是:程序員來自地球,業務人員來自火星)。。。。
2.數據特性定義active function
繼續拿上面那個問題說事,數據清洗好該構造特徵定義active function了。
active function是我隨便叫的,或者叫model equation?總之咱們若是假設特徵相互獨立,那麼就是 y=wx 這種;若是認爲特徵集之間會有交互,咱們有兩種方法,第一種是作一個 low rank 假設,好比 SVD 的 y=pq這種形式,就是對於用戶商品交互特徵進行建模;另一種就是寫成y=wij*xi*xj這種形式。前面一種是 factorization models 的搞法,後面一種是 用rf或者gbrt的交叉特徵的搞法。
對於咱們這個問題來看,銷售人員特徵、用戶特徵、商品特徵這種就屬於wx這種形式;而銷售人員商品交互特徵、用戶商品交互特徵、銷售人員用戶交互特徵這種就屬於y=sq+sp+pq(銷售s,用戶p,商品q)這種形式。
因此總體來看咱們問題的定義下來,active function應該爲y = wx + sq + sp + pq的形式。順便一說,考慮到時間因素,還要再加上好幾個t的項(若是採用pairwise interaction tensor的形式的話)。
定義好形式就能夠抽取特徵了,而後按照 categorical variables以及noncategorical variables的形式整理好,這時候就能夠開心用包啦!
打個比方,libFM就提供了一個建模的通用式子
分別是bias,獨立特徵以及交互特徵,通常人常說的IBCF,SVD等都是這個式子的特殊形式而已。
順便這裏說下,如今搞推薦的,通常兩種流派,一種是用MF的,一種是用LR,RF,GBRT上高維特徵的,常常吵的勸都勸不動。
我以爲這個只是數據特性的兩種active function定義的傾向而已。
前者考慮到不一樣categorical variable的交互。對於wij,咱們常常是很難觀測到行爲的,好比用戶i給電影j的行爲,已經觀測到才能估計wij,可是這表示他已經看了電影了,那推電影j就沒意義了,因此咱們使用pi*qj來近似wij。
後者通常不考慮categorical variable的交互,或者他們能觀測到wij對應的xi*xj的行爲,因此直接用分類迴歸模型求解wij而無需使用low rank假設。好比說天貓商品推薦,用戶想買一個商品,常常會有點擊搜索行爲,這種xi*xj就是可觀測的了,因此直接上rf或者gbrt就是合理的。其active function的通式爲這個:
因此一句話,沒有所謂推薦算法哪家強,只有合適的應用場景對應的合適的active function,而後影響到咱們是用MF仍是LR RF這種。觀測不到或者觀測不多用前者,反之用後者。或者兩個都上,作ensamble(有計算資源,就是這麼任性)。
3.根據業務定義合理損失函數
這又是一個比較有爭議的話題,不過也是推薦從業人員的工做核心所在,大概要忙活一下午?
通常的損失函數有三種,1.迴歸 2.分類 3.排序
好比說:,
說實在,我幹活歷來不用前面那種,只有競賽明確指明排行榜按照RMSE排序纔會用前者。由於咱們常常要作的是top-N的排序,對於用戶給商品打分估計準了,可是轉化率提不上去沒用,由於用戶只考慮買仍是不買,不少研究也指出RMSE跟轉化率和top-N不是很搭。
說到損失函數不得不說最近很火的learning to rank,其損失函數是MRR這種直接優化排序的,相比AUC等考慮全局排序或者甚至只是point wise的分類系列損失函數,從理論上來講更加合理。其損失函數是個非凸損失函數,咱們通常把其近似爲凸函數求解(實際上仍是有點坑)。
而後咱們要考慮損失函數是否帶權,以及正則的問題。帶權主要是好比一個商品推成功了賺5毛,一個商品推成功了賺50,天壤之別,這就要結合業務來定義了。正則通常上L2,好比這種
另外不少人以爲損失函數定義成怎樣對結果影響不大,我以爲吧,仍是頗有影響的吧摔。
4.損失函數求解調優
在給定對數據的觀測下定義優化問題求解優化問題一直是機器學習的主旋律,俗話說,數據挖坑一身功力全在調優(並非)。
咱們通常要選擇一個科學的適合現狀的方法,還有搞好超參數。
拿經常使用的推薦系統優化方法來講,SGD,ALS以及MCMC通常的算法包都會提供。以LibFM爲例對比三種方法:
能夠看到,新手用MCMC inference最好。在推薦的問題中,通常只須要調兩個超參數就好,factor的dimension k以及對factor初始化的高斯分佈的std。k通常從小的着手,5啊8啊都是不錯的作第一次調參的選擇,太大容易過擬合。std對結果影響很大。不過好在也比較好調,通常選擇0.1 0.2 0.5 1.0這種,並且咱們通常在迭代的初期就能夠經過觀測training error的方式就能夠肯定了,甚至比經常使用的開源包的實現方式(從train裏摳一部分作holdout set作觀測)還好。
若是是高手,能夠挑戰SGD,SGD的參數除了MCMC的那幾個,還有幾個很是很差調的參數,有正則項的lambda以及學習速率。正則項沒辦法,只能靠grid search。學習速率更坑,高了不收斂,低了跑的慢,具體什麼速率好只有上帝知道。(最好是0.0127這種,不要是10的倍數,我瞎說的)。
總之,這塊也是一個具備挑戰性和技術性的不能自動化的工做。
5.計算量太大的離線算法優化和線上算法優化
算法通常分好幾個部分,通常有線下部分和線上部分,好比不少作法是線下選離線商品池子,線上CTR預估。這樣就涉及到大量的離線評測和線上算法架構。
通常的公司項目的數據量都是單節點運算支撐不起的。百萬級有行爲用戶和幾十萬的商品都是很常見的,小規模也有幾萬,因此要離線評測通常須要並行和分佈式。這些也是很難自動化的。
對於數據的預處理和特徵的構造,通常都是數據並行,規模不是特別大的log或者不是太多冗餘的文本,python腳本nohup也是個不錯的選擇,或者用hadoop寫MR。模型的算法並行看狀況,通常的MF類型模型能夠O(kN)求解,單機寫的性能高點小時級別仍是能夠出結果的(好比SVDfeature這種),或者公司有條件上MPI,本身寫spark也能夠,可是沒有看到成熟的成功案例?還有用graphlab這種性能也是不錯的。
線上的話架構等模型定下來作LR這種,有實時的特徵(最近30個點擊這種),也有離線算好的,通常會對用戶大致離線算個離線池子,這樣線上壓力小,storm都是不錯的選擇,反正不須要實時訓練,數據增量記錄好一天甚至一週一迭代就好。
固然要上線要經歷九九八十一難,某廠一個產品離線到AB test上線到最後,存活率不足1%,還要根據線上結果咔嚓掉一半,這些也是工程師要經歷的磨難。
因此說了這麼多,就是說,報告老闆,當推薦算法開源包多如牛毛,咱們還要專門的推薦算法工程師的!有好多事情可作的!(因而個人飯碗保住了,又能夠愉快看動畫片在B站自由飛翔了)
不少地方寫了後面忘記前面,你們有什麼想法快來交流,相互提升,郵件交流(我近期興趣點在於如何有效利用外源數據提升推薦效果以及learning to rank調優這塊) flclain@gmail.com