1. 程式人生 > >基於內容的推薦演算法CB

基於內容的推薦演算法CB


Collaborative Filtering Recommendations (協同過濾,簡稱CF) 是目前最流行的推薦方法,在研究界和工業界得到大量使用。但是,工業界真正使用的系統一般都不會只有CF推薦演算法,Content-based Recommendations (CB) 基本也會是其中的一部分。

      CB應該算是最早被使用的推薦方法吧,它根據使用者過去喜歡的產品(本文統稱為 item),為使用者推薦和他過去喜歡的產品相似的產品。例如,一個推薦飯店的系統可以依據某個使用者之前喜歡很多的烤肉店而為他推薦烤肉店。 CB最早主要是應用在資訊檢索系統當中,所以很多資訊檢索及資訊過濾裡的方法都能用於CB中。

      CB的過程一般包括以下三步:

1. Item Representation:為每個item抽取出一些特徵(也就是item的content了)來表示此item;

2. Profile Learning:利用一個使用者過去喜歡(及不喜歡)的item的特徵資料,來學習出此使用者的喜好特徵(profile);

3. Recommendation Generation:通過比較上一步得到的使用者profile與候選item的特徵,為此使用者推薦一組相關性最大的item。

[3]中對於上面的三個步驟給出一張很細緻的流程圖(第一步對應著Content Analyzer,第二步對應著Profile Learner,第三步對應著Filtering Component):

Image

       舉個例子說明前面的三個步驟。對於個性化閱讀來說,一個item就是一篇文章。根據上面的第一步,我們首先要從文章內容中抽取出代表它們的屬性。常用的方法就是利用出現在一篇文章中詞來代表這篇文章,而每個詞對應的權重往往使用資訊檢索中的tf-idf來計算。比如對於本文來說,詞“CB”、“推薦”和“喜好”的權重會比較大,而“烤肉”這個詞的權重會比較低。利用這種方法,一篇抽象的文章就可以使用具體的一個向量來表示了。第二步就是根據使用者過去喜歡什麼文章來產生刻畫此使用者喜好的 profile了,最簡單的方法可以把使用者所有喜歡的文章對應的向量的平均值作為此使用者的profile。比如某個使用者經常關注與推薦系統有關的文章,那麼他的profile中“CB”、“CF”和“推薦”對應的權重值就會較高。在獲得了一個使用者的profile後,CB就可以利用所有item與此使用者profile的相關度對他進行推薦文章了。一個常用的相關度計算方法是cosine。最終把候選item裡與此使用者最相關(cosine值最大)的N個item作為推薦返回給此使用者。

       接下來我們詳細介紹下上面的三個步驟。

一. Item Representation

      真實應用中的item往往都會有一些可以描述它的屬性。這些屬性通常可以分為兩種:結構化的(structured)屬性與非結構化的(unstructured)屬性。所謂結構化的屬性就是這個屬性的意義比較明確,其取值限定在某個範圍;而非結構化的屬性往往其意義不太明確,取值也沒什麼限制,不好直接使用。比如在交友網站上,item就是人,一個item會有結構化屬性如身高、學歷、籍貫等,也會有非結構化屬性(如item自己寫的交友宣言,部落格內容等等)。對於結構化資料,我們自然可以拿來就用;但對於非結構化資料(如文章),我們往往要先把它轉化為結構化資料後才能在模型里加以使用。真實場景中碰到最多的非結構化資料可能就是文章了(如個性化閱讀中)。下面我們就詳細介紹下如何把非結構化的一篇文章結構化。

       如何代表一篇文章在資訊檢索中已經被研究了很多年了,下面介紹的表示技術其來源也是資訊檢索,其名稱為向量空間模型(Vector Space Model,簡稱VSM)。

      記我們要表示的所有文章集合為 Image(1),而所有文章中出現的詞(對於中文文章,首先得對所有文章進行分詞)的集合(也稱為詞典)為Image(2)。也就是說,我們有N篇要處理的文章,而這些文章裡包含了n個不同的詞。我們最終要使用一個向量來表示一篇文章,比如第j篇文章被表示為Image(3),其中Image(4)表示第1個詞Image(5)在文章j中的權重,值越大表示越重要;Image(6)中其他向量的解釋類似。所以,為了表示第j篇文章,現在關鍵的就是如何計算Image6各分量的值了。例如,我們可以選取Image4為1,如果詞Image5出現在第 j 篇文章中;選取為0,如果Image5未出現在第j篇文章中。我們也可以選取Image4為詞Image5出現在第 j 篇文章中的次數(frequency)。但是用的最多的計算方法還是資訊檢索中常用的詞頻-逆文件頻率(term frequency–inverse document frequency,簡稱tf-idf)。第j篇文章中與詞典裡第k個詞對應的tf-idf為:

