1. 程式人生 > >推薦系統之基於內容推薦CB

推薦系統之基於內容推薦CB

(個性化)推薦系統構建三大方法:基於內容的推薦content-based,協同過濾collaborative filtering,隱語義模型(LFM, latent factor model)推薦。這篇部落格主要講基於內容的推薦content-based。

基於內容的推薦1 Content-based System

{MMDs中基於user-item profile空間的cosin相似度的思路}

主要思想

 

上圖同時使用了explict和impliict資訊建立Item profiles,推薦時很可能是推薦紅色的六邊形。

Item模型 Item Profile

將item表示成一個features向量,如電影的features向量可以是<author, title, actor, director, ...>對應的boolean或者real-valued的數值向量。

這裡不同的features數值一般需要scale一下,不然數值偏大的features會dominate整個item模型的表示。其中一個比較公平的選擇縮放因子的方法是:使其每個縮放因子與其對應分量的平均值成反比。另一種對向量分量進行放縮變換的方式是首先對向量進行歸一化,也就是說計算每個分量的平均值然後對向量中的每一個分量減去對應的平均值。

文章推薦中的item描述示例:Text Features

Profile = set of “important” words in item (document)

使用TF-IDF進行文字特徵抽取,所以文字的profile是一個real vector,並且要設定一個threshold來過濾。[:TF-IDF(Term frequency * Inverse Doc Frequency)詞權重]

User模型 User Profile

通過使用者評分過(或者有過互動如觀看)的item的profiles構建使用者的profiles。
構建使用者模型的幾種方式:

simple方式建立一個使用者profile的一個圖示(不過這裡還沒加上weight):其中每個向量是一個item(如電影)的向量表示(向量分量可以是actor,這樣的話分類屬性就要用獨熱編碼表示,或者直接每個actor都表示成一個feature)

使用者profile建立示例

注意使用者的profile向量和item向量是同樣的表示,就是說item vec中的元素是profile(e.g actor),user vec中的元素也是profile(e.g actor)。使用者的profile是基於評分過的item profile建立的(沒有評分的就不用)。
效用矩陣(utility matrix)
就是user-item矩陣,如評分或者是否觀看的boolean矩陣[多個使用者是矩陣,一個使用者的時候當然就是向量了,下面的例子都是以一個使用者來說明的],使用者和item之間通過效用矩陣連線:(當然為了方便也可以不顯示使用效用矩陣,直接計算使用者評分過的電影資料)

示例1:Boolen Utility Matrix(simple方式,無評分,但有觀看)



這個實際就是上面的simple方式,所有看過的電影item向量加起來/N。電影的profile就是[(1,0), (1, 0), ....],這樣使用者的profile就是(0.4, 0.6)。
示例2:Star Ratings(variant方式,有評分)


If the utility matrix is not boolean, e.g., ratings 1–5, then we can weight the vectors representing the profiles of items by the utility value.

原始

user rating normalized

實際上是分兩步的:
先將效用矩陣效用值歸一化,作為項表示向量的權重
   =》 
再將項表示向量加權平均:
   =》    =》
由於每個user的慷慨程度不同,打分的出手值不同,需要規格化。通過規格化發現評分1 和2實際上是negative ratings。
規格化就相當於將item vec的每個屬性進行了一個規格化,這種規格化是通過這個屬性的所有item進行的。
注意profile的均值計算是使用者對所有電影評分總分的均值,而profile A的計算是(0+2)/profile A在電影中出現的次數,而不是使用者評分的所有電影總數。
這種方式有效的一個直覺知識是:每個Item中的profile評分都減去了總體均值,去除了不同使用者的慷慨程度影響,而除以profile在電影中出現的次數相當於再計算一次個體均值,更好擬合對某個profile的偏好程式。

推薦Making Predictions

使用餘弦相似度來度量user profile和item profile的相似度,因為它適合高維度向量的相似度計算,且cosin值越大越相似(此時角度就越小)。[]

這樣,我們就計算使用者x的catlog中所有item i進行相似度計算,推薦給使用者相似度高的items。
皮皮blog

評價:基於內容推薦的優缺點pros and cons

優點


