矩陣分解在協同過濾推薦算法中的應用

協同過濾推薦算法總結中,咱們講到了用矩陣分解作協同過濾是普遍使用的方法,這裏就對矩陣分解在協同過濾推薦算法中的應用作一個總結。(過年前最後一篇!祝你們新年快樂!明年的目標是寫120篇機器學習,深度學習和NLP相關的文章)javascript

1、1. 矩陣分解用於推薦算法要解決的問題

    在推薦系統中,咱們經常遇到的問題是這樣的,咱們有不少用戶和物品,也有少部分用戶對少部分物品的評分,咱們但願預測目標用戶對其餘未評分物品的評分,進而將評分高的物品推薦給目標用戶。好比下面的用戶物品評分表:css

用戶\物品html

物品1 物品2 物品3 物品4 物品5 物品6 物品7
用戶1 3 5 1
用戶2 2 4
用戶3 4
用戶4 2 1
用戶5 1 4

    對於每一個用戶,咱們但願較準確的預測出用戶對未評分物品的評分。對於這個問題咱們有不少解決方法,本文咱們關注於用矩陣分解的方法來作。若是將m個用戶和n個物品對應的評分看作一個矩陣\(M\),咱們但願經過矩陣分解來解決這個問題。java

2、傳統的奇異值分解SVD用於推薦

    說道矩陣分解,咱們首先想到的就是奇異值分解SVD。在奇異值分解(SVD)原理與在降維中的應用中,咱們對SVD原理作了總結。若是你們對SVD不熟悉的話,能夠翻看該文。python

    此時能夠將這個用戶物品對應的\(m \times n\)矩陣\(M\)進行SVD分解,並經過選擇部分較大的一些奇異值來同時進行降維,也就是說矩陣\(M\)此時分解爲:
\[ M_{m \times n}=U_{m \times k}\Sigma_{k \times k}V_{k \times n}^T \]
  算法

    其中k是矩陣\(M\)中較大的部分奇異值的個數,通常會遠遠的小於用戶數和物品樹。若是咱們要預測第i個用戶對第j個物品的評分\(m_{ij}\),則只須要計算\(u_i^T\Sigma v_j\)便可。經過這種方法,咱們能夠將評分表裏面全部沒有評分的位置獲得一個預測評分。經過找到最高的若干個評分對應的物品推薦給用戶。編程

    能夠看出這種方法簡單直接,彷佛頗有吸引力。可是有一個很大的問題咱們忽略了,就是SVD分解要求矩陣是稠密的,也就是說矩陣的全部位置不能有空白。有空白時咱們的\(M\)是無法直接去SVD分解的。你們會說,若是這個矩陣是稠密的,那不就是說咱們都已經找到全部用戶物品的評分了嘛,那還要SVD幹嗎! 的確,這是一個問題,傳統SVD採用的方法是對評分矩陣中的缺失值進行簡單的補全,好比用全局平均值或者用用戶物品平均值補全,獲得補全後的矩陣。接着能夠用SVD分解並降維。瀏覽器

    雖然有了上面的補全策略,咱們的傳統SVD在推薦算法上仍是較難使用。由於咱們的用戶數和物品通常都是超級大,隨便就成千上萬了。這麼大一個矩陣作SVD分解是很是耗時的。那麼有沒有簡化版的矩陣分解能夠用呢?咱們下面來看看實際能夠用於推薦系統的矩陣分解。微信

3、FunkSVD算法用於推薦

    FunkSVD是在傳統SVD面臨計算效率問題時提出來的,既然將一個矩陣作SVD分解成3個矩陣很耗時,同時還面臨稀疏的問題,那麼咱們能不能避開稀疏問題,同時只分解成兩個矩陣呢?也就是說,如今指望咱們的矩陣\(M\)這樣進行分解:
\[ M_{m \times n}=P_{m \times k}^TQ_{k \times n} \]markdown

    咱們知道SVD分解已經很成熟了,可是FunkSVD如何將矩陣\(M\)分解爲\(P\)\(Q\)呢?這裏採用了線性迴歸的思想。咱們的目標是讓用戶的評分和用矩陣乘積獲得的評分殘差儘量的小,也就是說,能夠用均方差做爲損失函數,來尋找最終的\(P\)\(Q\)

    對於某一個用戶評分\(m_{ij}\),若是用FunkSVD進行矩陣分解,則對應的表示爲\(q_j^Tp_i\),採用均方差作爲損失函數,則咱們指望\((m_{ij}-q_j^Tp_i)^2\)儘量的小,若是考慮全部的物品和樣本的組合,則咱們指望最小化下式:
\[ \sum\limits_{i,j}(m_{ij}-q_j^Tp_i)^2 \]

    只要咱們可以最小化上面的式子,並求出極值所對應的\(p_i, q_j\),則咱們最終能夠獲得矩陣\(P\)\(Q\),那麼對於任意矩陣\(M\)任意一個空白評分的位置,咱們能夠經過\(q_j^Tp_i\)計算預測評分。很漂亮的方法!

    固然,在實際應用中,咱們爲了防止過擬合,會加入一個L2的正則化項,所以正式的FunkSVD的優化目標函數\(J(p,q)\)是這樣的:
