1. 程式人生 > >機器學習(37)之矩陣分解在協同過濾推薦中的應用

機器學習(37)之矩陣分解在協同過濾推薦中的應用

微信公眾號

關鍵字全網搜尋最新排名

【機器學習演算法】排名第一

【機器學習】排名第一

【Python】排名第三

【演算法】排名第四

前言

在協同過濾推薦演算法總結(機器學習(36)之協同過濾典型演算法概述【精華】)中,講到了用矩陣分解做協同過濾是廣泛使用的方法,這裡就對矩陣分解在協同過濾推薦演算法中的應用做一個總結。

解決什麼問題

在推薦系統中,常常遇到的問題是這樣的,我們有很多使用者和物品,也有少部分使用者對少部分物品的評分,希望預測目標使用者對其他未評分物品的評分,進而將評分高的物品推薦給目標使用者。比如下面的使用者物品評分表:

640?wx_fmt=png&wxfrom=5&wx_lazy=1

對於每個使用者,希望較準確的預測出使用者對未評分物品的評分。對於這個問題有很多解決方法,本文關注於用矩陣分解的方法來做。如果將m個使用者和n個物品對應的評分看做一個矩陣M,我們希望通過矩陣分解來解決這個問題。

使用SVD解決

說道矩陣分解,首先想到的就是奇異值分解SVD。在奇異值分解(SVD)原理(機器學習(29)之奇異值分解SVD原理與應用詳解)和在降維中的應用中,對SVD原理做了總結。

此時可以將這個使用者物品對應的m×n矩陣M進行SVD分解,並通過選擇部分較大的一些奇異值來同時進行降維,也就是說矩陣M此時分解為:

640?wx_fmt=png

其中k是矩陣M中較大的部分奇異值的個數,一般會遠遠的小於使用者數和物品數。如果要預測第i個使用者對第j個物品的評分mij,則只需要計算uTiΣvj即可。通過這種方法,可以將評分表裡面所有沒有評分的位置得到一個預測評分。通過找到最高的若干個評分對應的物品推薦給使用者。

可以看出這種方法簡單直接,似乎很有吸引力。但是有一個很大的問題我們忽略了,就是SVD分解要求矩陣是稠密的,也就是說矩陣的所有位置不能有空白。有空白時M是沒法直接去SVD分解的。如果這個矩陣是稠密的,那不就是說我們都已經找到所有使用者物品的評分了嘛,那還要SVD幹嘛! 的確,這是一個問題,傳統SVD採用的方法是對評分矩陣中的缺失值進行簡單的補全,比如用全域性平均值或者用使用者物品平均值補全,得到補全後的矩陣。接著可以用SVD分解並降維。

雖然有了上面的補全策略,傳統SVD在推薦演算法上還是較難使用。因為使用者數和物品一般都是超級大,隨便就成千上萬了。這麼大一個矩陣做SVD分解是非常耗時的。那麼有沒有簡化版的矩陣分解可以用呢?我們下面來看看實際可以用於推薦系統的矩陣分解。

FunkSVD橫空出世

FunkSVD是在傳統SVD面臨計算效率問題時提出來的,既然將一個矩陣做SVD分解成3個矩陣很耗時,同時還面臨稀疏的問題,那麼能不能避開稀疏問題,同時只分解成兩個矩陣呢?也就是說,現在期望矩陣M這樣進行分解:

640?wx_fmt=png

SVD分解已經很成熟了,但是FunkSVD如何將矩陣M分解為P和Q呢?這裡採用了線性迴歸的思想。目標是讓使用者的評分和用矩陣乘積得到的評分殘差儘可能的小,也就是說,可以用均方差作為損失函式,來尋找最終的P和Q。

對於某一個使用者評分mij,如果用FunkSVD進行矩陣分解,則對應的表示為qTjpi,採用均方差做為損失函式,則我們期望

640?wx_fmt=png

儘可能的小,如果考慮所有的物品和樣本的組合,則我們期望最小化下式:

640?wx_fmt=png

只要能夠最小化上面的式子,並求出極值所對應的pi,qj,則最終可以得到矩陣P和Q,那麼對於任意矩陣M任意一個空白評分的位置,可以通過qTjpi計算預測評分。

