SVD在推荐系统中的应用详解以及算法推导
轉(zhuǎn)載請聲明出處http://blog.csdn.net/zhongkejingwang/article/details/43083603
? ? 前面文章SVD原理及推導(dǎo)已經(jīng)把SVD的過程講的很清楚了,本文介紹如何將SVD應(yīng)用于推薦系統(tǒng)中的評分預(yù)測問題。其實(shí)也就是復(fù)現(xiàn)Koren在NetFlix大賽中的使用到的SVD算法以及其擴(kuò)展出的RSVD、SVD++。
? ?記得剛接觸SVD是在大二,那會(huì)兒跟師兄在做項(xiàng)目的時(shí)候就用到這個(gè)東西,然后到大三下學(xué)期剛好百度舉辦了一個(gè)電影推薦算法大賽,躍躍欲試地參加了,當(dāng)時(shí)就用的SVD而且只會(huì)用這個(gè),后來覺得效果還不錯(cuò),接著就又找來了Koren的論文,看了一下把SVD++也實(shí)現(xiàn)了,把兩者結(jié)果融合得到不少的提升。下面是最終比賽結(jié)果:
? ? ? ? ? ? ? ? ? ? ? ??
其實(shí)這個(gè)最終結(jié)果是和第11名組隊(duì)后融合了他的結(jié)果,所以成績是一樣的。但是單純地使用SVD、SVD++融合得到的結(jié)果最好的也能到0.606左右,這個(gè)結(jié)果已經(jīng)很牛逼了,記得當(dāng)時(shí)0.6111在榜上維持了兩個(gè)多星期的No.1。當(dāng)時(shí)的遺憾就是沒能實(shí)現(xiàn)更多的SVD擴(kuò)展算法,導(dǎo)致融合的結(jié)果沒法再提升,代碼也由于時(shí)間倉促寫的很臃腫,前段時(shí)間有空把算法重寫了一下并實(shí)現(xiàn)了更多的擴(kuò)展算法,已經(jīng)共享到github上了,有興趣的可以看看:https://github.com/jingchenUSTC/SVDRecommenderSystem
? ? 下面開始介紹SVD算法,假設(shè)存在以下user和item的數(shù)據(jù)矩陣:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
這是一個(gè)極其稀疏的矩陣,這里把這個(gè)評分矩陣記為R,其中的元素表示user對item的打分,“?”表示未知的,也就是要你去預(yù)測的,現(xiàn)在問題來了:如何去預(yù)測未知的評分值呢?上一篇文章用SVD證明了對任意一個(gè)矩陣A,都有它的滿秩分解:
? ? ? ? ? ? ?
? ?那么剛才的評分矩陣R也存在這樣一個(gè)分解,所以可以用兩個(gè)矩陣P和Q的乘積來表示評分矩陣R:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
上圖中的U表示用戶數(shù),I表示商品數(shù)。然后就是利用R中的已知評分訓(xùn)練P和Q使得P和Q相乘的結(jié)果最好地?cái)M合已知的評分,那么未知的評分也就可以用P的某一行乘上Q的某一列得到了:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
這是預(yù)測用戶u對商品i的評分,它等于P矩陣的第u行乘上Q矩陣的第i列。這個(gè)是最基本的SVD算法,那么如何通過已知評分訓(xùn)練得到P和Q的具體數(shù)值呢?
假設(shè)已知的評分為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
則真實(shí)值與預(yù)測值的誤差為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
繼而可以計(jì)算出總的誤差平方和:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
只要通過訓(xùn)練把SSE降到最小那么P、Q就能最好地?cái)M合R了。那又如何使SSE降到最小呢?下面介紹一個(gè)常用的局部優(yōu)化算法。
梯度下降法
? ?為了說明梯度下降法,我找了一張PPT:
也就是說如果要最小化目標(biāo)函數(shù),必須往其負(fù)梯度方向搜索。這就是梯度下降法,注意它是一個(gè)局部優(yōu)化算法,也就是說有可能落到局部最優(yōu)解而不是全局最優(yōu)解。
Basic SVD
利用梯度下降法可以求得SSE在Puk變量(也就是P矩陣的第u行第k列的值)處的梯度:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
利用求導(dǎo)鏈?zhǔn)椒▌t,e^2先對e求導(dǎo)再乘以e對Puk的求導(dǎo):
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
由于
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
所以
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
上式中括號(hào)里的那一坨式子如果展開來看的話,其與Puk有關(guān)的項(xiàng)只有PukQki,其他的無關(guān)項(xiàng)對Puk的求導(dǎo)均等于0
所以求導(dǎo)結(jié)果為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
所以
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
為了讓式子更簡潔,令
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
這樣做對結(jié)果沒有影響,只是為了把求導(dǎo)結(jié)果前的2去掉,更好看點(diǎn)。得到
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
現(xiàn)在得到了目標(biāo)函數(shù)在Puk處的梯度了,那么按照梯度下降法,將Puk往負(fù)梯度方向變化:
令更新的步長(也就是學(xué)習(xí)速率)為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
則Puk的更新式為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
同樣的方式可得到Qik的更新式為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
得到了更新的式子,現(xiàn)在開始來討論這個(gè)更新要怎么進(jìn)行。有兩種選擇:1、計(jì)算完所有已知評分的預(yù)測誤差后再對P、Q進(jìn)行更新。2、每計(jì)算完一個(gè)eui后立即對Pu和qi進(jìn)行更新。這兩種方式都有名稱,分別叫:1、批梯度下降。2、隨機(jī)梯度下降。兩者的區(qū)別就是批梯度下降在下一輪迭代才能使用本次迭代的更新值,隨機(jī)梯度下降本次迭代中當(dāng)前樣本使用的值可能就是上一個(gè)樣本更新的值。由于隨機(jī)性可以帶來很多好處,比如有利于避免局部最優(yōu)解,所以現(xiàn)在大多傾向于使用隨機(jī)梯度下降進(jìn)行更新。
RSVD
? ?上面就是基本的SVD算法,但是,問題來了,上面的訓(xùn)練是針對已知評分?jǐn)?shù)據(jù)的,過分地?cái)M合這部分?jǐn)?shù)據(jù)有可能導(dǎo)致模型的測試效果很差,在測試集上面表現(xiàn)很糟糕。這就是過擬合問題,關(guān)于過擬合與欠擬合可以看一下這張圖
第一個(gè)是欠擬合,第二個(gè)剛好,第三個(gè)過擬合。那么如何避免過擬合呢?那就是在目標(biāo)函數(shù)中加入正則化參數(shù)(加入懲罰項(xiàng)),對于目標(biāo)函數(shù)來說,P矩陣和Q矩陣中的所有值都是變量,這些變量在不知道哪個(gè)變量會(huì)帶來過擬合的情況下,對所有變量都進(jìn)行懲罰:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
這時(shí)候目標(biāo)函數(shù)對Puk的導(dǎo)數(shù)就發(fā)生變化了,現(xiàn)在就來求加入懲罰項(xiàng)后的導(dǎo)數(shù)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
括號(hào)里第一項(xiàng)對Puk的求導(dǎo)前面已經(jīng)求過了,第二項(xiàng)對Puk的求導(dǎo)很容易求得,第三項(xiàng)與Puk無關(guān),導(dǎo)數(shù)為0,所以
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
同理可得SSE對qik的導(dǎo)數(shù)為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
將這兩個(gè)變量往負(fù)梯度方向變化,則更新式為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
這就是正則化后的SVD,也叫RSVD。
加入偏置的SVD、RSVD
? ?關(guān)于SVD算法的變種太多了,叫法也不統(tǒng)一,在預(yù)測式子上加點(diǎn)參數(shù)又會(huì)出來一個(gè)名稱。由于用戶對商品的打分不僅取決于用戶和商品間的某種關(guān)系,還取決于用戶和商品獨(dú)有的性質(zhì),Koren將SVD的預(yù)測公式改成這樣
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
第一項(xiàng)為總的平均分,bu為用戶u的屬性值,bi為商品i的屬性值,加入的這兩個(gè)變量在SSE式子中同樣需要懲罰,那么SSE就變成了下面這樣:
? ??
由上式可以看出SSE對Puk和qik的導(dǎo)數(shù)都沒有變化,但此時(shí)多了bu和bi變量,同樣要求出其更新式。首先求SSE對bu的導(dǎo)數(shù),只有第一項(xiàng)和第四項(xiàng)和bu有關(guān),第一項(xiàng)對bu的求導(dǎo)和之前的求導(dǎo)類似,用鏈?zhǔn)椒▌t即可求得,第四項(xiàng)直接求導(dǎo)即可,最后可得偏導(dǎo)數(shù)為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
同理可得對bi的導(dǎo)數(shù)為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
所以往其負(fù)梯度方向變化得到其更新式為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
這就是修改后的SVD(RSVD)。
ASVD
? ? 全稱叫Asymmetric-SVD,即非對稱SVD,其預(yù)測式子為
R(u)表示用戶u評過分的商品集合,N(u)表示用戶u瀏覽過但沒有評過分的商品集合,Xj和Yj是商品的屬性。這個(gè)模型很有意思,看預(yù)測式子,用戶矩陣P已經(jīng)被去掉了,取而代之的是利用用戶評過分的商品和用戶瀏覽過尚未評分的商品屬性來表示用戶屬性,這有一定的合理性,因?yàn)橛脩舻男袨橛涗洷旧砭湍芊磻?yīng)用戶的喜好。而且,這個(gè)模型可以帶來一個(gè)很大的好處,一個(gè)商場或者網(wǎng)站的用戶數(shù)成千上萬甚至過億,存儲(chǔ)用戶屬性的二維矩陣會(huì)占用巨大的存儲(chǔ)空間,而商品數(shù)卻沒有那么多,所以這個(gè)模型的好處顯而易見。但是它有個(gè)缺點(diǎn),就是迭代時(shí)間太長了,這是可以預(yù)見的,以時(shí)間換空間嘛。
同樣的,需要計(jì)算其各個(gè)參數(shù)的偏導(dǎo)數(shù),求出更新式,顯然,bu和bi的更新式和剛才求出的一樣
其中的向量z等于下面這坨
? ? ? ? ? ? ? ? ? ? ? ?
現(xiàn)在要求qik、x和y的更新式,在這里如果把z看成Pu則根據(jù)前面求得的更新式可得qik的更新式:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
求Xj的導(dǎo)數(shù)需要有點(diǎn)耐心,SSE的第二項(xiàng)對Xj的導(dǎo)數(shù)很容易得到,現(xiàn)在來求第一項(xiàng)對Xj的導(dǎo)數(shù):
???
上式求和符中的i,j都是屬于R(u)的,可以看到Zm只有當(dāng)m==k時(shí)才與Xjk有關(guān),所以
? ? ??
因?yàn)?/p>
? ? ? ??
所以
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
所以得到SSE對Xjk的導(dǎo)數(shù)為
??????????????????
同理可得SSE對Yjk的導(dǎo)數(shù)為
?????????????????????????????????
所以得到Xjk和Yjk的更新方程
??????????????
?????????????????????????
這就叫ASVD。。。。。。
SVDPP
? ? 最后這個(gè)模型也是Koren文章中提到的,SVDPlusPlus(SVD++),它的預(yù)測式子為
? ? ? ? ? ? ? ? ? ? ? ? ? ?
這里的N(u)表示用戶u行為記錄(包括瀏覽的和評過分的商品集合)。看了ASVD的更新式推導(dǎo)過程再來看這個(gè)應(yīng)該很簡單,Puk和qik的更新式子不變,Yjk的更新式子和ASVD的更新式一樣:
??????????????????????????????????
? ? 這些就是Koren在NetFlix大賽中用到的SVD算法,最后,還有一個(gè)需要提的:
對偶算法
? ? 將前面預(yù)測公式中的u和i調(diào)換位置得到其對偶算法,對于RSVD而言,u和i的位置是等價(jià)的、對稱的,所以其對偶算法和其本身沒有區(qū)別,但對于ASVD和SVD++則不同,有時(shí)候?qū)ε妓惴ǖ玫降慕Y(jié)果更加精確,并且,如果將對偶算法和原始算法的預(yù)測結(jié)果融合在一起的話,效果的提升會(huì)讓你吃驚!
對偶的ASVD預(yù)測公式:
這里R(i)表示評論過商品i的用戶集合,N(i)表示瀏覽過商品i但沒有評論的用戶集合。由于用戶數(shù)量龐大,所以對偶的ASVD會(huì)占用很大空間,這里需要做取舍了。
對偶的SVD++預(yù)測公式:
? ? ??
這里N(i)表示對商品i有過行為(瀏覽或評分)的用戶集合。
實(shí)現(xiàn)這一對偶的操作其實(shí)很簡單,只要讀取數(shù)據(jù)的時(shí)候把用戶id和商品id對調(diào)位置即可,也就是將R矩陣轉(zhuǎn)置后再訓(xùn)練。
? ? 暫時(shí)實(shí)現(xiàn)的算法就這些,代碼都在github上了,有興趣的可以看看,地址:https://github.com/jingchenUSTC/SVDRecommenderSystem
總結(jié)
以上是生活随笔為你收集整理的SVD在推荐系统中的应用详解以及算法推导的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全栈必备Linux 基础
- 下一篇: 大话推荐系统