Image(7)

其中Image(8)是第k個詞在文章j中出現的次數,而Image(9)是所有文章中包括第k個詞的文章數量。

      最終第k個詞在文章j中的權重由下面的公式獲得:

Image(10)

做歸一化的好處是不同文章之間的表示向量被歸一到一個量級上,便於下面步驟的操作。     

二. Profile Learning

       假設使用者u已經對一些item給出了他的喜好判斷,喜歡其中的一部分item,不喜歡其中的另一部分。那麼,這一步要做的就是通過使用者u過去的這些喜好判斷,為他產生一個模型。有了這個模型,我們就可以根據此模型來判斷使用者u是否會喜歡一個新的item。所以,我們要解決的是一個典型的有監督分類問題,理論上機器學習裡的分類演算法都可以照搬進這裡。

      下面我們簡單介紹下CB裡常用的一些學習演算法:

1. 最近鄰方法(k-Nearest Neighbor,簡稱kNN)

      對於一個新的item,最近鄰方法首先找使用者u已經評判過並與此新item最相似的k個item,然後依據使用者u對這k個item的喜好程度來判斷其對此新item的喜好程度。這種做法和CF中的item-based kNN很相似,差別在於這裡的item相似度是根據item的屬性向量計算得到,而CF中是根據所有使用者對item的評分計算得到。

      對於這個方法,比較關鍵的可能就是如何通過item的屬性向量計算item之間的兩兩相似度。[2]中建議對於結構化資料,相似度計算使用歐幾里得距離;而如果使用向量空間模型(VSM)來表示item的話,則相似度計算可以使用cosine。

2. Rocchio演算法

      Rocchio演算法是資訊檢索中處理相關反饋(Relevance Feedback)的一個著名演算法。比如你在搜尋引擎裡搜“蘋果”,當你最開始搜這個詞時,搜尋引擎不知道你到底是要能吃的水果,還是要不能吃的蘋果,所以它往往會盡量呈現給你各種結果。當你看到這些結果後,你會點一些你覺得相關的結果(這就是所謂的相關反饋了)。然後如果你翻頁檢視第二頁的結果時,搜尋引擎可以通過你剛才給的相關反饋,修改你的查詢向量取值,重新計算網頁得分,把跟你剛才點選的結果相似的結果排前面。比如你最開始搜尋“蘋果”時,對應的查詢向量是{“蘋果” : 1}。而當你點選了一些與Mac、iPhone相關的結果後,搜尋引擎會把你的查詢向量修改為{“蘋果” : 1, “Mac” : 0.8, “iPhone” : 0.7},通過這個新的查詢向量,搜尋引擎就能比較明確地知道你要找的是不能吃的蘋果了。Rocchio演算法的作用就是用來修改你的查詢向量的:{“蘋果” : 1}  --> {“蘋果” : 1, “Mac” : 0.8, “iPhone” : 0.7}。

      在CB裡,我們可以類似地使用Rocchio演算法來獲得使用者u的profileImage(11)

