基于物品的協(xié)同過濾
基本思想
基于物品的協(xié)同過濾(ItemCF):
- 預(yù)先根據(jù)所有用戶的歷史行為數(shù)據(jù),計算物品之間的相似性。
- 然后,把與用戶喜歡的物品相類似的物品推薦給用戶。
舉例來說,如果用戶 1 喜歡物品 A ,而物品 A 和 C 非常相似,則可以將物品 C 推薦給用戶1。ItemCF算法并不利用物品的內(nèi)容屬性計算物品之間的相似度, 主要通過分析用戶的行為記錄計算物品之間的相似度, 該算法認為, 物品 A 和物品 C 具有很大的相似度是因為喜歡物品 A 的用戶極可能喜歡物品 C。
計算過程
基于物品的協(xié)同過濾算法和基于用戶的協(xié)同過濾算法很像, 所以我們這里直接還是拿上面 Alice 的那個例子來看。
如果想知道 Alice 對物品5打多少分, 基于物品的協(xié)同過濾算法會這么做:
- 首先計算一下物品5和物品1, 2, 3, 4之間的相似性。
- 在Alice找出與物品 5 最相近的 n 個物品。
- 根據(jù) Alice 對最相近的 n 個物品的打分去計算對物品 5 的打分情況。
手動計算:
-
手動計算物品之間的相似度
物品向量:
- 皮爾遜相關(guān)系數(shù)類似。
- 下面計算物品 5 和物品 1 之間的余弦相似性:
基于 sklearn 計算物品之間的皮爾遜相關(guān)系數(shù):

- 根據(jù)皮爾遜相關(guān)系數(shù), 可以找到與物品5最相似的2個物品是 item1 和 item4, 下面基于上面的公式計算最終得分:
ItemCF編程實現(xiàn)
-
構(gòu)建物品-用戶的評分矩陣
import numpy as np
import pandas as pd
def loadData():
items = {'A': {'Alice': 5.0, 'user1': 3.0, 'user2': 4.0, 'user3': 3.0, 'user4': 1.0},
'B': {'Alice': 3.0, 'user1': 1.0, 'user2': 3.0, 'user3': 3.0, 'user4': 5.0},
'C': {'Alice': 4.0, 'user1': 2.0, 'user2': 4.0, 'user3': 1.0, 'user4': 5.0},
'D': {'Alice': 4.0, 'user1': 3.0, 'user2': 3.0, 'user3': 5.0, 'user4': 2.0},
'E': {'user1': 3.0, 'user2': 5.0, 'user3': 4.0, 'user4': 1.0}
}
return items -
計算物品間的相似度矩陣
item_data = loadData()
similarity_matrix = pd.DataFrame(
np.identity(len(item_data)),
index=item_data.keys(),
columns=item_data.keys(),
)
# 遍歷每條物品-用戶評分數(shù)據(jù)
for i1, users1 in item_data.items():
for i2, users2 in item_data.items():
if i1 == i2:
continue
vec1, vec2 = [], []
for user, rating1 in users1.items():
rating2 = users2.get(user, -1)
if rating2 == -1:
continue
vec1.append(rating1)
vec2.append(rating2)
similarity_matrix[i1][i2] = np.corrcoef(vec1, vec2)[0][1]
print(similarity_matrix)A B C D E
A 1.000000 -0.476731 -0.123091 0.532181 0.969458
B -0.476731 1.000000 0.645497 -0.310087 -0.478091
C -0.123091 0.645497 1.000000 -0.720577 -0.427618
D 0.532181 -0.310087 -0.720577 1.000000 0.581675
E 0.969458 -0.478091 -0.427618 0.581675 1.000000 -
從 Alice 購買過的物品中,選出與物品
E最相似的num件物品。target_user = ' Alice '
target_item = 'E'
num = 2
sim_items = []
sim_items_list = similarity_matrix[target_item].sort_values(ascending=False).index.tolist()
for item in sim_items_list:
# 如果target_user對物品item評分過
if target_user in item_data[item]:
sim_items.append(item)
if len(sim_items) == num:
break
print(f'與物品{target_item}最相似的{num}個物品為:{sim_items}')與物品E最相似的2個物品為:['A', 'D'] -
預(yù)測用戶 Alice 對物品
E的評分target_user_mean_rating = np.mean(list(item_data[target_item].values()))
weighted_scores = 0.
corr_values_sum = 0.
target_item = 'E'
for item in sim_items:
corr_value = similarity_matrix[target_item][item]
user_mean_rating = np.mean(list(item_data[item].values()))
weighted_scores += corr_value * (item_data[item][target_user] - user_mean_rating)
corr_values_sum += corr_value
target_item_pred = target_user_mean_rating + weighted_scores / corr_values_sum
print(f'用戶{target_user}對物品{target_item}的預(yù)測評分為:{target_item_pred}')用戶 Alice 對物品E的預(yù)測評分為:4.6
-
base 公式
- 該公式表示同時喜好物品 和物品 的用戶數(shù),占喜愛物品 的比例。
- 缺點:若物品 為熱門物品,那么它與任何物品的相似度都很高。
-
對熱門物品進行懲罰
- 根據(jù) base 公式在的問題,對物品 進行打壓。打壓的出發(fā)點很簡單,就是在分母再除以一個物品 被購買的數(shù)量。
- 此時,若物品 為熱門物品,那么對應(yīng)的 也會很大,受到的懲罰更多。
-
控制對熱門物品的懲罰力度
- 除了第二點提到的辦法,在計算物品之間相似度時可以對熱門物品進行懲罰外。
- 可以在此基礎(chǔ)上,進一步引入?yún)?shù) ,這樣可以通過控制參數(shù) 來決定對熱門物品的懲罰力度。
-
對活躍用戶的懲罰
-
在計算物品之間的相似度時,可以進一步將用戶的活躍度考慮進來。
-
對于異常活躍的用戶,在計算物品之間的相似度時,他的貢獻應(yīng)該小于非活躍用戶。
-
協(xié)同過濾算法存在的問題之一就是泛化能力弱:
- 即協(xié)同過濾無法將兩個物品相似的信息推廣到其他物品的相似性上。
- 導(dǎo)致的問題是熱門物品具有很強的頭部效應(yīng), 容易跟大量物品產(chǎn)生相似, 而尾部物品由于特征向量稀疏, 導(dǎo)致很少被推薦。
比如下面這個例子:

- 左邊矩陣中, 表示的是物品。
- 可以看出, 是一件熱門物品,其與 、、 的相似度比較大。因此,推薦系統(tǒng)更可能將 推薦給用過 、、 的用戶。
- 但是,推薦系統(tǒng)無法找出 之間相似性的原因是交互數(shù)據(jù)太稀疏, 缺乏相似性計算的直接數(shù)據(jù)。
所以這就是協(xié)同過濾的天然缺陷:推薦系統(tǒng)頭部效應(yīng)明顯, 處理稀疏向量的能力弱。
為了解決這個問題, 同時增加模型的泛化能力。2006年,矩陣分解技術(shù)(Matrix Factorization, MF)被提出:
- 該方法在協(xié)同過濾共現(xiàn)矩陣的基礎(chǔ)上, 使用更稠密的隱向量表示用戶和物品, 挖掘用戶和物品的隱含興趣和隱含特征。
- 在一定程度上彌補協(xié)同過濾模型處理稀疏矩陣能力不足的問題。
- 什么時候使用UserCF,什么時候使用ItemCF?為什么?
(1)UserCF
- 由于是基于用戶相似度進行推薦, 所以具備更強的社交特性, 這樣的特點非常適于用戶少, 物品多, 時效性較強的場合。
- 比如新聞推薦場景, 因為新聞本身興趣點分散, 相比用戶對不同新聞的興趣偏好, 新聞的及時性,熱點性往往更加重要, 所以正好適用于發(fā)現(xiàn)熱點,跟蹤熱點的趨勢。
- 另外還具有推薦新信息的能力, 更有可能發(fā)現(xiàn)驚喜, 因為看的是人與人的相似性, 推出來的結(jié)果可能更有驚喜,可以發(fā)現(xiàn)用戶潛在但自己尚未察覺的興趣愛好。
(2)ItemCF
- 這個更適用于興趣變化較為穩(wěn)定的應(yīng)用, 更接近于個性化的推薦, 適合物品少,用戶多,用戶興趣固定持久, 物品更新速度不是太快的場合。
- 比如推薦藝術(shù)品, 音樂, 電影。
2.協(xié)同過濾在計算上有什么缺點?有什么比較好的思路可以解決(緩解)?
該問題答案參考上一小節(jié)的協(xié)同過濾算法的問題分析。
3.上面介紹的相似度計算方法有什么優(yōu)劣之處?
cosine相似度計算簡單方便,一般較為常用。但是,當(dāng)用戶的評分數(shù)據(jù)存在 bias 時,效果往往不那么好。
- 簡而言之,就是不同用戶評分的偏向不同。部分用戶可能樂于給予好評,而部分用戶習(xí)慣給予差評或者亂評分。
- 這個時候,根據(jù)cosine 相似度計算出來的推薦結(jié)果效果會打折扣。
舉例來說明,如下圖(
X,Y,Z表示物品,d,e,f表示用戶):
- 如果使用余弦相似度進行計算,用戶 d 和 e 之間較為相似。但是實際上,用戶 d 和 f 之間應(yīng)該更加相似。只不過由于 d 傾向于打高分,e 傾向于打低分導(dǎo)致二者之間的余弦相似度更高。
- 這種情況下,可以考慮使用皮爾遜相關(guān)系數(shù)計算用戶之間的相似性關(guān)系。
4.協(xié)同過濾還存在其他什么缺陷?有什么比較好的思路可以解決(緩解)?
參考資料
- 協(xié)同過濾的優(yōu)點就是沒有使用更多的用戶或者物品屬性信息,僅利用用戶和物品之間的交互信息就能完成推薦,該算法簡單高效。
- 但這也是協(xié)同過濾算法的一個弊端。由于未使用更豐富的用戶和物品特征信息,這也導(dǎo)致協(xié)同過濾算法的模型表達能力有限。
- 對于該問題,邏輯回歸模型(LR)可以更好地在推薦模型中引入更多特征信息,提高模型的表達能力。
- 基于用戶的協(xié)同過濾來構(gòu)建推薦系統(tǒng):https://mp.weixin.qq.com/s/ZtnaQrVIpVOPJpqMdLWOcw
- https://datawhalechina.github.io/fun-rec/

