貝葉斯個性化排序(BPR)演算法小結

劉建平Pinard發表於2018-06-03

    在矩陣分解在協同過濾推薦演算法中的應用中,我們討論過像funkSVD之類的矩陣分解方法如何用於推薦。今天我們講另一種在實際產品中用的比較多的推薦演算法:貝葉斯個性化排序(Bayesian Personalized Ranking, 以下簡稱BPR),它也用到了矩陣分解,但是和funkSVD家族卻有很多不同之處。下面我們來詳細討論。

1.  BPR演算法使用背景

    在很多推薦場景中,我們都是基於現有的使用者和商品之間的一些資料,得到使用者對所有商品的評分,選擇高分的商品推薦給使用者,這是funkSVD之類演算法的做法,使用起來也很有效。但是在有些推薦場景中,我們是為了在千萬級別的商品中推薦個位數的商品給使用者,此時,我們更關心的是使用者來說,哪些極少數商品在使用者心中有更高的優先順序,也就是排序更靠前。也就是說,我們需要一個排序演算法,這個演算法可以把每個使用者對應的所有商品按喜好排序。BPR就是這樣的一個我們需要的排序演算法。

2.  排序推薦演算法背景介紹

     排序推薦演算法歷史很悠久,早在做資訊檢索的各種產品中就已經在使用了。最早的第一類排序演算法類別是點對方法(Pointwise Approach),這類演算法將排序問題被轉化為分類、迴歸之類的問題,並使用現有分類、迴歸等方法進行實現。第二類排序演算法是成對方法(Pairwise Approach),在序列方法中,排序被轉化為對序列分類或對序列迴歸。所謂的pair就是成對的排序,比如(a,b)一組表明a比b排的靠前。我們要講到的BPR就屬於這一類。第三類排序演算法是列表方法(Listwise Approach),它採用更加直接的方法對排序問題進行了處理。它在學習和預測過程中都將排序列表作為一個樣本。排序的組結構被保持。

    本文關注BPR,這裡我們對排序推薦演算法本身不多講,如果大家感興趣,可以閱讀李航的A Short Introduction to Learning to Rank.

3. BPR建模思路

    在BPR演算法中,我們將任意使用者u對應的物品進行標記,如果使用者u在同時有物品i和j的時候點選了i,那麼我們就得到了一個三元組$<u,i,j>$,它表示對使用者u來說,i的排序要比j靠前。如果對於使用者u來說我們有m組這樣的反饋,那麼我們就可以得到m組使用者u對應的訓練樣本。

    既然是基於貝葉斯,那麼我們也就有假設,這裡的假設有兩個:一是每個使用者之間的偏好行為相互獨立,即使用者u在商品i和j之間的偏好和其他使用者無關。二是同一使用者對不同物品的偏序相互獨立,也就是使用者u在商品i和j之間的偏好和其他的商品無關。為了便於表述,我們用$>_u$符號表示使用者u的偏好,上面的$<u,i,j>$可以表示為:$i>_uj$。

    在BPR中,這個排序關係符號$>_u$滿足完全性,反對稱性和傳遞性,即對於使用者集U和物品集I:

    完整性:$\forall i,j \in I: i \neq j \Rightarrow i >_u j\; \cup\;  j>_u i$

    反對稱性:$\forall i,j \in I: i >_u j\; \cap\;  j>_u i \Rightarrow i=j$

    傳遞性:$\forall i,j,k \in I: i >_u j\; \cap\;  j>_u k \Rightarrow i>_uk$

    同時,BPR也用了和funkSVD類似的矩陣分解模型,這裡BPR對於使用者集U和物品集I的對應的$U \times I$的預測排序矩陣$\overline{X}$,我們期望得到兩個分解後的使用者矩陣$W$($|U| \times k$)和物品矩陣$H$($|I| \times k$),滿足$$\overline{X} = WH^T$$

    這裡的k和funkSVD類似,也是自己定義的,一般遠遠小於$|U|,|I|$。

    由於BPR是基於使用者維度的,所以對於任意一個使用者u,對應的任意一個物品i我們期望有:$$\overline{x}_{ui} = w_u \bullet h_i = \sum\limits_{f=1}^kw_{uf}h_{if}$$

    最終我們的目標,是希望尋找合適的矩陣$W,H$,讓$\overline{X}$和$X$最相似。讀到這裡,也許你會說,這和funkSVD之類的矩陣分解模型沒有什麼區別啊? 的確,現在還看不出,下面我們來看看BPR的演算法優化思路,就會慢慢理解和funkSVD有什麼不同了。