Image(12)

其中Image(13)表示item j的屬性,Image(14)Image(15)分別表示已知的使用者u喜歡與不喜歡的item集合;而Image(16)Image(17)為正負反饋的權重,它們的值由系統給定。

      在獲得Image11後,對於某個給定的item j,我們可以使用Image(11)[1]Image(13)的相似度來代表使用者u對j的喜好度。

      Rocchio演算法的一個好處是Image(11)[1]可以根據使用者的反饋實時更新,其更新代價很小。

      正如在本節開頭所說,本節要解決的是一個典型的有監督分類問題。所以各種有效的分類機器學習演算法都可以用到這裡,下面列舉幾個常用的分類演算法:

3. 決策樹演算法(Decision Tree,簡稱DT)

      當item的屬性較少而且是結構化屬性時,決策樹一般會是個好的選擇。這種情況下決策樹可以產生簡單直觀、容易讓人理解的結果。而且我們可以把決策樹的決策過程展示給使用者u,告訴他為什麼這些item會被推薦。但是如果item的屬性較多,且都來源於非結構化資料(如item是文章),那麼決策樹的效果可能並不會很好。

4. 線性分類演算法(Linear Classifer,簡稱LC)

      對於我們這裡的二類問題,線性分類器(LC)嘗試在高維空間找一個平面,使得這個平面儘量分開兩類點。也就是說,一類點儘可能在平面的某一邊,而另一類點儘可能在平面的另一邊。

      仍以學習使用者u的分類模型為例。Image(13)[5]表示item j的屬性向量,那麼LC嘗試在Image(13)[5]空間中找平面Image(18),使得此平面儘量分開使用者u喜歡與不喜歡的item。其中的Image(19)就是我們要學習的引數了。最常用的學習Image19的方法就是梯度下降法了,其更新過程如下:

Image(20)

其中的上角標t表示第t次迭代,Image(21)表示使用者u對item j的打分(例如喜歡則值為1,不喜歡則值為-1)。Image(22)為學習率,它控制每步迭代變化多大,由系統給定。

     和Rocchio演算法一樣,上面更新公式的好處就是它可以以很小的代價進行實時更新,實時調整使用者u對應的Image19

     說到這裡,很多童鞋可能會想起一些著名的線性分類器:Logistic Regression和Linear SVM等等,它們當然能勝任我們這裡的分類任務。[2]中提到Linear SVM用在文字分類上能獲得相當不錯的效果:)。

     如果item屬性Image(13)[5]的每個分量都是0/1取值的話(如item為文章,Image(13)[5]的第k個分量為1表示詞典中第k個詞在item j中,為0表示第k個詞不在item j中),那麼還有一種很有意思的啟發式更新Image19的演算法:Winnow演算法。[4]中就是使用Winnow演算法來獲得user profile的。

5. 樸素貝葉斯演算法(Naive Bayes,簡稱NB)

      NB演算法就像它的簡稱一樣,牛逼!NB經常被用來做文字分類,它假設在給定一篇文章的類別後,其中各個詞出現的概率相互獨立。它的假設雖然很不靠譜,但是它的結果往往驚人地好。再加上NB的程式碼實現比較簡單,所以它往往是很多分類問題裡最先被嘗試的演算法。我們現在的profile learning問題中包括兩個類別:使用者u喜歡的item,以及他不喜歡的item。在給定一個item的類別後,其各個屬性的取值概率互相獨立。我們可以利用使用者u的歷史喜好資料訓練NB,之後再用訓練好的NB對給定的item做分類。NB的介紹很多,這裡就不再囉嗦了,有不清楚的童鞋可以參考NB Wiki,或者[1-3]。