\[ \underbrace{arg\;min}_{p_i,q_j}\;\sum\limits_{i,j}(m_{ij}-q_j^Tp_i)^2 + \lambda(||p_i||_2^2 + ||q_j||_2^2 ) \]

    其中\(\lambda\)爲正則化係數,須要調參。對於這個優化問題,咱們通常經過梯度降低法來進行優化獲得結果。

    將上式分別對\(p_i, q_j\)求導咱們獲得:
\[ \frac{\partial J}{\partial p_i} = -2(m_{ij}-q_j^Tp_i)q_j + 2\lambda p_i \]
\[ \frac{\partial J}{\partial q_j} = -2(m_{ij}-q_j^Tp_i)p_i + 2\lambda q_j \]
 

    則在梯度降低法迭代時,\(p_i, q_j\)的迭代公式爲:
\[ p_i = p_i + \alpha((m_{ij}-q_j^Tp_i)q_j - \lambda p_i) \]
\[ q_j =q_j +  \alpha((m_{ij}-q_j^Tp_i)p_i - \lambda q_j) \]

    經過迭代咱們最終能夠獲得\(P\)\(Q\),進而用於推薦。FunkSVD算法雖然思想很簡單,可是在實際應用中效果很是好,這真是驗證了大道至簡。

4、BiasSVD算法用於推薦

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

    假設評分系統平均分爲\(\mu\),第i個用戶的用戶偏置項爲\(b_i\),而第j個物品的物品偏置項爲\(b_j\),則加入了偏置項之後的優化目標函數\(J(p,q)\)是這樣的
\[ \underbrace{arg\;min}_{p_i,q_j}\;\sum\limits_{i,j}(m_{ij}-\mu-b_i-b_j-q_j^Tp_i)^2 + \lambda(||p_i||_2^2 + ||q_j||_2^2 + ||b_i||_2^2 + ||b_j||_2^2) \]

    這個優化目標也能夠採用梯度降低法求解。和FunkSVD不一樣的是,此時咱們多了兩個偏執項\(b_i,b_j\),,\(p_i, q_j\)的迭代公式和FunkSVD相似,只是每一步的梯度導數稍有不一樣而已,這裏就不給出了。而\(b_i,b_j\)通常能夠初始設置爲0,而後參與迭代。這裏給出\(b_i,b_j\)的迭代方法
\[ b_i = b_i + \alpha(m_{ij}-\mu-b_i-b_j-q_j^Tp_i -\lambda b_i) \]
\[ b_j = b_j + \alpha(m_{ij}-\mu-b_i-b_j-q_j^Tp_i -\lambda b_j) \]

    經過迭代咱們最終能夠獲得\(P\)\(Q\),進而用於推薦。BiasSVD增長了一些額外因素的考慮,所以在某些場景會比FunkSVD表現好。

5、SVD++算法用於推薦

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

    對於某一個用戶i,它提供了隱式反饋的物品集合定義爲\(N(i)\), 這個用戶對某個物品j對應的隱式反饋修正的評分值爲\(c_{ij}\), 那麼該用戶全部的評分修正值爲\(\sum\limits_{s \in N(i)}c_{sj}\)。通常咱們將它表示爲用\(q_j^Ty_s\)形式,則加入了隱式反饋項之後的優化目標函數\(J(p,q)\)是這樣的:
\[ \underbrace{arg\;min}_{p_i,q_j}\;\sum\limits_{i,j}(m_{ij}-\mu-b_i-b_j-q_j^Tp_i - q_j^T|N(i)|^{-1/2}\sum\limits_{s \in N(i)}y_{s})^2+ \lambda(||p_i||_2^2 + ||q_j||_2^2 + ||b_i||_2^2 + ||b_j||_2^2 + \sum\limits_{s \in N(i)}||y_{s}||_2^2) \]

    其中,引入\(|N(i)|^{-1/2}\)是爲了消除不一樣|N(i)|個數引發的差別。式子夠長的,不過須要考慮用戶的隱式反饋時,使用SVD++仍是不錯的選擇。

6、6. 矩陣分解推薦方法小結

    FunkSVD將矩陣分解用於推薦方法推到了新的高度,在實際應用中使用也是很是普遍。固然矩陣分解方法也在不停的進步,目前張量分解和分解機方法是矩陣分解推薦方法從此的一個趨勢。

    對於矩陣分解用於推薦方法自己來講,它容易編程實現,實現複雜度低,預測效果也好,同時還能保持擴展性。這些都是它寶貴的優勢。固然,矩陣分解方法有時候解釋性仍是沒有基於機率的邏輯迴歸之類的推薦算法好,不過這也不影響它的流形程度。小的推薦系統用矩陣分解應該是一個不錯的選擇。大型的話,則矩陣分解比起如今的深度學習的一些方法不佔優點。

 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: 微信:nickchen121)

posted @ 2019-07-19 17:56  十七歲的有德 閱讀( ...) 評論( ...) 編輯 收藏
相關文章
相關標籤/搜索