4. BPR的演算法優化思路

    BPR 基於最大後驗估計$P(W,H|>_u)$來求解模型引數$W,H$,這裡我們用$\theta$來表示引數$W$和$H$, $>_u$代表使用者u對應的所有商品的全序關係,則優化目標是$P(\theta|>_u)$。根據貝葉斯公式,我們有:$$P(\theta|>_u) = \frac{P(>_u|\theta)P(\theta)}{P(>_u)}$$

    由於我們求解假設了使用者的排序和其他使用者無關,那麼對於任意一個使用者u來說,$P(>_u)$對所有的物品一樣,所以有:$$P(\theta|>_u) \propto P(>_u|\theta)P(\theta)$$

    這個優化目標轉化為兩部分。第一部分和樣本資料集D有關,第二部分和樣本資料集D無關。

    對於第一部分,由於我們假設每個使用者之間的偏好行為相互獨立,同一使用者對不同物品的偏序相互獨立,所以有:$$\prod_{u \in U}P(>_u|\theta) = \prod_{(u,i,j) \in (U \times I \times I)}P(i >_u j|\theta)^{\delta((u,i,j) \in D)}(1-P(i >_u j|\theta))^{\delta((u,j,i) \not\in D) }$$

    其中,$$\delta(b)= \begin{cases} 1& {if\; b\; is \;true}\\ 0& {else} \end{cases}$$   

    根據上面講到的完整性和反對稱性,優化目標的第一部分可以簡化為:$$\prod_{u \in U}P(>_u|\theta) = \prod_{(u,i,j) \in D}P(i >_u j|\theta)$$

    而對於$P(i >_u j|\theta)$這個概率,我們可以使用下面這個式子來代替:$$P(i >_u j|\theta) = \sigma(\overline{x}_{uij}(\theta))$$

    其中,$\sigma(x)$是sigmoid函式。這裡你也許會問,為什麼可以用這個sigmoid函式來代替呢? 其實這裡的代替可以選擇其他的函式,不過式子需要滿足BPR的完整性,反對稱性和傳遞性。原論文作者這麼做除了是滿足這三個性質外,另一個原因是為了方便優化計算。

    對於$\overline{x}_{uij}(\theta)$這個式子,我們要滿足當$i >_u j$時,$\overline{x}_{uij}(\theta) > 0$, 反之當$j >_u i$時,$\overline{x}_{uij}(\theta) < 0$,最簡單的表示這個性質的方法就是$$\overline{x}_{uij}(\theta) = \overline{x}_{ui}(\theta) - \overline{x}_{uj}(\theta)$$

    而$\overline{x}_{ui}(\theta) , \overline{x}_{uj}(\theta)$,就是我們的矩陣$ \overline{X}$對應位置的值。這裡為了方便,我們不寫$\theta$,這樣上式可以表示為:$$\overline{x}_{uij} = \overline{x}_{ui} - \overline{x}_{uj}$$

    注意上面的這個式子也不是唯一的,只要可以滿足上面提到的當$i >_u j$時,$\overline{x}_{uij}(\theta) > 0$,以及對應的相反條件即可。這裡我們仍然按原論文的式子來。

    最終,我們的第一部分優化目標轉化為:$$\prod_{u \in U}P(>_u|\theta) = \prod_{(u,i,j) \in D} \sigma(\overline{x}_{ui} - \overline{x}_{uj})$$    

    對於第二部分$P(\theta)$,原作者大膽使用了貝葉斯假設,即這個概率分佈符合正太分佈,且對應的均值是0,協方差矩陣是$\lambda_{\theta}I$,即$$P(\theta) \sim N(0, \lambda_{\theta}I)$$

    原作者為什麼這麼假設呢?個人覺得還是為了優化方便,因為後面我們做優化時,需要計算$lnP(\theta) $,而對於上面假設的這個多維正態分佈,其對數和$||\theta||^2$成正比。即:$$lnP(\theta) = \lambda||\theta||^2$$

    最終對於我們的最大對數後驗估計函式$ln\;P(\theta|>_u) \propto ln\;P(>_u|\theta)P(\theta) = ln\;\prod\limits_{(u,i,j) \in D} \sigma(\overline{x}_{ui} - \overline{x}_{uj}) + ln P(\theta) = \sum\limits_{(u,i,j) \in D}ln\sigma(\overline{x}_{ui} - \overline{x}_{uj}) + \lambda||\theta||^2\;$   

    這個式子可以用梯度上升法或者牛頓法等方法來優化求解模型引數。如果用梯度上升法,對$\theta$求導,我們有: $$\frac{\partial ln\;P(\theta|>_u)}{\partial \theta} \propto \sum\limits_{(u,i,j) \in D} \frac{1}{1+e^{\overline{x}_{ui} - \overline{x}_{uj}}}\frac{\partial (\overline{x}_{ui} - \overline{x}_{uj})}{\partial \theta} + \lambda \theta$$

    由於$$\overline{x}_{ui} - \overline{x}_{uj} = \sum\limits_{f=1}^kw_{uf}h_{if} - \sum\limits_{f=1}^kw_{uf}h_{jf}$$

    這樣我們可以求出:$$\frac{\partial (\overline{x}_{ui} - \overline{x}_{uj})}{\partial \theta} = \begin{cases} (h_{if}-h_{jf})& {if\; \theta = w_{uf}}\\ w_{uf}& {if\;\theta = h_{if}} \\ -w_{uf}& {if\;\theta = h_{jf}}\end{cases}$$ 

    有了梯度迭代式子,用梯度上升法求解模型引數就容易了。下面我們歸納下BPR的演算法流程。