三. Recommendation Generation

      如果上一步Profile Learning中使用的是分類模型(如DT、LC和NB),那麼我們只要把模型預測的使用者最可能感興趣的n個item作為推薦返回給使用者即可。而如果Profile Learning中使用的直接學習使用者屬性的方法(如Rocchio演算法),那麼我們只要把與使用者屬性最相關的n個item作為推薦返回給使用者即可。其中的使用者屬性與item屬性的相關性可以使用如cosine等相似度度量獲得。

     下面說說CB的優缺點。

CB的優點

1. 使用者之間的獨立性(User Independence):既然每個使用者的profile都是依據他本身對item的喜好獲得的,自然就與他人的行為無關。而CF剛好相反,CF需要利用很多其他人的資料。CB的這種使用者獨立性帶來的一個顯著好處是別人不管對item如何作弊(比如利用多個賬號把某個產品的排名刷上去)都不會影響到自己。

2. 好的可解釋性(Transparency):如果需要向用戶解釋為什麼推薦了這些產品給他,你只要告訴他這些產品有某某屬性,這些屬性跟你的品味很匹配等等。

3. 新的item可以立刻得到推薦(New Item Problem):只要一個新item加進item庫,它就馬上可以被推薦,被推薦的機會和老的item是一致的。而CF對於新item就很無奈,只有當此新item被某些使用者喜歡過(或打過分),它才可能被推薦給其他使用者。所以,如果一個純CF的推薦系統,新加進來的item就永遠不會被推薦:( 。

CB的缺點

1. item的特徵抽取一般很難(Limited Content Analysis):如果系統中的item是文件(如個性化閱讀中),那麼我們現在可以比較容易地使用資訊檢索裡的方法來“比較精確地”抽取出item的特徵。但很多情況下我們很難從item中抽取出準確刻畫item的特徵,比如電影推薦中item是電影,社會化網路推薦中item是人,這些item屬性都不好抽。其實,幾乎在所有實際情況中我們抽取的item特徵都僅能代表item的一些方面,不可能代表item的所有方面。這樣帶來的一個問題就是可能從兩個item抽取出來的特徵完全相同,這種情況下CB就完全無法區分這兩個item了。比如如果只能從電影裡抽取出演員、導演,那麼兩部有相同演員和導演的電影對於CB來說就完全不可區分了。

2. 無法挖掘出使用者的潛在興趣(Over-specialization):既然CB的推薦只依賴於使用者過去對某些item的喜好,它產生的推薦也都會和使用者過去喜歡的item相似。如果一個人以前只看與推薦有關的文章,那CB只會給他推薦更多與推薦相關的文章,它不會知道使用者可能還喜歡數碼。

3. 無法為新使用者產生推薦(New User Problem):新使用者沒有喜好歷史,自然無法獲得他的profile,所以也就無法為他產生推薦了。當然,這個問題CF也有。

       CB應該算是第一代的個性化應用中最流行的推薦演算法了。但由於它本身具有某些很難解決的缺點(如上面介紹的第1點),再加上在大多數情況下其精度都不是最好的,目前大部分的推薦系統都是以其他演算法為主(如CF),而輔以CB以解決主演算法在某些情況下的不精確性(如解決新item問題)。但CB的作用是不可否認的,只要具體應用中有可用的屬性,那麼基本都能在系統裡看到CB的影子。組合CB和其他推薦演算法的方法很多(我很久以後會寫一篇博文詳細介紹之),最常用的可能是用CB來過濾其他演算法的候選集,把一些不太合適的候選(比如不要給小孩推薦偏成人的書籍)去掉。

[References]

[1] Gediminas Adomavicius and Alexander Tuzhilin, Towards the Next Generation of Recommender Systems: A Survey of the State-of-the-Art and Possible Extensions

[2] Michael J. Pazzani and Daniel Billsus, Content-Based Recommendation Systems, 2007

[3] Pasquale Lops, Marco de Gemmis and Giovanni Semeraro, Chapter 3 in Recommender Systems Handbook, 2011

[4] Michael J. Pazzani, A Framework for Collaborative, Content-Based and Demographic Filtering, 1999