當然,在實際應用中,為了防止過擬合,會加入一個L2的正則化項,因此正式的FunkSVD的優化目標函式J(p,q)是這樣的:

640?wx_fmt=png

其中λ為正則化係數,需要調參。對於這個優化問題,一般通過梯度下降法來進行優化得到結果。將上式分別對pi,qj求導我們得到:

640?wx_fmt=png

則在梯度下降法迭代時,pi,qj的迭代公式為:

640?wx_fmt=png

通過迭代最終可以得到P和Q,進而用於推薦。FunkSVD演算法雖然思想很簡單,但是在實際應用中效果非常好,這真是驗證了大道至簡。

BiasSVD再升級

在FunkSVD演算法火爆之後,出現了很多的改進版演算法。其中BiasSVD算是改進的比較成功的一種演算法。BiasSVD假設評分系統包括三部分的偏置因素:一些和使用者物品無關的評分因素,使用者有一些和物品無關的評分因素,稱為使用者偏置項。而物品也有一些和使用者無關的評分因素,稱為物品偏置項。這其實很好理解。比如一個垃圾山寨貨評分不可能高,自帶這種爛屬性的物品由於這個因素會直接導致使用者評分低,與使用者無關。

假設評分系統平均分為μ,第i個使用者的使用者偏置項為bi,而第j個物品的物品偏置項為bj,則加入了偏置項以後的優化目標函式J(p,q)是這樣的:

640?wx_fmt=png

這個優化目標也可以採用梯度下降法求解。和FunkSVD不同的是,此時我們多了兩個偏執項bi,bj,pi,qj的迭代公式和FunkSVD類似,這裡就不給出了。而bi,bj一般可以初始設定為0,然後參與迭代。這裡給出bi,bj的迭代方法

640?wx_fmt=png

通過迭代我們最終可以得到P和Q,進而用於推薦。BiasSVD增加了一些額外因素的考慮,因此在某些場景會比FunkSVD表現好。

SVD++更強悍

SVD++演算法在BiasSVD演算法上進一步做了增強,這裡它增加考慮使用者的隱式反饋。好吧,一個簡單漂亮的FunkSVD硬是被越改越複雜。

對於某一個使用者i,它提供了隱式反饋的物品集合定義為N(i), 這個使用者對某個物品j對應的隱式反饋修正的評分值為cij, 那麼該使用者所有的評分修正值為∑csj。一般將它表示為用qTjys形式,則加入了隱式反饋項以後的優化目標函式J(p,q)是這樣的:

640?wx_fmt=png

其中,引入|N(i)|−1/2是為了消除不同|N(i)|個數引起的差異。式子夠長的,不過需要考慮使用者的隱式反饋時,使用SVD++還是不錯的選擇。

小結

FunkSVD將矩陣分解用於推薦方法推到了新的高度,在實際應用中使用也是非常廣泛。當然矩陣分解方法也在不停的進步,目前張量分解和分解機方法是矩陣分解推薦方法今後的一個趨勢。

對於矩陣分解用於推薦方法本身來說,它容易程式設計實現,實現複雜度低,預測效果也好,同時還能保持擴充套件性。這些都是它寶貴的優點。當然,矩陣分解方法有時候解釋性還是沒有基於概率的邏輯迴歸之類的推薦演算法好,不過這也不影響它的流形程度。小的推薦系統用矩陣分解應該是一個不錯的選擇。大型的話,則矩陣分解比起現在的深度學習的一些方法不佔優勢。

歡迎分享給他人讓更多的人受益

640?wx_fmt=png

參考:

  1. 宗成慶《統計自然語言處理》 第2版

  2. 部落格園

    http://www.cnblogs.com/pinard/p/6351319.html

  3. 周志華《機器學習》

  4. 李航《統計學習方法》

  5. 《推薦系統》

  6. 《機器學習實戰》

近期熱文

加入微信機器學習交流

請新增微信:guodongwe1991

備註姓名-單位-研究方向

廣告、商業合作

請新增微信:guodongwe1991

(備註:商務合作)