協同過濾#
協同過濾 (Collaborative Filtering) 是推薦系統最經典的方法,核心思想是利用群體智慧:相似的用戶喜歡相似的物品。
基本概念#
用戶-物品矩陣#
物品1 物品2 物品3 物品4
用戶A 5 3 ? 1
用戶B 4 ? ? 1
用戶C 1 1 ? 5
用戶D ? 1 5 4協同過濾的核心任務是填充矩陣中的空白,預測用戶對未評分物品的評分。
兩種主要方法#
| 方法 | 核心思想 | 計算物件 |
|---|---|---|
| User-Based CF | 相似的用戶喜歡相似的物品 | 用戶相似度 |
| Item-Based CF | 用戶喜歡與歷史物品相似的物品 | 物品相似度 |
User-Based 協同過濾#
演算法流程#
1. 計算用戶之間的相似度
2. 找到目標用戶的 K 個最相似用戶
3. 用這 K 個用戶的評分加權預測目標用戶的評分
4. 推薦預測評分最高的物品預測公式#
r̂(u,i) = r̄_u + Σ[sim(u,v) × (r(v,i) - r̄_v)] / Σ|sim(u,v)|r̄_u:用戶 u 的平均評分sim(u,v):用戶 u 和 v 的相似度r(v,i):用戶 v 對物品 i 的評分
優缺點#
| 優點 | 缺點 |
|---|---|
| 可以發現用戶潛在興趣 | 用戶量大時計算複雜 |
| 推薦結果可解釋 | 用戶冷啟動問題 |
| 實現簡單 | 相似度矩陣需要頻繁更新 |
Item-Based 協同過濾#
演算法流程#
1. 計算物品之間的相似度
2. 對用戶歷史評分過的物品
3. 找到每個物品的相似物品
4. 用用戶對歷史物品的評分加權預測新物品評分預測公式#
r̂(u,i) = Σ[sim(i,j) × r(u,j)] / Σ|sim(i,j)|sim(i,j):物品 i 和 j 的相似度r(u,j):用戶 u 對物品 j 的評分
與 User-Based 的比較#
| 維度 | User-Based | Item-Based |
|---|---|---|
| 計算物件 | 用戶相似度矩陣 | 物品相似度矩陣 |
| 適用場景 | 用戶少、物品多 | 用戶多、物品少 |
| 更新頻率 | 需要頻繁更新 | 相對穩定 |
| 工業應用 | 較少 | 廣泛(Amazon、Netflix) |
| 冷啟動 | 物品冷啟動較好 | 用戶冷啟動較好 |
工業實踐:Item-Based CF 更常用,因為物品之間的相似度比用戶之間更穩定,可以離線計算。
相似度計算方法#
餘弦相似度#
cos(u,v) = (u·v) / (|u| × |v|)
= Σ(r_ui × r_vi) / √(Σr_ui²) × √(Σr_vi²)皮爾遜相關係數#
pearson(u,v) = Σ[(r_ui - r̄_u)(r_vi - r̄_v)] /
√[Σ(r_ui - r̄_u)²] × √[Σ(r_vi - r̄_v)²]皮爾遜相關係數考慮了用戶評分的偏差(有人傾向打高分,有人傾向打低分)。
Jaccard 相似度#
jaccard(u,v) = |I_u ∩ I_v| / |I_u ∪ I_v|只考慮是否有評分,不考慮評分值。
改進的餘弦相似度#
考慮物品的平均評分:
sim(i,j) = Σ[(r_ui - r̄_i)(r_uj - r̄_j)] /
√[Σ(r_ui - r̄_i)²] × √[Σ(r_uj - r̄_j)²]相似度計算的優化#
問題:熱門物品偏差#
熱門物品與任何物品的共同用戶都很多,容易導致相似度過高。
解決方案:IUF (Inverse User Frequency)#
類似於 TF-IDF 的思想:
sim(i,j) = Σ[1/log(1 + |N_u|)] / √(|N_i| × |N_j|)N_u:用戶 u 評分過的物品數- 活躍用戶對相似度的貢獻被降權
歸一化處理#
sim_norm(i,j) = sim(i,j) / max(sim(i,·))避免某些物品的相似度普遍較高。
實踐中的挑戰#
1. 稀疏性問題#
用戶-物品矩陣通常非常稀疏(99.9%+ 為空),導致相似度計算不準確。
解決方案:
- 矩陣分解(降維)
- 預設投票
- 聚類
2. 可擴展性問題#
| 規模 | 計算複雜度 |
|---|---|
| m 用戶 | O(m²) 用戶相似度 |
| n 物品 | O(n²) 物品相似度 |
解決方案:
- 離線預計算
- 分佈式計算
- 近似最近鄰 (ANN)
3. 冷啟動問題#
| 類型 | 表現 | 緩解方案 |
|---|---|---|
| 新用戶 | 無歷史行為 | 引導選擇興趣、使用人口統計學特徵 |
| 新物品 | 無人評分 | 基於內容的推薦、編輯推薦 |
工程實現要點#
相似度矩陣存儲#
存儲方案
# 使用稀疏矩陣存儲
from scipy.sparse import csr_matrix
# 只存儲非零元素
similarity = csr_matrix((data, (row, col)), shape=(n_items, n_items))
# 或使用 Redis 存儲 TopK 相似物品
# key: item_id, value: [(similar_item_id, score), ...]增量更新#
1. 新增用戶行為時,更新相關物品的相似度
2. 定期全量重算,保證準確性
3. 使用雙 Buffer 切換,避免服務中斷離線/在線分離#
| 階段 | 任務 | 頻率 |
|---|---|---|
| 離線 | 計算相似度矩陣 | 每天/每小時 |
| 在線 | 查詢相似物品,加權計算 | 實時 |
評估指標#
預測準確度#
RMSE = √[Σ(r̂_ui - r_ui)² / n]
MAE = Σ|r̂_ui - r_ui| / n排序指標#
| 指標 | 計算方式 |
|---|---|
| Precision@K | 推薦列表中相關物品的比例 |
| Recall@K | 相關物品被推薦的比例 |
| NDCG@K | 考慮位置的排序質量 |
總結#
| 要點 | 說明 |
|---|---|
| 核心思想 | 利用群體智慧,相似用戶/物品有相似偏好 |
| User-Based | 找相似用戶,適合用戶少物品多的場景 |
| Item-Based | 找相似物品,工業界更常用 |
| 相似度 | 餘弦、皮爾遜、Jaccard |
| 挑戰 | 稀疏性、可擴展性、冷啟動 |
| 工程實踐 | 離線計算相似度,在線查詢召回 |