自己动手写一个推荐系统,推荐系统小结,推荐系统:总体介绍、推荐算法、性能比较, 漫谈“推荐系统”, 浅谈矩阵分解在推荐系统中的应用...
自己動手寫一個推薦系統
廢話:
最近朋友在學習推薦系統相關,說是實現完整的推薦系統,于是我們三不之一會有一些討論和推導,想想索性整理出來。
在文中主要以工程中做推薦系統的流程著手,穿插一些經驗之談,并對于推薦系統的算法的學術界最新的研究進展和流派作一些介紹。當然由于我做推薦系統之時還年幼,可能有很多偏頗甚至錯誤的見解,就當拋磚引玉,還請各位大大指點。
?
?
Reading?lists
雖然很多人覺得作為AI的分支之一,推薦跟自然語言處理等問題的難度不可同日而語。但所謂磨刀不誤砍柴工,我覺得,至少在開工前先應該閱讀這樣基本書,起碼要看看目錄,以對于推薦系統有個初步的了解。
?
中文書籍:
1.《推薦系統實踐》項亮http://book.douban.com/subject/10769749/
這本書你說他好吧,不如recommend?handbook;你說他不好吧,確實又把很多基礎而簡單的問題講的很詳細,而且還是中文的。薄薄的一本書,分分鐘可以翻完,總而言之,是一本入門的好書。
?
外文書籍:
1.《Recommender?Systems?Handbook》Paul?B.?Kantor??http://book.douban.com/subject/3695850/
其實所有敢自稱handbook的書都是神書。這本書寫的非常細,而且非常全,如果你去看一些推薦系統的一些比較冷門的topic的paper,比如fighting?spam的,甚至能發現很多paper就是直接引用這本書里相關章節的內容。可以說這本書是做推薦同學必備的枕邊書,沒看過這本書出去吹牛逼時你都不好意思說自己是做推薦的,不過說實在,真正看完的沒幾個,一般是用到哪里查哪里,我剛才就去豆瓣驗證了,幾個做推薦的都是在讀,一群文藝青年都是想讀。此書唯一的缺點是沒有出新版,有些地方已經成為時代的眼淚了。
?
?
2.《Recommender?Systems?-?An?Introduction》?Dietmar?Jannach?
http://book.douban.com/subject/5410320/
跟上面一本差不多,學院派的綜述型的書,厚厚一本,不看的時候當枕頭用。
?
3.《mahout?in?action》Sean?Owen?http://book.douban.com/subject/4893547/
上面的一中一外的書都是理論基礎的書,這本書就和工程有些沾邊。如果你要用mahout框架來做推薦系統,那么是必須要掃一遍的;如果你不用mahout,看看其中的流程和代碼組織也是有一定好處的。
?
Paper:
由于《Recommender?Systems?Handbook》很多地方已經成為了時代的眼淚,這里推薦一些綜述,以便開闊眼界。
一篇是physics?report上面的recommend?system這篇綜述,可以說是最新最全的綜述了,看完后學術界都在折騰啥分分鐘就清楚了。http://arxiv.org/pdf/1202.1112v1.pdf
比較經典的是recommend?system的state?of?art這篇綜述,很多老一輩的同志喜歡推薦的,說實在這篇因為年代久遠,也已經成為時代的眼淚了。
?
開工:
上面給了一些reading?lists,并不是說要讀完所有的才能開工,只是說,先看完個目錄,哪里不懂查哪里。在下面介紹的做推薦系統的流程中,我只是想給大家介紹個普通的推薦系統該怎么做,所以很多地方都有偷懶,還請大家見諒。而且由于我不是做的在線的推薦系統,而是屬于隔天推薦的那種離線的,所以敘述工程的時候就是只敘述離線的推薦。
?
數據準備:
一般來說,做推薦系統的數據一般分兩種,一種從在線的讀取,比如用戶產生一個行為,推薦系統就反應下(傳說豆瓣fm就是這么做的?),還有一種就是從數據庫里讀。
我個人一般是這樣做的:跟做反作弊的人打個招呼,讓他們在記用戶行為數據的時候順便存到各個線上服務器上,再寫個php腳本,從各個服務器上把我需要的日志抓過來,然后當日要的最新的數據就來了。
但是這種地方其實存儲的數據是加了一些判斷的,也就是說是分類記錄的(因為很多記錄是別人刷的,比如丟一個鏈接到qq群里讓別人幫忙投票什么的),這里不細說,到后面fighting?spam的地方再討論。
?
數據過濾:
當我們得到了每天產生的數據后,說實在這些數據實在是太多了,我們當然用不到這么多,就要寫個過濾模塊,把一些我們用不到的數據過濾掉。
我一般是這樣做的:寫個python的腳本,把過濾器放到一個單獨的模塊,要用的過濾器就到責任鏈里面注冊下。這樣別人和自己維護起來也方便點,順便一說,過濾的東西一般來說有這樣幾種:一種是一個item只有一個user打過分的,而且以前沒有人打分的,這樣的數據放到推薦的模型里去跑雖然mahout會自動無視它,但其實按照power?law來說是有不少的,內存能省就省吧;還有一種是有些黑名單的,有item和user各自的黑名單,這些也是事先要去掉的。
?
數據存儲:
這個就是大家仁者見仁,智者見智的時候了,因為一般來說,是你選用的算法和算法具體的實現方式以及基礎架構決定了你的存儲方式,就不多說了。
我一般是這樣做的:一般做成增量處理的方式,然后每天一計算,一周一回滾。由于算法實現的特殊性,每40個item?user對存儲在一起,有點類似于bitmap吧。
?
推薦系統算法部分:
這部分以前寫過類似的小記錄和心得筆記之類的東西,就直接貼了_(:з」∠)_
這里的推薦系統的核心算法主要用mahout實現。
?
各種算法對于推薦都有著自己的特定的假設,對于什么時候什么樣的算法會有比較好的performance應該對于假設反復驗證。說白了就是做實驗。
?
然后我們一般用什么算法呢,看看mahout給的算法吧,花樣繁多,什么item?based,user?based,slop-one,SVD等等,常用的都有了,那我們要用什么算法呢。
先簡單說下user?based的算法在mahout中的一些實現:
第一步應該先算出所有人的相似度矩陣W,再去對于item進行遍歷,事實上mahout也是這樣做的。
相似度矩陣也許可以保留下來,這樣可以用來做譜聚類來驗證。
UserSimilarity?封裝了用戶之間的相似性
UserSimilarity?similarity?=?new?PearsonCorrelationSimilarity?(model);
UserNeighborhood封裝了最相似的用戶組
UserNeighborhood?neighborhood?=?new?NearestNUserNeighborhood?(2,?similarity,?model);
總而言之,用DataModel來生成data?model,用UserSimilarity生成User-user之間的相似度矩陣,用戶的鄰居的定義用UserNeighborhood定義,推薦引擎使用Recommender實現。
?
對于推薦的評判是使用evaluator來進行評判?
double?score?=?evaluator.evaluate(recommenderBuilder,?null,?model,?0.95,?0.05);
用95%的數據構建模型,用5%的數據進行test
?
Fixed-size?neighborhoods
對于到底用多少人作為用戶周圍的一圈,我們事實上沒有一個確定的值,就像做生物實驗一樣需要不斷在特定的數據集里跑出來。
?
Threshold-based?neighborhood
當然,我們也可以定義個threshold去找出最相似的用戶群。
Threshold定義為-1到1(相似度矩陣返回的相似度就是在這個范圍)
new?ThresholdUserNeighborhood(0.7,?similarity,?model)
?
我們對于各個算法做個簡單的比(吐)較(槽):
(假設我們是要像亞馬遜一樣對商品做推薦,然后我們最終是要做top?k的推薦)
?
Item?based
一般來說item-based要跑得快一些,因為item比user少
?
Slop?one
說實在話我覺得在對于一些個人品味比較看重的東西上這個算法不是很靠譜
但是它在GroupLens?10?million數據的結果是0.65
當然,對于股票系統這種還是可取的
這個算法的假設是對于不同item的preference有種線性關系
不過slope-one有個好處是它的online算的很快,并且它的性能不由用戶的數量決定
在mahout中的調用方法是new?SlopeOneRecommender(model)
這個方法提供了兩種weight:weighting?based?on?count?and?on?standard?deviation
count?是越多的user的給越多的權重,對出的是一個加權的平均數
standard?deviation則是越低的deviation給予越高的權重
這兩個weight是默認采用的,當然disable它們只會讓結果變得稍微壞一點0.67
不過這個算法有個很明顯的缺點是比較占內存
但是幸運的是我們可以把它存在數據庫里:MySQLJDBCDataModel
?
Singular?value?decomposition–based?recommenders
事實上,盡管SVD失去了一些信息,但是有時候它可以改善推薦的結果。
這個過程在有用的方式平滑了輸入
new?SVDRecommender(model,?new?ALSWRFactorizer(model,?10,?0.05,?10))
第一個參數10是我們的目標屬性個數
第二個屬性是lambda->regularization
最后一個參數是training?step跑的次數
?
KnnItemBasedRecommender
囧,事實上這個是用的knn的方式來做的算法,和前面的選擇一個threshold然后圈畫用戶的算法是比較像的
但是用knn代價是非常高的,因為它要去比較所有的items的對
ItemSimilarity?similarity?=?new?LogLikelihoodSimilarity(model);
Optimizer?optimizer?=?new?NonNegativeQuadraticOptimizer();
return?new?KnnItemBasedRecommender(model,?similarity,?optimizer,?10);
結果也還不算差,是0.76
?
Cluster-based?recommendation
基于聚類的推薦可以說是基于用戶的推薦的算法的變體中最好的一種思路
對于每一個聚類里面的用戶進行推薦
這個算法在推薦里面是非常快的,因為什么都事先算好了。
這個算法對于冷啟動還是挺不錯的
感覺mahout里面用的聚類算法應該類似于Kmeans?
TreeClusteringRecommender
UserSimilarity?similarity?=?new?LogLikelihoodSimilarity(model);
ClusterSimilarity?clusterSimilarity?=
new?FarthestNeighborClusterSimilarity(similarity);
return?new?TreeClusteringRecommender(model,?clusterSimilarity,?10);
注意的是兩個cluster之間的相似度是用ClusterSimilarity來定義的
其中cluster之間的相似度還有NearestNeighborClusterSimilarity可選
?
吐槽:
對于算法的選擇,其實我們是要和我們要推薦的目標掛鉤的。為什么最近學術界搞SVD那一系的算法這么火,什么LDA,plsa各種算法層出不窮,事實上因為netflix的要求是要優化RMSE,在機器學習的角度來看,類似于回歸問題,而工業界的角度來說,我們一般的需求是做top?k的推薦,更加類似于分類問題。所以為什么相比用SVD系列的算法,用item?based這種更加ad?hoc的算法要表現的更好一些。當然2012年的KDD?cup第一名的組用的是item?based+SVD的算法,這是后話。
?
那么我就假設解我們這個top?k的商品推薦的問題就用item?based好了(速度快,結果又不算差),接下來就是確定相似度了。
?
相似度確定:
?
我們對于各個相似度做一些比(吐)較(槽):
PearsonCorrelationSimilarity
Pearson?correlation:
coeff?=?corr(X?,?Y); ??
function?coeff?=?myPearson(X?,?Y)
%?本函數實現了皮爾遜相關系數的計算操作
%
%?輸入:
%???X:輸入的數值序列
%???Y:輸入的數值序列
%
%?輸出:
%???coeff:兩個輸入數值序列X,Y的相關系數
%
?
?
if?length(X)?~=?length(Y)
????error('兩個數值數列的維數不相等');
????return;
end
?
fenzi?=?sum(X?.*?Y)?-?(sum(X)?*?sum(Y))?/?length(X);
fenmu?=?sqrt((sum(X?.^2)?-?sum(X)^2?/?length(X))?*?(sum(Y?.^2)?-?sum(Y)^2?/?length(X)));
coeff?=?fenzi?/?fenmu;
?
end?%函數myPearson結束
?
當兩個變量的標準差都不為零時,相關系數才有定義,皮爾遜相關系數適用于:
(1)、兩個變量之間是線性關系,都是連續數據。
(2)、兩個變量的總體是正態分布,或接近正態的單峰分布。
(3)、兩個變量的觀測值是成對的,每對觀測值之間相互獨立。
1.沒有考慮到用戶偏好重合的items的數量?
2,只有一個item是相交錯的話是不能得到correlation的,對于比較稀疏或者小的數據集這是個要注意的問題。不過一般來說兩個用戶之間只有一個item重疊從直覺上來說也不那么相似
Pearson?correlation一般出現在早期的推薦的論文和推薦的書里,不過并不總是好的。
在mahout中使用了一個增加的參數Weighting.WEIGHTED,適當使用可以改善推薦結果
?
EuclideanDistanceSimilarity
Return?1?/?(1?+?d)
CosineMeasureSimilarity
當two?series?of?input?values?each?have?a?mean?of?0(centered)時和PearsonCorrelation是有相同結果的
所以在mahout中我們只要簡單的使用PearsonCorrelationSimilarity就好
?
Spearman?correlation
這個方法用rank的方式,雖然失去了具體的打分信息,不過卻保留了item的order
Return的結果是-1和1兩個值,不過和pearson一樣,對于只有一個item重疊的也算不出。
而且這個算法比較慢,因為它要算和存儲rank的信息。所以paper多而實際用的少,對于小數據集才值得考慮
?
CachingUserSimilarity
UserSimilarity?similarity?=?new?CachingUserSimilarity(
new?SpearmanCorrelationSimilarity(model),?model);
?
Ignoring?preference?values?in?similarity?with?the?Tanimoto?coefficient
TanimotoCoefficientSimilarity
如果一開始就有preference?value,當數據中signal比noise多的時候可以用這個方法。
不過一般來說有preference信息的結果要好。
?
log-likelihood
Log-likelihood?try?to?access?how?unlikely?這些重疊的部分是巧合
結果的值可以解釋為他們的重合部分并不是巧合的概念
算法的結果可能比tanimoto要好,是一個更加聰明的metric
?
Inferring?preferences
對于數據量比較小的數據,pearson很難handle,比如一個user只express一個preference
于是要估計相似度么.........
AveragingPreferenceInferrer?
setPreferenceInferrer().
不過這種辦法在實際中并不是有用的,只是在很早的paper中mention到
通過現在的信息來估計并不能增加什么東西,并且很大的降低了計算速度
?
最終我們要通過實驗來比較上面的相似度,一般來說是用準確率,召回率,覆蓋率評測。
這里有一篇Building?Industrial-scale?Real-world?Recommender?Systems
http://vdisk.weibo.com/s/rMSj-
寫netflex的,非常好,我就不獻丑多說了,所以上面只是吐槽下常見的算法和相似度。
?
其實算法按流派分是分為下面這些類別的,大家有興趣也可以了解下,我這里就不多做介紹:
Similarity-based?methods
Dimensionality?Reduction?Techniques
Dimensionality-based?methods
Diffusion-based?methods
Social?fltering
Meta?approaches
我上面所說的相似度和推薦算法,只能算是Similarity-based?methods和Dimensionality?Reduction?Techniques里的非常小的一小部分,只當拋磚引玉了。
Ps:剛在豆瓣上問了下,他們說就用前兩種,事實上我也是覺得協同過濾+SVD?偶爾做做topic?model就夠了?如果沒事干再上點social?trusted的東西
?
增加規則:
記得hulu在做presentation的時候說過“不能做規則定制的推薦系統不是一個好的推薦系統”(好像是這樣吧......)事實上我們做出來的推薦的結果是需要做很多處理再展現給用戶的,這時候就是需要增加規則的時候了。
1.改善推薦效果:有些協同過濾的算法,做出來的結果不可避免的產生一些讓人啼笑皆非的結果,比如用戶什么都買,導致你有可能跟姑娘們推薦的時候在佛祖下面推薦泳裝什么的(真實的故事)。這時候就有兩種辦法,一種就是調整模型,一種就是增加規則做一定的限制。再舉個常見的例子就是有時候會在推薦冬裝的時候出現夏裝什么的,這時候一般我的處理方式是給這種季節性商品做一個隨時間的衰退。
2.增加廣告和導向:插入廣告,我們的最愛,這個就不多說了,靠規則。而所謂用戶喜歡的,其實不一定就是最好的,比如用戶一般來說就喜歡便宜的,還有什么韓流爆款之流,如果你推出來的東西都是這樣的,整個系統就變成洗剪吹大集合了,非常影響定位,這時候也要上規則。
3.做一些數據挖掘和fighting?spam的工作:這個在fighting?spam的地方細說
?
可視化參數調整:
做完上面的工作,一般來說推薦系統的基礎架構就差不多了,但是往往各個算法以及你自己上的規則都有多如牛毛的參數要調整,這時候一般要自己寫個測試腳本,將調整的結果可視化下一下,我個人推薦的是highchart,看參數以及比較各個指標非常清爽,?還可以自己做一些比如是取log之類的定制,很是方便。http://www.highcharts.com/
?
?
調整參數以及上線:
上線前有兩個事要做,一般來說就是離線測試和AB?test。
離線測試就是把數據抽樣一部分,分為train?data和test?data,然后評估一些準確率,召回率以及coverage之類的指標,用上面的可視化工具觀測比較下,感覺差不多了把pm叫過來讓她給小編們看看,看看審美和效果之類的。這是比較粗糙的,有的地方做的比較過細,還有用戶調研和請一些人來實際使用,這是后話。
AB?test也是大家最喜歡的地方了。因為說實在,評估推薦系統學術界是看準確率那一些東西,但是工業界還是看pv?uv轉化率這種實打實帶來效益的東西,而AB?test就是評估這些的。我個人是比較推薦這種方法,說不上好,只是拋磚引玉,就是按一般的做法先空跑一個星期,然后再把系統上線實際做算法pk,然后選取的實驗用戶一半的幾率進入原來的算法的推薦,一半的幾率進入你的算法的推薦,每天看看轉化率之間的比較,順便還可以調下參數做做實驗。如果算法穩定表現較好,就差不多了。
?
Fighting?spam:
俗話說,有人的地方就有江湖,有推薦的地方就有人刷。刷子一般分三種類型的:average?random和nuke。一般來說,average和random比較好對付,只要你的系統魯棒性好點,基本影響不大。但是nuke的就非常煩,一般來說有兩種思路解決,一種是提高系統魯棒性,另外就是上規則。我們從這張圖看看兩種思路分布對應的解決效果:
?
其實魯棒性的系統做的就是把efficient?attack的曲線降低,其實效果不算太好。
規則就是做到提前檢測,將危險扼殺在搖籃之中,就是做的藍色的那塊detectable的部分。
Fighting?spam是個博大精深的問題,俗話說,與人斗,其樂無窮,就是說的這個意思。
我們從規則說來,一般來說規則可以放到最前面的數據收集和過濾的階段,比如在收集數據的時候看看這個人是否是多個賬號但是是一個ip,或者有些人用戶名或者注冊郵箱有群體相似性質,或者有沒有出現pv等不正常的情況。有時候我們也可以從推薦的結果里上規則來查,比如有些人刷的過火了,導致推薦結果出現一些問題,我們就可以用迭代的方式按照先驗的刷子的比例來排出刷子排行榜之類的東西。這些都是經驗之談,上不了臺面,大家也可以自己摸索。
?
結束:
上面啰嗦了半天,大體上做一個完整的簡單推薦系統就是涉及到上面這些步驟。一些地方說的不夠詳細,有些是因為我懶,有些是不方便說。大家覺得我說的不對或者不妥的地方,可以直接在下面跟帖噴,或者有大大指導我也是很歡迎的,大家多交流經驗。我的郵箱是flclain@gmail.com?豆瓣是http://www.douban.com/people/45119625/?有什么問題也可以豆瓣或者郵件交流。
其實我是覺得,要是有個大大說“你個傻缺,寫的狗屁不通,讓我來教你我是怎么做推薦的”就更好了。
?
?
?
推薦系統小結
推薦系統(RecSys)作為電子商務中一個很火的應用,主要是為了幫助用戶發現可能感興趣的東西,這種就叫做個性化推薦系統;而廣告商還可以利用結果將內容投放給可能會對它們感興趣的用戶,這就成了個性化廣告。比較著名的推薦系統有亞馬遜,被RWW(讀寫網)稱為“推薦系統之王”,你從亞馬遜買了一本書以后,會發現它會經常向你的郵箱發一些相關的書籍,這個有時比較惱人,呵呵;此外還要電影和視頻網站,像YouTube和Hulu等會美國比較著名的視頻網站;個性化音樂網絡電臺,像國際的Pandora和Last.fm以及國內的豆瓣電臺;社交網絡,如Facebook等;個性化閱讀,如GoogleReader等;個性化郵件和個性化廣告等。
架構
主流的推薦系統的架構如下圖:
而動態推薦系統的架構如下:
關于推薦系統的架構,這幾篇文章寫得不錯,這里mark一下。
推薦系統的架構,
?
http://www.cnblogs.com/kobedeshow/p/3569525.html?utm_source=tuicool
?
淘寶推薦系統,
http://www.biaodianfu.com/taobao-recommendation-system.html?utm_source=tuicool
InfoQ上關于Hulu的視頻推薦系統架構經驗,
Hulu推薦系統構建經驗談,
http://www.infoq.com/cn/presentations/hulu-recommendation-system-construction-experiences/
?
算法
推薦系統的實現算法,按照使用的數據,主要分為以下三種算法:
?????? 協同過濾:用戶的行為數據,像點擊、評分、購買等;
?????? 內容過濾:用戶內容屬性和物品內容屬性;
?????? 社會化過濾:用戶之間的社交網絡關系,如朋友、關注關系等。
按照模型劃分,主要有以下三種:
?????? 最近鄰模型:基于用戶/物品的協同過濾算法;
?????? Latent Factor Model:基于矩陣分解的模型;
?????? 圖模型:二分圖模型,社會網絡圖模型等。
除了推薦系統自身的問題,像冷啟動、數據的稀疏性問題等,還有一個需要關注的問題,就是推薦系統的時間效應問題,比較常見的時間效應問題主要反映在用戶興趣的變化、物品流行度的變化以及商品的季節效應。即下面主要考慮三個問題,如何建立動態用戶興趣模型,如何建立用戶長期興趣和短期興趣的動態用戶興趣模型,還有網站時效性對用戶行為和推薦系統設計的影響。
考慮到推薦系統的時間效應問題,可以將協同過濾所使用的數據集歸結為一個四元組,即{用戶,物品,行為,時間},那么現在就面臨一個問題,如何通過研究用戶的歷史行為和興趣愛好,預測用戶將來的行為和喜好。需要解決以下三個問題:動態評分預測、動態Top-N推薦、時效性的影響。
對于第一個問題,動態評分預測問題。數據集可以選用比較直觀的顯性反饋數據集,即(用戶,物品,評分,時間),研究是這樣一個問題,給定用戶u,物品i,時間t,預測用戶u在時間t對物品i的評分r。對于該類問題,相關的算法已經有了很多的研究,與時間無關的評分預測問題算法主要有以下幾種:
?????? 基于用戶/物品的協同過濾算法;
?????? 基于矩陣分解的模型LatentFactor Model;
?????? 受限波爾茲曼機RBM。
與時間相關的評分預測問題算法主要是基于下面兩種想法:
?????? 用戶會喜歡和他們最近喜歡的物品相似的物品;
?????? 用戶會喜歡和他們興趣相似的用戶最近喜歡的物品。
當然上面的這些算法是提出來了,但是有些地方有待優化。
上述算法需要考慮的時間效應問題主要有以下幾個方面:
用戶興趣的變化,比如說:年齡增長,從青年長成中年壯年;生活狀態的變化,由以前的學生到踏上工作崗位;社會熱點問題的影響,奧運會等。此外還有季節效應問題,一些在夏季很流行的,在秋冬季節未必就很流行。如何解決上述問題,提出優化還有待進一步思考。
對于動態Top-N推薦問題,數據集選用的是不太直觀的隱性反饋數據集,{(用戶,物品,時間)},研究的是這樣的一個問題,給定用戶u,時間t,預測用戶u在時間t可能會喜歡的物品列表R(u)。在這方面的相關研究也很成熟,有基于鄰域的協同過濾算法,主要分為兩種,一種是ItemCF,推薦給用戶那些跟他們之前喜歡的物品類似的物品;還有一種是UserCF,推薦給用戶那些跟他們興趣相似的用戶喜歡的物品。還有基于評分數據的Top-N推薦算法,該想法的思路是推薦給用戶那些他們可能評分最高的物品。該想法都是圍繞用戶的興趣展開的,需要考慮到,用戶興趣分為短期興趣和長期興趣,短期興趣的特點是臨時、易變;長期興趣的特點是長久、穩定;用戶的短期興趣可能會轉化為長期興趣,所以需要在推薦時綜合考慮長期興趣和短期興趣。該問題的解決有待進一步思考。
對于時效性的影響,每個在線系統都是一個動態系統,但它們有不同的演化速率。比如說,新聞,博客演化的很快,但音樂,電影的系統演化的卻比較慢。這就帶來這樣一個問題,不同演化速率的系統需要不同類型的推薦算法,如何解決該問題,也是應該進一步深入思考的。
?
?
?
?
最近一直學習Mahout和推薦引擎相關的知識,一直想搞清楚,什么樣的推薦系統的架構才是合理,既能對海量數據進行復雜運算,又能及時響應做出推薦。在網上發現一篇對推薦系統結構講解的很好的文章數:據驅動銷售——個性化推薦引擎,里面提到這樣的思想“?數據的特性對我們的架構設計起到了一個非常關鍵的作用,因為我們可以使用完全不同的方式來將靜態數據和動態數據分開處理,再合并分析?”,對于一個數據挖掘初學者的我,很受啟發。
? ? ?同時,自己也在思考,若結合實際的推薦系統中,針對不同的協同過濾算法,如何來劃分動態、靜態數據,它們是怎樣的結構,怎么存儲的,又是怎么合并分析的。根據文章作者對推薦系統的設計思路,結合Mahout的源碼實現,我似乎找到了一些相似之處,來解釋上面的問題。
? ? ?首先,仔細縷一遍Mahout產生推薦的算法流程:
? ? ?1. 原始數據,Mahout中所有協同過濾算的的輸入數據,都要求這樣的結構(UserID、ItemID、Preference)為一條記錄,表示一個用戶對某一個商品的喜愛程度;怎么得出這樣的結果,Mahout并沒實現,值需要你輸入;一般來講是通過分析用戶各類行為日志記錄,結合一些特征屬性,計算出來。
? ? ?2. 根據不同的協同過濾算法,得到用戶與用戶的關系(基于用戶的) 或 商品與商品的關系(基于商品的);這時的數據結構,更像是矩陣:UserAID(ItemAID)、UserBID(ItemBID)、Value(相似度)。
? ? ?3. 計算推薦列表,這一步比較細碎,根據不同的推薦算法,會有些許不同,但大體流程是不變;首先會計算出可能被推薦的書籍(基于用戶的協同過濾算法,會先找出此用戶的鄰居,依次找出這些鄰居喜歡的商品且此用戶未瀏覽的商品;而基于商品的協同過濾算法,則直接找出所有此用戶未瀏覽的商品);其次逐個計算這些可能被推薦的商品的得分,并以此得分由高到底的排序;最后返回前面N個(N可有客戶端作為請求參數而指定)。
? ? ?都知道,Mahout框架式基于Hadoop的,這樣分布式的運算以便海量數據的處理;然而Mahout的實現卻又很多種(哪怕是同一個算法),也許Mahout是為了給開發者提供多種實現的選擇;我自己總結了一下,它的實現模式根據Hadoop框架的使用情況大概可分為三種:
?????第一種:完全不使用Hadoop,上述的邏輯均在單機里完成,為了達到效率,在第二步時,Mahout提供一個參數maxEntries來控制總數據量。
? ? ?第二種:部分使用Hadoop,即在上述邏輯中第二步運算用戶與用戶關系或商品與商品關系時使用Hadoop,將運算結果持久化;后續的計算由單機完成后并展示。
? ? ?第三種;完全是Hadoop運算,運算完以后的結果為:每個用戶有一個推薦列表;展示的話直接查庫就OK
? ? ?根據那片文章中作者描述的推薦系統結構,采用第二種實現是相對合理的,因為關系數據相對靜態,并且此部分的數據量是十分龐大,它類似矩陣,若你用戶數量或商品數量而M,那它的數據量為M*(M-1)/2,若全部放在內存中,會占用大量的資源,對靜態數據來講完全沒有必要。
? ? ?而在第三步為用戶計算推薦列表時,又可以結合用戶的一些在線屬性或瀏覽情況得到一些實時變化的推薦產生更好的用戶體驗。
?
?
推薦系統:總體介紹、推薦算法、性能比較
探索推薦引擎內部的秘密,第 1 部分: 推薦引擎初探
個性化推薦技術漫談
?
一些推薦算法:
SVD:?SVD在推薦系統中的應用
slope one:推薦系統:Slope One 算法
apriori:先驗算法
???????????? ???推薦系統:關聯規則(2)
FP-Growth:推薦系統:關聯規則(3) —— FP-Growth 算法
Item CF :推薦系統:協同過濾 之 Item-based Collaborative Filtering
User CF:推薦系統:協同過濾 之 User-based Collaborative Filtering
?
算法間比較:
推薦系統的常見推薦算法的性能比較
?
相似性計算:
探索推薦引擎內部的秘密,第 2 部分: 深入推薦引擎相關算法 - 協同過濾
?
?
?
?
?
?
?
漫談“推薦系統”由于需要準備一月底與三月中兩個關于“推薦系統”的短期課程(前者在阿卜杜拉國王科技大學,沒錯就是那個傳說中沙特的土豪大學!后者在悉尼科技大學),期間二月份還夾帶了一個推薦系統相關的討論班,所以從去年十二月開始我幾乎每個周末至少得抽出一天的時間來做幻燈片。推薦技術是我個人研究興趣并不是我日常工作內容,無法利用上班時間準備,再加上我有強迫癥(必須要讓累加起來多達二百多頁的幻燈片風格色調字體公式圖例都保持視覺上的審美愉悅與邏輯上的高度統一),所以在畫圖敲公式上花了很長時間。幻燈片做煩了,突然很想寫點東西聊聊我對推薦系統的見解。此文不會出現公式,盡量用白話說清楚目前主流推薦技術的直觀原理。
?
先談談問題背景,故事是這樣的:互聯網出現后,隨著網上內容的增加,好學的小伙伴們發現很多他們不懂的姿勢網上都有,可互聯網不像圖書館搞個書目索引就行,于是出現了搜索引擎幫助小伙伴們在茫茫互聯網上找到他們感興趣的東西,但條件是你必須知道你想要什么,然后提取成關鍵字去搜,所謂信息檢索(Information Retrieval)。十年過去了,信息爆炸了,問題出現了,搜索引擎動輒返回幾十萬個結果,或者有些想要的信息卻根本不知道它的存在,甚至根本不知道如何用關鍵詞描述你想要的東西,這時推薦系統應運而生——小伙伴們不用自己去找,推薦系統就會根據小伙伴們的個人資料歷史紀錄從海量信息中自動篩選符合小伙伴們口味的內容進行推薦,所謂推薦系統(Recommender Systems)。如今,推薦系統已經無處不在,幾乎所有的網絡服務都集成了推薦系統。在此我就不提那些學術圈老掉牙的例子什么Netflix電影推薦啊Google新聞推薦啊Yahoo!廣告推薦啊什么的了;我瞄了下自己的手機舉幾個例子吧:微博朋友推薦、蝦米音樂推薦、LinkedIn工作推薦、YouTube視頻推薦、大眾點評餐館推薦、等等。?
?
既然要談的是推薦“技術”,那么我得先把推薦問題用數學語言形式化了。淡定淡定,推薦問題形式化后非常簡單干凈——就三個矩陣(從這里往下得有一丟丟想像力,能在腦海里想象簡單的矩陣操作)。最重要的一個矩陣是評分或偏好矩陣(Rating/Preference Matrix),其每一行對應一個用戶,每一列對應一件物品,矩陣中的任一元素就是某用戶對某物品的感興趣程度(評分可以用正整數表示,點贊神馬的可以用0/1表示),不失一般性,下面我們僅基于評分矩陣討論。這個評分矩陣是極其稀疏的,因為每個用戶只可能對很少一部分物品打分。第二個矩陣是用戶信息矩陣,每一行對應一個用戶,每一列對應一個用戶屬性(如年齡、職業、地區、標簽等)。第三個矩陣是物品信息矩陣,每一行對應一件物品,每一列對應一個物品屬性(如電影的流派、導演、演員等)。推薦問題的目標就是:基于給定的三個矩陣,把評分矩陣中缺失元素的評分預測出來,并基于預測出來的評分把得分高的物品推薦給相應用戶。這里值得注意的是,只有評分矩陣是所有推薦技術所必需的,用戶信息矩陣與物品信息矩陣這兩者是可選的。真實推薦系統面臨最大的挑戰是評分矩陣的大規模與稀疏性。
?
接下來我把一些當前常用的推薦技術分門別類。推薦技術可先分為三大類:基于人口統計的推薦技術(Demography-based)、基于物品內容的推薦技術(Content-based)、以及基于協同過濾的推薦技術(Collaborative Filtering,簡稱CF)。基于人口的又包括基于用戶資料的(User Profile)和基于信任關系的(社交網絡上的好友關系)等。基于物品內容的又可細分為基于元數據的(即Metadata,比如電影的流派、導演、演員等)和基于內容數據的(比如視頻數據、音頻數據)等——真實應用大多是基于元數據的,基于內容數據的推薦系統由于語義鴻溝(Semantic Gap)和效率問題,做了幾十年,一直未突破(深度學習能突破么,拭目以待呵呵)。雖然基于人口和基于內容的兩大類推薦技術在實際中的應用極廣而且效果在某些應用場景下不比第三類技術協同過濾差,那為什么協同過濾技術一躍成為當今主流的推薦技術了呢?有以下幾方面原因:1)協同過濾問題相當干凈,只需要一個評分矩陣,不需要用戶信息與物品信息,這解決了用戶物品信息缺失場景下的推薦問題。2)協同過濾問題的本質是矩陣補全問題(Matrix Completion),也就是把一個稀疏矩陣的缺失元素給估計出來,這是機器學習中一個經典問題,除了推薦之外還有無數的應用都可歸結為矩陣補全問題,所以機器學習的高速發展也促進了協同過濾技術。3)2006年Netflix發起的那個百萬美元大獎功不可沒,直接上演了持續多年相關研究領域全民做推薦的激情歲月,雖然吧這個競賽使用了一個完全誤導的評價指標來判斷推薦算法的優劣(使用的是RMSE指標,這是一個評價回歸的指標,而推薦問題事實上是一個排序問題)。跑題了,接著分類。協同過濾技術可以繼續分為基于記憶的(Memory-based)和基于模型的(Model-based)。基于記憶的繼續可分為基于用戶的(User-based)和基于物品的(Item-based);而基于模型的可以繼續分為基于矩陣分解的(Matrix Factorization)和基于聯合聚類的(Co-clustering)。基于記憶的協同過濾技術使用的是K-近鄰(K-Nearest Neighbors)的思想,而基于模型的協同過濾技術使用的是機器學習方法。分類結束。
?
真實系統都是使用的混合策略(Hybrid Strategy),多為基于人口、基于元數據、以及基于用戶或物品的協同過濾推薦技術的各種組合。基于模型的協同過濾雖然使用了高端大氣上檔次的機器學習方法,但做過真實應用的同學都懂的,簡單粗暴才是王道,提出并改進一個模型連發三篇頂級機器學習會議論文提高了一個百分點,往往不如真實系統中屌絲程序員在哪疙瘩加個莫名的閾值來得有效。那為什么頂尖互聯網企業都在搞機器學習呢?這么說吧,五百的衣服和五萬的衣服功能都是一樣的,但是地位高到一定程度,除了衣服的基本功能外我們還會追求一些其它的東西。但是如果只是想基于推薦技術做一個網絡服務神馬的,就沒必要搞那么玄的機器學習花樣了,反而大規模計算的效率問題和推薦應用本身是否有市場前景是更應該考慮的,有了這些,最基本的基于人口統計與基于記憶的推薦技術就能搞定大多數應用。貌似跑題了,接著說混合策略。有些混合策略是對不同推薦技術的結果加權相加(Weighting);有些是根據場景不同在不同技術間跳轉(Switching),比如新用戶基于人口統計老用戶基于協同過濾;有些是一個網頁上不同區域同時顯示不同推薦技術的結果(Mixing);有些是用一個推薦技術對另一個推薦技術輸出的結果進行提升(Cascading)。
?
除了基于模型的協同過濾技術外,其它的推薦技術在原理上都相對簡單,使用一些相關查詢和啟發式算法就能解決。這段就把除基于模型的協同過濾以外的推薦技術都簡單介紹下。首先是基于人口統計學的,該類推薦技術需要基于用戶信息矩陣和評分矩陣。原理很簡單,就是查找用戶信息矩陣中背景類似的用戶,然后把對應評分矩陣中打高分的物品推薦給背景類似的用戶。舉個例子,用戶信息上顯示兩個人年齡相仿居于灣區互聯網從業者,于是系統就會認為這兩人相關性強會有共同愛好,把其中一人打高分的電影推薦給另一個。這種推薦技術的優點是簡單,一些相關性查詢操作就能搞定,而且沒有“冷啟動(Cold-start)”問題(即用戶缺失歷史評分紀錄);缺點是無法個性化推薦,基于人口統計相似度的假設太強,比如同為IT男,一個技術宅,一個偽文青,你把技術宅喜歡的東西推薦給偽文青肯定是不靠譜的,比如我排斥一切XX俠的電影。接下來是基于物品內容的推薦技術,該類推薦技術需要基于物品信息矩陣和評分矩陣(這里只討論基于元數據的,基于真實內容的開門課都講不完)。該類推薦技術的原理也很簡單,基于元數據計算物品之間的相關性,然后把與該用戶以前打高分的物品最相關的物品推薦給他。這類推薦技術比前一種靠譜,因為用戶在同類物品上一般會表現出相同的興趣程度。舉個例子,我如果對《巴黎我愛你》打了個高分,那么推薦系統就會向我推薦強關聯的《紐約我愛你》,而我也會對同一血統的電影很感興趣。因此,該類技術的優點就是對偏好的建模較為精細與準確;缺點是依賴于物品元數據包含的信息量,以及存在冷啟動問題(需要用戶的歷史評分)。接下來介紹基于記憶的協同過濾技術,該類推薦技術的標準問題設置僅需要評分矩陣,當然近年來學術界有些關于遷移學習(Transfer Learning)在推薦系統中的研究會使用到用戶與物品的信息矩陣、甚至使用另一個域的評分矩陣(我以前在推薦系統中的工作主要在這塊,感興趣的同學可以用谷歌百度下一個二頁紙的小文“Cross-Domain Collaborative Filtering: A Brief Survey”),但這里我們只討論標準的協同過濾問題設置。基于用戶的協同過濾分為兩步:第一步是計算用戶之間的相關度,這里的相關度是評分矩陣行向量間的相關度,其直觀意義就是如果兩個用戶在相同物品上打的分越接近,那么這兩個用戶的偏好也越接近。如果評分矩陣是一個沒有缺失項的滿矩陣,那么行向量之間的相似度直接可以用歐式距離或者夾角余弦計算;由于評分矩陣是稀疏矩陣,因此計算相關性首先要把兩個行向量之間的交集(打過分的物品)找出來,并只在該交集上計算一個類似夾角余弦的值,叫作皮爾森相關系數(Pearson Correlation Coefficients)。在取得了與所有用戶兩兩之間的相關性后,第二步就是預測該用戶的缺失評分。給定一個待預測用戶,找到他的K-近鄰用戶集合,他的缺失評分就是用其K-近鄰用戶對應物品上的歷史評分用相關性加權平均得到。基于物品的協同過濾和基于用戶的是對稱的,一個是對行操作,一個是對列操作,方法和原理都是一樣的。
?
從這里往后的內容主要將介紹基于模型的協同過濾技術。在大多數推薦系統的介紹中一般直接就把基于模型與矩陣分解等同起來了,因為應用到實際推薦系統中的基于模型的推薦技術一般都是基于矩陣分解的,比如Netflix百萬大獎得主提出的(Time)SVD++方法(但事實上前幾名所用的方法都是很多種算法集成的結果,所以說研究歸研究,在實際應用中干凈優美的模型很難超越東拼西湊再加點人腦規則的四不像,這個道理我早在八年前做TRECvid的時候就總結出來了,當時直接導致我放棄多媒體研究直到現在一直對計算機視覺抱有悲觀態度)。又跑題了,繼續說基于模型的推薦技術。除了矩陣分解,這里我還要額外介紹一種基于聯合聚類的技術,所謂聯合聚類,就是對用戶與物品(即評分矩陣的行與列)同時聚類,聚類的方法可以是簡單的K-Means,但更優美的建模方法是雙向混合模型——我個人非常喜歡這種建模方式,雖然對于評分預測的性能沒有基于矩陣分解的好(因為矩陣分解的目標就是擬合評分而混合模型的目標是估計用戶與物品在潛在類型上的分布)。
?
先說基于矩陣分解的方法吧。給定一個評分矩陣(大小為N*M),把該矩陣分解為兩個矩陣的乘積,一個是用戶特征矩陣(大小為N*K),一個是物品特征矩陣(大小為M*K),其中潛在特征(latent features)的維度遠小于用戶數與物品數;目標函數就是兩個特征矩陣的重構與給定評分矩陣在那些可見評分上的值盡可能接近,一般使用矩陣范數(Frobenius norm),即兩個矩陣相減所有元素上殘差平方和;再加上對兩個特征矩陣的矩陣范數作為正則化項。改優化問題常用兩種方法解決:一種是交替最小二乘(Alternative Least Squares),交替優化用戶特征矩陣與物品特征矩陣,在優化其一的時候固定另一個的值視其為已知,這樣就相當于每輪解決一個標準的最小二乘問題,最后收斂到局部最優解。該方法的優點是收斂速度快,缺點是需要對用戶數與物品數大小的方正求逆,難以規模化。另一種是隨機梯度下降(Stochastic Gradient Descent),對每個用戶與每個物品(評分矩陣的行與列)分別求偏導建立牛頓迭代公式,然后用可見評分順序對這些迭代公式進行更新。該方法的優點是可以并行化、效率高,目前大規模矩陣分解都是用的這種優化算法;缺點可能是收斂速度沒有第一種快(這點我不是很確定)。最后說說這種形式矩陣分解的物理含義。這樣分解成兩部分后,就相當于用戶和物品都被放置到一個潛在的K維特征空間,只要擁有相似潛在特征的用戶與物品,他們的夾角就小乘積就大得到的預測評分也就相應更高。那么憑什么我們能指定一個“潛在的K維特征空間”呢?拿Pandora的音樂推薦舉例子,每個音樂有幾百條“音樂基因”就是音樂的顯式特征(不知道音樂基因的可以去古歌百度一下Music Gene Project)。如果不降維的話,那么音樂特征矩陣和用戶特征矩陣的緯度就是其真實的特征緯度。假設我們基于主成分分析(PCA)用相同的一套基分別對這兩個矩陣進行線性變換,那么得到的兩個矩陣就可以認為是投影到潛在特征空間的兩個矩陣,而這兩個矩陣的乘積和原來的兩個矩陣是一樣的(因為當中兩個投影矩陣的乘積是單位矩陣)。那么假如我們只用前K個基投影呢?那我們就得到了只有K維潛在特征空間的低秩矩陣。所以在實際問題中,我們都不需要知道真實的特征空間,只需要人為指定一個K維潛在特征空間就可以了,得出的結果可以認為是真實特征經過某個線性變化后投影到一個低維潛在特征空間。
?
最后介紹基于聯合聚類的方法。這類方法的物理意義更直觀,其實也能表示成為矩陣分解的形式,但不同的是聯合聚類把評分矩陣(大小為N*M)分解為三部分,一個是用戶隸屬度矩陣(N*K),表示每個用戶在K個潛在用戶組上的分布情況,所有元素為正每行加起來為1;一個是物品隸屬度矩陣(M*L),表示每個物品在L個潛在物品組上的分布情況,所有元素為正每行加起來為1;還有一個是壓縮評分矩陣(K*L),表示某個用戶組對某個物品組給的評分。使用這三個矩陣的乘積重構評分矩陣可以對缺失評分進行預測。解決該問題最簡單的方法是分別對行與列進行K-Means聚類,然后用戶與物品隸屬度矩陣就根據聚類結果把對應的組設為1其它為0(硬聚類),而壓縮評分矩陣是每個聯合聚類中評分的平均值。更一般性的建模方法是令兩個隸屬度矩陣為在潛在組別上的分布(軟聚類),這需要使用期望最大(Expectation-Maximization)算法解決;進一步地考慮貝葉斯,由于隸屬度就是Dirichlet分布,那么其實該聯合聚類問題可以使用Latent Dirichlet Allocation的變種建模,叫作Bi-LDA,使用吉布斯采樣解決。這類方法的具體細節就不介紹了。
至此為止,基本的推薦技術大體都過了一遍了。剩下的就是解決協同過濾技術中的各種挑戰,比如興趣隨時間與環境變化問題、矩陣稀疏問題、冷啟動問題、噪聲問題、大規模矩陣分解問題等等,這些“挑戰”也是近年來學術界寫論文的切入點。但其實在工業界,這些所謂的挑戰大多都不是問題,或是可以用替代方案解決、或是對結果真正的影響不大。我個人覺得無論是學術界還是工業界,當前最重要的問題還是大規模矩陣分解問題(我也無法免俗大數據啊),各路神仙也從不同的突破點去解決這個問題,有使用分布式計算的、有提出加速優化算法的、有使用近似哈希算法的等等。在我的短期課程中,針對這些挑戰的一些解決方案也占了很大的比重,但是這里就不一一累述了,用純文字描述個問題都得花半頁紙。其實我本來還想談一下在線推薦系統,也是如今精準廣告投放背后的核心技術,但是也因為問題的設置和協同過濾有很大的不同,技術上也幾乎沒有什么交集,就不展開了。在線推薦系統的主要技術是一大類被稱為Multi-Armed Bandits(MAB)的方法——沒錯就是LH機!廣告投放就像賭博,你選哪個廣告投放出去都會有不同的回報,隨著一次又一次的嘗試,從失敗中吸取教訓,慢慢學習到背后隱含的規律,之后就可以保持大概率的贏面。MAB的在線學習策略遵循的是“開采(Exploitation)”與“探索(Exploration)”,一邊盡量投注之前贏面較大的廣告,一邊又不停嘗試其它未知底細的廣告以發現更高的贏面——這不就像是人生么?有些人覺得現狀不錯就一直保持著開采狀態,而有些人則時不時探索一下,也許會走一些彎路,可或許在一段彎路過后會發現比以前更好的一條路;更何況,人生并不只是用最后累積到的財富來論成敗,沿途的風景,妙不可言的或是痛徹心扉的,都是人生獨一無二的財富。?
淺談矩陣分解在推薦系統中的應用為了方便介紹,假設推薦系統中有用戶集合有6個用戶,即U={u1,u2,u3,u4,u5,u6},項目(物品)集合有7個項目,即V={v1,v2,v3,v4,v5,v6,v7},用戶對項目的評分結合為R,用戶對項目的評分范圍是[0, 5]。R具體表示如下:
?
? ? ? ?推薦系統的目標就是預測出符號“?”對應位置的分值。推薦系統基于這樣一個假設:用戶對項目的打分越高,表明用戶越喜歡。因此,預測出用戶對未評分項目的評分后,根據分值大小排序,把分值高的項目推薦給用戶。怎么預測這些評分呢,方法大體上可以分為基于內容的推薦、協同過濾推薦和混合推薦三類,協同過濾算法進一步劃分又可分為基于基于內存的推薦(memory-based)和基于模型的推薦(model-based),本文介紹的矩陣分解算法屬于基于模型的推薦。
? ? ? ? 矩陣分解算法的數學理論基礎是矩陣的行列變換。在《線性代數》中,我們知道矩陣A進行行變換相當于A左乘一個矩陣,矩陣A進行列變換等價于矩陣A右乘一個矩陣,因此矩陣A可以表示為A=PEQ=PQ(E是標準陣)。
? ? ? ?矩陣分解目標就是把用戶-項目評分矩陣R分解成用戶因子矩陣和項目因子矩陣乘的形式,即R=UV,這里R是n×m, n =6, m =7,U是n×k,V是k×m。直觀地表示如下:
?
? ? ? ?高維的用戶-項目評分矩陣分解成為兩個低維的用戶因子矩陣和項目因子矩陣,因此矩陣分解和PCA不同,不是為了降維。用戶i對項目j的評分r_ij =innerproduct(u_i, v_j),更一般的情況是r_ij =f(U_i, V_j),這里為了介紹方便就是用u_i和v_j內積的形式。下面介紹評估低維矩陣乘積擬合評分矩陣的方法。
? ? ? 首先假設,用戶對項目的真實評分和預測評分之間的差服從高斯分布,基于這一假設,可推導出目標函數如下:
?
?
最后得到矩陣分解的目標函數如下:
?
? ? ? ?從最終得到得目標函數可以直觀地理解,預測的分值就是盡量逼近真實的已知評分值。有了目標函數之后,下面就開始談優化方法了,通常的優化方法分為兩種:交叉最小二乘法(alternative least squares)和隨機梯度下降法(stochastic gradient descent)。
? ? ? 首先介紹交叉最小二乘法,之所以交叉最小二乘法能夠應用到這個目標函數主要是因為L對U和V都是凸函數。首先分別對用戶因子向量和項目因子向量求偏導,令偏導等于0求駐點,具體解法如下:
?
? ? ? ?上面就是用戶因子向量和項目因子向量的更新公式,迭代更新公式即可找到可接受的局部最優解。迭代終止的條件下面會講到。
? ? ? ?接下來講解隨機梯度下降法,這個方法應用的最多。大致思想是讓變量沿著目標函數負梯度的方向移動,直到移動到極小值點。直觀的表示如下:
?
? ? ?其實負梯度的負方向,當函數是凸函數時是函數值減小的方向走;當函數是凹函數時是往函數值增大的方向移動。而矩陣分解的目標函數L是凸函數,因此,通過梯度下降法我們能夠得到目標函數L的極小值(理想情況是最小值)。
? ? ?言歸正傳,通過上面的講解,我們可以獲取梯度下降算法的因子矩陣更新公式,具體如下:
? ? ??
(3)和(4)中的γ指的是步長,也即是學習速率,它是一個超參數,需要調參確定。對于梯度見(1)和(2)。
下面說下迭代終止的條件。迭代終止的條件有很多種,就目前我了解的主要有
1)??? 設置一個閾值,當L函數值小于閾值時就停止迭代,不常用
2)??? 設置一個閾值,當前后兩次函數值變化絕對值小于閾值時,停止迭代
3)??? 設置固定迭代次數
? ? ? ?另外還有一個問題,當用戶-項目評分矩陣R非常稀疏時,就會出現過擬合(overfitting)的問題,過擬合問題的解決方法就是正則化(regularization)。正則化其實就是在目標函數中加上用戶因子向量和項目因子向量的二范數,當然也可以加上一范數。至于加上一范數還是二范數要看具體情況,一范數會使很多因子為0,從而減小模型大小,而二范數則不會它只能使因子接近于0,而不能使其為0,關于這個的介紹可參考論文Regression Shrinkage and Selection via the Lasso。引入正則化項后目標函數變為:
(5)中λ_1和λ_2是指正則項的權重,這兩個值可以取一樣,具體取值也需要根據數據集調參得到。優化方法和前面一樣,只是梯度公式需要更新一下。
矩陣分解算法目前在推薦系統中應用非常廣泛,對于使用RMSE作為評價指標的系統尤為明顯,因為矩陣分解的目標就是使RMSE取值最小。但矩陣分解有其弱點,就是解釋性差,不能很好為推薦結果做出解釋。
總結
以上是生活随笔為你收集整理的自己动手写一个推荐系统,推荐系统小结,推荐系统:总体介绍、推荐算法、性能比较, 漫谈“推荐系统”, 浅谈矩阵分解在推荐系统中的应用...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Barra模型初探,A股市场风格解析
- 下一篇: adb 强制删除系统应用