5. BPR演算法流程

    下面簡要總結下BPR的演算法訓練流程:  

    輸入:訓練集D三元組,梯度步長$\alpha$, 正則化引數$\lambda$,分解矩陣維度k。          

    輸出:模型引數,矩陣$W,H$

    1. 隨機初始化矩陣$W,H$

    2. 迭代更新模型引數:

$$w_{uf} =w_{uf} + \alpha(\sum\limits_{(u,i,j) \in D} \frac{1}{1+e^{\overline{x}_{ui} - \overline{x}_{uj}}}(h_{if}-h_{jf}) + \lambda w_{uf}) $$

$$h_{if} =h_{if} + \alpha(\sum\limits_{(u,i,j) \in D} \frac{1}{1+e^{\overline{x}_{ui} - \overline{x}_{uj}}}w_{uf} + \lambda h_{if}) $$

$$h_{jf} =h_{jf} + \alpha(\sum\limits_{(u,i,j) \in D} \frac{1}{1+e^{\overline{x}_{ui} - \overline{x}_{uj}}}(-w_{uf}) + \lambda h_{jf}) $$

    3. 如果$W,H$收斂,則演算法結束,輸出W,H,否則回到步驟2.

    當我們拿到$W,H$後,就可以計算出每一個使用者u對應的任意一個商品的排序分:$\overline{x}_{ui} = w_u \bullet h_i $,最終選擇排序分最高的若干商品輸出。

6. BPR小結

    BPR是基於矩陣分解的一種排序演算法,但是和funkSVD之類的演算法比,它不是做全域性的評分優化,而是針對每一個使用者自己的商品喜好分貝做排序優化。因此在迭代優化的思路上完全不同。同時對於訓練集的要求也是不一樣的,funkSVD只需要使用者物品對應評分資料二元組做訓練集,而BPR則需要使用者對商品的喜好排序三元組做訓練集。

    在實際產品中,BPR之類的推薦排序在海量資料中選擇極少量資料做推薦的時候有優勢,因此在某寶某東等大廠中應用也很廣泛。由於BPR並不複雜,下一篇我會用tensorflow來做一個BPR的實踐,敬請期待。


(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com)        

    

相關文章