矩陣分解#

矩陣分解 (Matrix Factorization) 是協同過濾的進階方法,通過將用戶-物品矩陣分解為低維隱因子向量,解決稀疏性問題。

基本原理#

分解目標#

m × n 的用戶-物品評分矩陣 R 分解為兩個低維矩陣:

R(m×n) ≈ P(m×k) × Q(k×n)^T

其中:
- P:用戶隱因子矩陣,每個用戶對應 k 維向量
- Q:物品隱因子矩陣,每個物品對應 k 維向量
- k:隱因子數量(通常 10~200)

預測評分#

r̂(u,i) = p_u · q_i = Σ(p_uk × q_ik)

隱因子可以理解為潛在的「主題」或「特徵」,如電影的動作程度、愛情程度等。

SVD 及其變體#

基礎 SVD#

損失函式:

L = Σ(r_ui - p_u · q_i)² + λ(||p_u||² + ||q_i||²)
  • 第一項:預測誤差
  • 第二項:正則化,防止過擬合

SVD++#

加入隱式反饋:

r̂(u,i) = μ + b_u + b_i + q_i · (p_u + |N(u)|^(-1/2) Σ y_j)

其中:
- μ:全局平均評分
- b_u:用戶偏差
- b_i:物品偏差
- N(u):用戶 u 有過行為的物品集合
- y_j:物品 j 的隱式特徵向量

SVD++ 考慮了用戶「看過什麼」這一隱式資訊,即使沒有評分,瀏覽行為也能提供資訊。

TimeSVD++#

考慮時間因素:

r̂(u,i,t) = μ + b_u(t) + b_i(t) + q_i · p_u(t)

用戶偏好和物品熱度都會隨時間變化。

優化演算法#

隨機梯度下降 (SGD)#

for epoch in range(num_epochs):
    for u, i, r in training_data:
        error = r - predict(u, i)
        # 更新用戶向量
        P[u] += lr * (error * Q[i] - reg * P[u])
        # 更新物品向量
        Q[i] += lr * (error * P[u] - reg * Q[i])

交替最小二乘 (ALS)#

ALS 是 Facebook 推薦系統採用的主要方法,更適合分布式計算。

核心思想:交替固定一個矩陣,優化另一個矩陣。

1. 初始化 Q 為隨機矩陣
2. 固定 Q,求解 P = R × Q × (Q^T × Q + λI)^(-1)
3. 固定 P,求解 Q
4. 重複 2-3 直到收斂
ALS 優點
  • 每一步都有解析解,計算穩定
  • 天然可並行:每個用戶/物品的更新互不依賴
  • 適合處理大規模稀疏矩陣

SGD vs ALS#

維度SGDALS
收斂速度較慢較快(稀疏資料)
並行化困難容易
實現複雜度簡單中等
適用場景顯式評分隱式反饋

隱式反饋處理#

One-Class 問題#

實際推薦系統中,評分資料很少,更多的是隱式反饋(點擊、瀏覽、購買)。

反饋類型特點示例
顯式反饋用戶明確表達喜好評分、點讚
隱式反饋只有正樣本,缺少負樣本點擊、購買

Weighted-ALS#

針對隱式反饋的改進:

L = Σ c_ui × (r_ui - p_u · q_i)² + λ(||P||² + ||Q||²)

其中:
- r_ui = 1(有行為)或 0(無行為)
- c_ui = 1 + α × 行為次數(置信度)

行為次數越多,置信度越高。預設 α = 40。

負樣本採樣#

由於沒有明確的負樣本,需要構造:

方法說明效果
隨機採樣均勻隨機選擇無行為物品一般
熱門採樣按物品熱度採樣較好
曝光採樣從曝光未點擊中採樣最好

熱門採樣的邏輯:熱門物品用戶更可能知道其存在,如果沒有行為,更可能是真正的負樣本。

BPR: 面向排序的矩陣分解#

動機#

傳統矩陣分解優化的是評分預測準確度,但推薦的最終目標是排序正確。

BPR 優化目標#

max Σ log σ(r̂_uij) - λ||Θ||²

其中:
- r̂_uij = r̂_ui - r̂_uj
- (u, i, j):用戶 u 對物品 i 有正反饋,對物品 j 無反饋
- σ:sigmoid 函式

BPR 直接優化「正樣本排在負樣本前面」的概率。

BPR 訓練流程#

for epoch in range(num_epochs):
    for u, i, j in sample_triplets():
        x_uij = predict(u, i) - predict(u, j)
        gradient = sigmoid(-x_uij)
        # 更新參數
        update_parameters(u, i, j, gradient)

評估指標:AUC#

AUC = Σ I(r̂_ui > r̂_uj) / |positive| × |negative|

AUC 衡量正樣本排在負樣本前面的概率。

向量檢索#

問題#

矩陣分解得到用戶和物品的隱因子向量後,如何高效找到最相似的物品?

解決方案:近似最近鄰 (ANN)#

工具特點適用場景
FaissFacebook 開源,支援動態更新通用推薦
AnnoySpotify 開源,輕量級中小規模
NMSLIB高性能,多種演算法大規模搜尋
Faiss 示例
import faiss

# 構建索引
d = 128  # 向量維度
index = faiss.IndexFlatL2(d)  # L2 距離
index.add(item_vectors)  # 添加物品向量

# 查詢最相似的 k 個物品
k = 10
D, I = index.search(user_vector, k)

聚類加速#

另一種方法是先對物品向量聚類:

1. 對物品向量進行 K-means 聚類
2. 計算用戶向量與每個聚類中心的相似度
3. 選擇相似度最高的聚類
4. 從選中的聚類中選擇具體物品

優點:可以控制推薦多樣性。

工程實踐#

模型訓練#

工具語言特點
Spark ALSScala分布式,適合大規模
LightFMPython支援混合特徵
ImplicitPython專注隱式反饋
QMFC++Quora 開源,單機高性能

QMF 性能:單機(32 核、244G 記憶體)20 分鐘完成 10 億非零元素的矩陣分解。

模型更新策略#

策略頻率優點缺點
全量更新每天準確計算量大
增量更新每小時及時可能累積誤差
混合策略-平衡實現複雜

總結#

要點說明
核心思想將用戶和物品映射到低維隱因子空間
SVD++加入隱式反饋和偏置項
ALS交替優化,適合分布式計算
Weighted-ALS處理隱式反饋,使用置信度加權
BPR面向排序優化,直接優化 AUC
向量檢索使用 ANN 加速相似向量查找