1 新來item一來就可以作推薦,它的推薦是基於其本身特徵,而不是其它使用者對其的評分。沒有協同過濾的first-rater問題。
2 意味著you can start working making content-based recommendations from day one for your very first user.
3 協同過濾對於口味獨特的使用者可能找不到相似使用者,而基於內容的推薦仍然可以推薦。when we get to collaborative filtering,We need to find similar users.But if the user were very unique or idiosyncratic taste there may not be any other similar users.But the content-based approach, user can very unique tastes as long as we can build item profiles for the items that the user likes.

缺點


如果使用者從未評分過某種型別的item,那麼那種item也永遠不會被推薦給使用者,即使那個item在當前是相當受歡迎的。
冷啟動問題:新使用者沒有profile。
[海量資料探勘Mining Massive Datasets(MMDs) week4-Jure Leskovec courses 推薦系統Recommendation System]
皮皮blog

基於內容的推薦2 Content Based Recommendations

{Andrew NG機器學習course中基於user-item profile線性規劃的思路}

基於線性規劃的主要思想

我們將每個使用者的評分預測看成一個分開獨立的線性迴歸問題 separate linear regression problem,也就是說對每個使用者j我們都要去學習它的引數向量θ^j(維度R=n+1,其中n為features的數目),這樣我們就通過內積θj'Xi來預測user j對item i的評分。

content based recommendations:我們假設我們已經有不同items的features了,that capture what is the content of these movies, how romantic/action is this movie?這樣的話我們就是在用items的內容features來作預測。

我們對每個item的feature向量都新增一個額外的截斷interceptor feature x0=1,n=2為feature的數目(不包括x0)。

假設我們通過線性規劃求出了Alice的引數θ(對於Alice評過的每部電影就是一個example,其中example0中x = [0.9 0], y = 5,用梯度下降求出theta),這樣預測Alice對第3部電影的評分為4.95(如圖)。

最優化演算法:引數向量θj的估計

Note: 常數項1/mj刪除了;且同線性規劃一樣不regularize θ0。

Suppose there is only one user and he has rated every movie in the training set. This implies that nu=1 and r(i,j)=1 for every i,j. In this case, the cost function J(θ) is equivalent to the one used for regularized linear regression.

[機器學習Machine Learning - Andrew NG courses]

Reviews複習

規格化問題

計算出規格化後的矩陣為:

[[-1.333 -1.     0.     0.333  2.   ]
 [-0.333  0.    -1.     1.333  0.   ]
 [ 1.667  1.     1.    -1.667 -2.   ]]

Content-based的cosin距離計算問題

Note: 距離越小越相似。

計算得到的距離矩陣分別為:

scale_alpha = 0          scale_alpha = 0.5           scale_alpha = 1                scale_alpha = 2
    A        B        C            A        B        C                   A        B        C                A        B        C
[[ 0.     0.333  1.   ]        [[ 0.     0.278  0.711]     [[ 0.     0.153  0.383]      [[ 0.     0.054  0.135]
 [ 0.333  0.     0.592]     [ 0.278  0.     0.333]      [ 0.153  0.     0.15 ]        [ 0.054  0.     0.047]

 [ 1.     0.592  0.   ]]        [ 0.711  0.333  0.   ]]     [ 0.383  0.15   0.   ]]       [ 0.135  0.047  0.   ]]

程式碼:

import numpy as np
from scipy import spatial

from Utility.PrintOptions import printoptions


def Nomalize(A):
'''
    user-item規格化:對每個元素先減行和,再減列和
    '''
row_mean = np.mean(A, 1).reshape([len(A), 1])  # 進行廣播運算A -= row_meancol_mean = np.mean(A, 0)A -= col_mean
    with printoptions(precision=3):
print(A)
    return A
def CosineDist(A, scale_alpha):
'''
    計算行向量間的cosin相似度
    '''
A[:, -1] *= scale_alphacos_dist = spatial.distance.squareform(spatial.distance.pdist(A, metric='cosine'))
    with printoptions(precision=3):
print('scale_alpha = %s' % scale_alpha)
        print('\tA\t\tB\t\tC')
        print(cos_dist)
        print()


if __name__ == '__main__':
task = 2
if task == 1:
A = np.array([[1, 2, 3, 4, 5], [2, 3, 2, 5, 3], [5, 5, 5, 3, 2]], dtype=float)Nomalize(A)
    else:
for scale_alpha in [0, 0.5, 1, 2]:
A = np.array([[1, 0, 1, 0, 1, 2], [1, 1, 0, 0, 1, 6], [0, 1, 0, 1, 0, 2]], dtype=float)
            CosineDist(A, scale_alpha=scale_alpha)