工程實踐#

推薦系統的落地需要解決許多工程問題,本章介紹資料採集、實時推薦、實驗平台和服務化等實踐經驗。

資料採集#

採集要素#

要素說明示例
用戶標識唯一識別用戶user_id、device_id、cookie
行為類型用戶做了什麼曝光、點擊、購買、收藏
行為物件作用於什麼物品item_id
時間戳什麼時候發生timestamp
上下文發生的環境頁面、位置、設備

埋點規範#

{
  "event_type": "click",
  "user_id": "u123456",
  "item_id": "i789",
  "timestamp": 1706313600000,
  "page_id": "home",
  "position": 3,
  "recommend_id": "rec_xxx",
  "device": {
    "os": "iOS",
    "version": "17.0"
  }
}

recommend_id 非常重要,用於關聯曝光和後續行為,追蹤推薦效果。

資料質量保障#

問題影響解決方案
資料丟失訓練資料不完整多端上報、本地快取重傳
資料延遲特徵更新不及時流批一體架構
資料錯誤模型效果下降資料校驗、異常監控
重複資料統計偏差去重機制

去重策略#

內容去重:Simhash#

處理相似內容,避免推薦重複新聞:

1. 對文本分詞,計算每個詞的權重
2. 每個詞雜湊成二進位向量,0 變成 -1
3. 加權求和,正數變 1,負數變 0
4. 得到 Simhash 指紋

特點:

  • 相似內容的 Simhash 相近
  • 計算漢明距離判斷相似度
  • 計算效率高

用戶去重:Bloom Filter#

防止重複推薦已看過的內容:

1. 準備長度為 m 的二進位向量
2. 使用 k 個獨立雜湊函式
3. 每個已推薦物品雜湊到 k 個位置,設為 1
4. 查詢時,k 個位置都為 1 則認為已推薦過

Bloom Filter 有一定的誤判率(可能把未推薦的判斷為已推薦),但可以接受。

實時推薦#

三個層次#

層次說明難度
給得及時服務響應快基本要求
用得及時特徵實時更新中等
改得及時模型實時更新困難

實時架構#

用戶行為 → Kafka → 流計算 → 特徵更新 → 在線服務
                    ↓
                模型更新
                    ↓
              推薦結果更新

增量更新 Item-CF#

當用戶產生新行為時:

增量更新邏輯
輸入:用戶 u 對物品 i 產生行為

步驟:
1. 取出用戶歷史行為物品列表 [j1, j2, ...]
2. 對每個 j:
   - 增加 (i, j) 的共現次數
   - 增加 i 的評分用戶數
3. 重新計算所有相關物品對的相似度
4. 更新推薦結果

效率優化#

方法說明
剪枝相似度穩定後不再更新(Hoeffding 不等式)
滑窗只保留最近 K 條行為
採樣對高頻行為降採樣
合併批量處理多條行為再更新
快取熱門資料放入快取

實驗平台#

為什麼需要實驗平台#

資料驅動的核心是做對比實驗,科學地評估改進效果。

A/B 測試三要素#

要素說明
流量用戶訪問,實驗樣本來源
參數不同策略或模型的配置
結果日誌記錄,分析實驗效果

分層實驗架構#

Google 的分層實驗框架:

        全部流量
            ↓
    ┌───────┴───────┐
    域 1           域 2
    ↓               ↓
  層 1 → 桶 1-5    獨立實驗
    ↓
  層 2 → 桶 1-5
    ↓
  層 3 → 桶 1-5

核心概念:

概念說明
域 (Domain)流量的劃分
層 (Layer)參數子集的測試
桶 (Bucket)實驗組和對照組

流量分配#

def get_bucket(user_id, layer_id, n_buckets=1000):
    """
    計算用戶落入哪個桶
    - 同一用戶在同一層始終落入同一桶(體驗一致)
    - 不同層的分配相互獨立(無偏置)
    """
    hash_key = f"{user_id}_{layer_id}"
    hash_value = md5(hash_key.encode()).hexdigest()
    return int(hash_value, 16) % n_buckets

實驗規模估算#

Google 公式:

N >= 10.5 × (s/θ)²

其中:
- s:指標標準差
- θ:希望檢測的敏感度(如 2% 的 CTR 變化)

這個規模保證 90% 的統計功效。

服務化#

在線服務要求#

要求指標
延遲P99 < 100ms
可用性99.99%
QPS根據業務量級

微服務架構#

API Gateway
    ↓
┌───┴───┐
召回服務  排序服務
    ↓        ↓
Redis   模型服務

模型部署#

方式適用場景
嵌入式小模型,直接加載到服務行程
RPC 服務大模型,獨立部署
TensorFlow ServingTF 模型標準化部署
TritonNVIDIA GPU 推理服務

開源工具#

演算法層#

任務工具
文本處理FastText、Gensim、LightLDA
協同過濾Surprise、Implicit
矩陣分解QMF、Spark ALS
深度學習TensorFlow、PyTorch
向量檢索Faiss、Annoy、NMSLIB

平台層#

任務工具
消息佇列Kafka
流計算Flink、Storm
批處理Spark
存儲Redis、Cassandra、HBase
搜尋引擎ElasticSearch

完整推薦系統#

項目語言特點
LensKitJava學術界常用
SurprisePython簡單易用,適合學習
RecBolePython深度學習推薦框架

建議選擇各個模組的開源項目,自己組合集成,而不是使用大而全的框架。這樣更容易診斷問題和優化。

團隊組建#

最小配置#

角色數量職責
演算法工程師1-2資料分析、模型訓練、效果評估
後端工程師2推薦服務、API 開發
運維工程師1-2資料採集、日誌管理

工程師核心素質#

素質說明
工程能力快速交付高效少 Bug 的程式碼
理論基礎能看懂論文,理解演算法原理
可視化思維將資料規律直觀呈現

總結#

要點說明
資料採集規範埋點,保障資料質量
去重策略Simhash 內容去重,Bloom Filter 用戶去重
實時推薦三個層次:服務實時、特徵實時、模型實時
實驗平台分層實驗,無偏流量分配
服務化低延遲、高可用、可降級
開源工具按模組選擇,自己組合