日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

推荐系统遇上深度学习(二十)-贝叶斯个性化排序算法原理及实战

發(fā)布時間:2024/1/17 windows 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 推荐系统遇上深度学习(二十)-贝叶斯个性化排序算法原理及实战 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


排序推薦算法大體上可以分為三類,第一類排序算法類別是點(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ù)測過程中都將排序列表作為一個樣本。排序的組結(jié)構(gòu)被保持。

之前我們介紹的算法大都是Pointwise的方法,今天我們來介紹一種Pairwise的方法:貝葉斯個性化排序(Bayesian Personalized Ranking, 以下簡稱BPR)

1、BPR算法簡介

1.1 基本思路

在BPR算法中,我們將任意用戶u對應(yīng)的物品進(jìn)行標(biāo)記,如果用戶u在同時有物品i和j的時候點(diǎn)擊了i,那么我們就得到了一個三元組<u,i,j>,它表示對用戶u來說,i的排序要比j靠前。如果對于用戶u來說我們有m組這樣的反饋,那么我們就可以得到m組用戶u對應(yīng)的訓(xùn)練樣本。

這里,我們做出兩個假設(shè):

  • 每個用戶之間的偏好行為相互獨(dú)立,即用戶u在商品i和j之間的偏好和其他用戶無關(guān)。
  • 同一用戶對不同物品的偏序相互獨(dú)立,也就是用戶u在商品i和j之間的偏好和其他的商品無關(guān)。
  • 為了便于表述,我們用>u符號表示用戶u的偏好,上面的<u,i,j>可以表示為:i >u j。

    在BPR中,我們也用到了類似矩陣分解的思想,對于用戶集U和物品集I對應(yīng)的U*I的預(yù)測排序矩陣,我們期望得到兩個分解后的用戶矩陣W(|U|×k)和物品矩陣H(|I|×k),滿足:

    ?

    ?

    那么對于任意一個用戶u,對應(yīng)的任意一個物品i,我們預(yù)測得出的用戶對該物品的偏好計(jì)算如下:

    ?

    ?

    而模型的最終目標(biāo)是尋找合適的矩陣W和H,讓X-(公式打不出來,這里代表的是X上面有一個橫線,即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),那么對于任意一個用戶u來說,P(>u)對所有的物品一樣,所以有:

    ?

    ?

    這個優(yōu)化目標(biāo)轉(zhuǎn)化為兩部分。第一部分和樣本數(shù)據(jù)集D有關(guān),第二部分和樣本數(shù)據(jù)集D無關(guān)。

    第一部分

    對于第一部分,由于我們假設(shè)每個用戶之間的偏好行為相互獨(dú)立,同一用戶對不同物品的偏序相互獨(dú)立,所以有:

    ?

    ?

    上面的式子類似于極大似然估計(jì),若用戶u相比于j來說更偏向i,那么我們就希望P(i >u j|θ)出現(xiàn)的概率越大越好。

    上面的式子可以進(jìn)一步改寫成:

    ?

    ?

    而對于P(i >u j|θ)這個概率,我們可以使用下面這個式子來代替:

    ?

    ?

    其中,σ(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ù)加入了正則項(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ù),得到每個用戶打分過的電影,同時,還需要得到用戶的數(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

    下面我們會對每一個用戶u,在user_ratings中隨機(jī)找到他評分過的一部電影i,保存在user_ratings_test,后面構(gòu)造訓(xùn)練集和測試集需要用到。

    def generate_test(user_ratings):"""對每一個用戶u,在user_ratings中隨機(jī)找到他評分過的一部電影i,保存在user_ratings_test,我們?yōu)槊總€用戶取出的這一個電影,是不會在訓(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ù)樣本:

    def generate_train_batch(user_ratings,user_ratings_test,item_count,batch_size=512):"""構(gòu)造訓(xùn)練用的三元組對于隨機(jī)抽出的用戶u,i可以從user_ratings隨機(jī)抽出,而j也是從總的電影集中隨機(jī)抽出,當(dāng)然j必須保證(u,j)不在user_ratings中"""t = []for b in range(batch_size):u = random.sample(user_ratings.keys(),1)[0]i = random.sample(user_ratings[u],1)[0]while i==user_ratings_test[u]:i = random.sample(user_ratings[u],1)[0]j = random.randint(1,item_count)while j in user_ratings[u]:j = random.randint(1,item_count)t.append([u,i,j])return np.asarray(t)

    構(gòu)造測試數(shù)據(jù)
    同樣構(gòu)造三元組,我們剛才給每個用戶單獨(dú)抽出了一部電影,這個電影作為i,而用戶所有沒有評分過的電影都是負(fù)樣本j:

    def generate_test_batch(user_ratings,user_ratings_test,item_count):"""對于每個用戶u,它的評分電影i是我們在user_ratings_test中隨機(jī)抽取的,它的j是用戶u所有沒有評分過的電影集合,比如用戶u有1000部電影沒有評分,那么這里該用戶的測試集樣本就有1000個"""for u in user_ratings.keys():t = []i = user_ratings_test[u]for j in range(1,item_count + 1):if not(j in user_ratings[u]):t.append([u,i,j])yield np.asarray(t)

    模型構(gòu)建
    首先回憶一下我們需要學(xué)習(xí)的參數(shù)θ,其實(shí)就是用戶矩陣W(|U|×k)和物品矩陣H(|I|×k)對應(yīng)的值,對于我們的模型來說,可以簡單理解為由id到embedding的轉(zhuǎn)化,因此有:

    u = tf.placeholder(tf.int32,[None]) i = tf.placeholder(tf.int32,[None]) j = tf.placeholder(tf.int32,[None])user_emb_w = tf.get_variable("user_emb_w", [user_count + 1, hidden_dim],initializer=tf.random_normal_initializer(0, 0.1)) item_emb_w = tf.get_variable("item_emb_w", [item_count + 1, hidden_dim],initializer=tf.random_normal_initializer(0, 0.1))u_emb = tf.nn.embedding_lookup(user_emb_w, u) i_emb = tf.nn.embedding_lookup(item_emb_w, i) j_emb = tf.nn.embedding_lookup(item_emb_w, j)

    回想一下我們要優(yōu)化的目標(biāo),第一部分是ui和uj對應(yīng)的預(yù)測值的評分之差,再經(jīng)由sigmoid變換得到的[0,1]值,我們希望這個值越大越好,對于損失來說,當(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))])

    因此,我們模型整個的優(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)

    至此,我們整個模型就介紹完了,如果大家想要了解完整的代碼實(shí)現(xiàn),可以參考github喲。

    3、總結(jié)

    1.BPR是基于矩陣分解的一種排序算法,它不是做全局的評分優(yōu)化,而是針對每一個用戶自己的商品喜好分貝做排序優(yōu)化。
    2.它是一種pairwise的排序算法,對于每一個三元組<u,i,j>,模型希望能夠使用戶u對物品i和j的差異更明顯。
    3.同時,引入了貝葉斯先驗(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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。