推荐系统遇上深度学习(二十)-贝叶斯个性化排序算法原理及实战
排序推薦算法大體上可以分為三類,第一類排序算法類別是點(diǎn)對方法(Pointwise Approach),這類算法將排序問題被轉(zhuǎn)化為分類、回歸之類的問題,并使用現(xiàn)有分類、回歸等方法進(jìn)行實(shí)現(xiàn)。第二類排序算法是成對方法(Pairwise Approach),在序列方法中,排序被轉(zhuǎn)化為對序列分類或?qū)π蛄谢貧w。所謂的pair就是成對的排序,比如(a,b)一組表明a比b排的靠前。第三類排序算法是列表方法(Listwise Approach),它采用更加直接的方法對排序問題進(jìn)行了處理。它在學(xué)習(xí)和預(yù)測過程中都將排序列表作為一個(gè)樣本。排序的組結(jié)構(gòu)被保持。
之前我們介紹的算法大都是Pointwise的方法,今天我們來介紹一種Pairwise的方法:貝葉斯個(gè)性化排序(Bayesian Personalized Ranking, 以下簡稱BPR)
1、BPR算法簡介
1.1 基本思路
在BPR算法中,我們將任意用戶u對應(yīng)的物品進(jìn)行標(biāo)記,如果用戶u在同時(shí)有物品i和j的時(shí)候點(diǎn)擊了i,那么我們就得到了一個(gè)三元組<u,i,j>,它表示對用戶u來說,i的排序要比j靠前。如果對于用戶u來說我們有m組這樣的反饋,那么我們就可以得到m組用戶u對應(yīng)的訓(xùn)練樣本。
這里,我們做出兩個(gè)假設(shè):
為了便于表述,我們用>u符號表示用戶u的偏好,上面的<u,i,j>可以表示為:i >u j。
在BPR中,我們也用到了類似矩陣分解的思想,對于用戶集U和物品集I對應(yīng)的U*I的預(yù)測排序矩陣,我們期望得到兩個(gè)分解后的用戶矩陣W(|U|×k)和物品矩陣H(|I|×k),滿足:
?
?
那么對于任意一個(gè)用戶u,對應(yīng)的任意一個(gè)物品i,我們預(yù)測得出的用戶對該物品的偏好計(jì)算如下:
?
?
而模型的最終目標(biāo)是尋找合適的矩陣W和H,讓X-(公式打不出來,這里代表的是X上面有一個(gè)橫線,即W和H矩陣相乘后的結(jié)果)和X(實(shí)際的評分矩陣)最相似??吹竭@里,也許你會說,BPR和矩陣分解沒有什區(qū)別呀?是的,到目前為止的基本思想是一致的,但是具體的算法運(yùn)算思路,確實(shí)千差萬別的,我們慢慢道來。
1.2 算法運(yùn)算思路
BPR 基于最大后驗(yàn)估計(jì)P(W,H|>u)來求解模型參數(shù)W,H,這里我們用θ來表示參數(shù)W和H, >u代表用戶u對應(yīng)的所有商品的全序關(guān)系,則優(yōu)化目標(biāo)是P(θ|>u)。根據(jù)貝葉斯公式,我們有:
?
?
由于我們求解假設(shè)了用戶的排序和其他用戶無關(guān),那么對于任意一個(gè)用戶u來說,P(>u)對所有的物品一樣,所以有:
?
?
這個(gè)優(yōu)化目標(biāo)轉(zhuǎn)化為兩部分。第一部分和樣本數(shù)據(jù)集D有關(guān),第二部分和樣本數(shù)據(jù)集D無關(guān)。
第一部分
對于第一部分,由于我們假設(shè)每個(gè)用戶之間的偏好行為相互獨(dú)立,同一用戶對不同物品的偏序相互獨(dú)立,所以有:
?
?
上面的式子類似于極大似然估計(jì),若用戶u相比于j來說更偏向i,那么我們就希望P(i >u j|θ)出現(xiàn)的概率越大越好。
上面的式子可以進(jìn)一步改寫成:
?
?
而對于P(i >u j|θ)這個(gè)概率,我們可以使用下面這個(gè)式子來代替:
?
?
其中,σ(x)是sigmoid函數(shù),σ里面的項(xiàng)我們可以理解為用戶u對i和j偏好程度的差異,我們當(dāng)然希望i和j的差異越大越好,這種差異如何體現(xiàn),最簡單的就是差值:
?
?
省略θ我們可以將式子簡略的寫為:
?
?
因此優(yōu)化目標(biāo)的第一項(xiàng)可以寫作:
?
?
哇,是不是很簡單的思想,對于訓(xùn)練數(shù)據(jù)中的<u,i,j>,用戶更偏好于i,那么我們當(dāng)然希望在X-矩陣中ui對應(yīng)的值比uj對應(yīng)的值大,而且差距越大越好!
第二部分
回想之前我們通過貝葉斯角度解釋正則化的文章:https://www.jianshu.com/p/4d562f2c06b8
當(dāng)θ的先驗(yàn)分布是正態(tài)分布時(shí),其實(shí)就是給損失函數(shù)加入了正則項(xiàng),因此我們可以假定θ的先驗(yàn)分布是正態(tài)分布:
?
?
所以:
?
?
因此,最終的最大對數(shù)后驗(yàn)估計(jì)函數(shù)可以寫作:
?
?
剩下的我們就可以通過梯度上升法(因?yàn)槭且屔鲜阶畲蠡?來求解了。我們這里就略過了,BPR的思想已經(jīng)很明白了吧,哈哈!讓我們來看一看如何實(shí)現(xiàn)吧。
2、算法實(shí)現(xiàn)
本文的github地址為:https://github.com/princewen/tensorflow_practice/tree/master/recommendation/Basic-BPR-Demo
所用到的數(shù)據(jù)集是movieslen 100k的數(shù)據(jù)集,下載地址為:http://grouplens.org/datasets/movielens/
數(shù)據(jù)預(yù)處理
首先,我們需要處理一下數(shù)據(jù),得到每個(gè)用戶打分過的電影,同時(shí),還需要得到用戶的數(shù)量和電影的數(shù)量。
def load_data():user_ratings = defaultdict(set)max_u_id = -1max_i_id = -1with open('data/u.data','r') as f:for line in f.readlines():u,i,_,_ = line.split("\t")u = int(u)i = int(i)user_ratings[u].add(i)max_u_id = max(u,max_u_id)max_i_id = max(i,max_i_id)print("max_u_id:",max_u_id)print("max_i_idL",max_i_id)return max_u_id,max_i_id,user_ratings下面我們會對每一個(gè)用戶u,在user_ratings中隨機(jī)找到他評分過的一部電影i,保存在user_ratings_test,后面構(gòu)造訓(xùn)練集和測試集需要用到。
def generate_test(user_ratings):"""對每一個(gè)用戶u,在user_ratings中隨機(jī)找到他評分過的一部電影i,保存在user_ratings_test,我們?yōu)槊總€(gè)用戶取出的這一個(gè)電影,是不會在訓(xùn)練集中訓(xùn)練到的,作為測試集用。"""user_test = dict()for u,i_list in user_ratings.items():user_test[u] = random.sample(user_ratings[u],1)[0]return user_test構(gòu)建訓(xùn)練數(shù)據(jù)
我們構(gòu)造的訓(xùn)練數(shù)據(jù)是<u,i,j>的三元組,i可以根據(jù)剛才生成的用戶評分字典得到,j可以利用負(fù)采樣的思想,認(rèn)為用戶沒有看過的電影都是負(fù)樣本:
構(gòu)造測試數(shù)據(jù)
同樣構(gòu)造三元組,我們剛才給每個(gè)用戶單獨(dú)抽出了一部電影,這個(gè)電影作為i,而用戶所有沒有評分過的電影都是負(fù)樣本j:
模型構(gòu)建
首先回憶一下我們需要學(xué)習(xí)的參數(shù)θ,其實(shí)就是用戶矩陣W(|U|×k)和物品矩陣H(|I|×k)對應(yīng)的值,對于我們的模型來說,可以簡單理解為由id到embedding的轉(zhuǎn)化,因此有:
回想一下我們要優(yōu)化的目標(biāo),第一部分是ui和uj對應(yīng)的預(yù)測值的評分之差,再經(jīng)由sigmoid變換得到的[0,1]值,我們希望這個(gè)值越大越好,對于損失來說,當(dāng)然是越小越好。因此,計(jì)算如下:
x = tf.reduce_sum(tf.multiply(u_emb,(i_emb-j_emb)),1,keep_dims=True) loss1 = - tf.reduce_mean(tf.log(tf.sigmoid(x)))第二部分是我們的正則項(xiàng),參數(shù)就是我們的embedding值,所以正則項(xiàng)計(jì)算如下:
l2_norm = tf.add_n([tf.reduce_sum(tf.multiply(u_emb, u_emb)),tf.reduce_sum(tf.multiply(i_emb, i_emb)),tf.reduce_sum(tf.multiply(j_emb, j_emb))])因此,我們模型整個(gè)的優(yōu)化目標(biāo)可以寫作:
regulation_rate = 0.0001 bprloss = regulation_rate * l2_norm - tf.reduce_mean(tf.log(tf.sigmoid(x)))train_op = tf.train.GradientDescentOptimizer(0.01).minimize(bprloss)至此,我們整個(gè)模型就介紹完了,如果大家想要了解完整的代碼實(shí)現(xiàn),可以參考github喲。
3、總結(jié)
1.BPR是基于矩陣分解的一種排序算法,它不是做全局的評分優(yōu)化,而是針對每一個(gè)用戶自己的商品喜好分貝做排序優(yōu)化。
2.它是一種pairwise的排序算法,對于每一個(gè)三元組<u,i,j>,模型希望能夠使用戶u對物品i和j的差異更明顯。
3.同時(shí),引入了貝葉斯先驗(yàn),假設(shè)參數(shù)服從正態(tài)分布,在轉(zhuǎn)換后變?yōu)榱薒2正則,減小了模型的過擬合。
參考文獻(xiàn)
1、http://www.cnblogs.com/pinard/p/9128682.html
2、http://www.cnblogs.com/pinard/p/9163481.html
總結(jié)
以上是生活随笔為你收集整理的推荐系统遇上深度学习(二十)-贝叶斯个性化排序算法原理及实战的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ElasticSearch学习资料
- 下一篇: 当你看完这篇朴素贝叶斯(NB)算法后,是