簡介#
News feed(動態消息)是社群平台的核心功能,透過在使用者的時間軸上顯示好友的近期活動來維持用戶黏著度。Facebook、Twitter、LinkedIn 等主流社群平台皆採用個人化動態消息來提升用戶參與度。

本章的任務是設計一個個人化動態消息系統。
需求釐清#
以下是候選人與面試官之間的典型對話。
候選人: 可以假設個人化動態消息的目的是讓使用者持續使用平台嗎?
面試官: 是的,我們在貼文之間顯示贊助廣告,越高的參與度代表越多的收入。
候選人: 當使用者重新整理時間軸時,系統會顯示包含新活動的貼文。可以假設這些活動包括未讀貼文與有未讀留言的貼文嗎?
面試官: 這是合理的假設。
候選人: 貼文可以包含文字、圖片、影片或任意組合嗎?
面試官: 可以是任意組合。
候選人: 為維持用戶參與度,系統應將最具吸引力的內容放在時間軸頂部,因為使用者更可能與前幾篇貼文互動。這樣理解正確嗎?
面試官: 是的,沒錯。
候選人: 我們要優化的是哪種類型的參與度?我假設有不同的互動類型,例如點擊、按讚和分享。
面試官: 好問題。不同的互動在平台上有不同的價值。例如,按讚比單純點擊更有價值。理想情況下,系統在排序貼文時應考量主要的互動類型。我讓你來定義「參與度」並決定模型的優化目標。
候選人: 平台上有哪些主要互動類型?我假設使用者可以點擊、按讚、分享、留言、隱藏、封鎖其他使用者,以及發送交友邀請。還有其他需要考慮的嗎?
面試官: 你提到了主要的互動類型,就聚焦在這些上。
候選人: 系統的回應速度要求是什麼?
面試官: 使用者重新整理時間軸或開啟應用程式後,系統應快速顯示排序後的貼文。太慢的話使用者會失去耐心而離開。假設系統需在 200 毫秒(ms)內完成排序並顯示。
候選人: 每日活躍用戶數有多少?每天預期有多少次時間軸更新?
面試官: 總用戶約 30 億,其中約 20 億為每日活躍用戶,平均每天查看兩次動態消息。
問題摘要:設計一個個人化動態消息系統,檢索使用者未讀的貼文或含有未讀留言的貼文,並根據參與度分數進行排序。排序延遲不超過 $200 \mathrm{~ms}$,目標是提升用戶參與度。
將問題框架化為 ML 任務#
定義 ML 目標#
以下是三種可能的 ML 目標:
- 最大化特定隱性互動數量:如停留時間或點擊數
- 最大化特定顯性互動數量:如按讚或分享數
- 最大化基於隱性與顯性互動的加權分數
逐一分析如下。
選項一:最大化特定隱性互動(如停留時間或點擊數)
- 優點:隱性互動的資料量遠大於顯性互動,更多訓練資料通常能帶來更精確的模型
- 缺點:隱性互動不一定反映使用者的真實偏好。例如,使用者可能點擊了一篇貼文,卻發現不值得閱讀
選項二:最大化特定顯性互動(如按讚、分享、隱藏)
- 優點:顯性訊號通常比隱性訊號更有意義。例如,按讚傳達的參與訊號比單純點擊更強
- 缺點:極少數使用者會透過顯性互動表達意見。使用者可能覺得貼文有趣卻不做任何反應,導致訓練資料不足,模型難以做出準確預測
選項三:最大化基於隱性與顯性互動的加權分數
此選項同時使用隱性與顯性互動來衡量使用者對貼文的參與程度:
- 為每種互動類型分配權重,權重依據該互動對平台的價值而定
- 優化 ML 系統以最大化互動的加權分數
表 10.1 顯示不同互動類型與權重的對應關係。按讚的權重高於點擊,分享的價值高於按讚,而隱藏和封鎖等負面互動則有負權重。這些權重可依業務需求調整。
| 互動類型 | 點擊 | 按讚 | 留言 | 分享 | 交友邀請 | 隱藏 | 封鎖 |
|---|---|---|---|---|---|---|---|
| 權重 | 1 | 5 | 10 | 20 | 30 | -20 | -50 |
表 10.1:不同互動類型的權重
最終選擇: 選擇第三個混合選項,因為它允許為不同互動分配不同權重,能根據業務需求優化系統。
指定系統的輸入與輸出#
如圖 10.2 所示,個人化動態消息系統以使用者為輸入,輸出一份依參與度分數排序的未讀貼文(或含未讀留言的貼文)清單。

選擇適當的 ML 類別#
個人化動態消息系統根據貼文對使用者的吸引力生成排序清單。Pointwise Learning to Rank(LTR) 是一種簡單且有效的方法,透過參與度分數來排序貼文以實現個人化。
如圖 10.3 所示,我們使用多個二元分類器來預測 $\langle$ user, post $\rangle$ 配對中各種隱性與顯性互動的機率。

預測完成後,計算參與度分數。圖 10.4 展示計算範例:
| 互動類型 | 點擊 | 按讚 | 留言 | 分享 | 交友邀請 | 隱藏 | 封鎖 |
|---|---|---|---|---|---|---|---|
| 預測機率 | 23% | 48% | 12% | 4% | 0.1% | 0.005% | 0.0003% |
| 價值 | 1 | 5 | 10 | 20 | 30 | -20 | -50 |
| 分數 | 0.23 | 2.4 | 1.2 | 0.8 | 0.03 | -0.001 | -0.00015 |
| 參與度分數 = 4.65885 |
圖 10.4:參與度分數計算範例
資料準備#
資料工程#
在進行特徵工程之前,先了解有哪些原始資料。假設以下四種原始資料可用:
- Users(使用者)
- Posts(貼文)
- User-post interactions(使用者-貼文互動)
- Friendship(好友關係)
使用者資料#
| ID | 使用者名稱 | 年齡 | 性別 | 城市 | 國家 | 語言 | 時區 |
|---|
表 10.2:使用者資料 schema
貼文資料#
| 作者 ID | 文字內容 | Hashtag | 提及 | 圖片或影片 | 時間戳記 |
|---|---|---|---|---|---|
| 5 | Today at our fav place with my best friend | life_is_good, happy | hs2008 | - | 1658450539 |
| 1 | It was the best trip we ever had | Travel, Maldives | Alexish, shan.tony | htcdn.mysite.com/maldives.jpg | 1658451341 |
| 29 | Today I had a bad experience I would like to tell you about. I went… | - | - | - | 1658451365 |
表 10.3:貼文資料
使用者-貼文互動資料#
| 使用者 ID | 貼文 ID | 互動類型 | 互動值 | 位置(緯度, 經度) | 時間戳記 |
|---|---|---|---|---|---|
| 4 | 18 | 按讚 | - | 38.8951, -77.0364 | 1658450539 |
| 4 | 18 | 分享 | User 9 | 41.9241, -89.0389 | 1658451365 |
| 9 | 18 | 留言 | You look amazing | 22.7531, 47.9642 | 1658435948 |
| 9 | 18 | 封鎖 | - | 22.7531, 47.9642 | 1658451849 |
| 6 | 9 | 曝光 | 37.5189, 122.6405 | 1658821820 |
表 10.4:使用者-貼文互動資料
好友關係資料#
好友關係表儲存使用者之間的連結,並允許使用者標記密友和家人。
| 使用者 ID 1 | 使用者 ID 2 | 成為好友的時間 | 密友 | 家人 |
|---|---|---|---|---|
| 28 | 3 | 1558451341 | True | False |
| 7 | 39 | 1559281720 | False | True |
| 11 | 25 | 1559312942 | False | False |
表 10.5:好友關係資料
特徵工程#
本節從以下三個類別工程化預測特徵:
- 貼文特徵(Post features)
- 使用者特徵(User features)
- 使用者-作者親和度(User-author affinities)
貼文特徵#
實務上每篇貼文有許多屬性,以下討論最重要的幾項:
- 文字內容
- 圖片或影片
- 互動數據
- Hashtag
- 貼文年齡
文字內容#
- 定義:貼文的主要文字內容
- 重要性:有助於判斷貼文的主題
- 處理方式:對文字進行前處理,再使用預訓練語言模型將文字轉換為數值向量。由於文字內容通常是完整句子而非單一詞彙,使用如 BERT 等上下文感知語言模型
圖片或影片#
- 定義:貼文可能包含的圖片或影片
- 重要性:可從中提取重要訊號。例如,包含槍枝的圖片可能表示該貼文不適合兒童
- 處理方式:先進行前處理,再使用預訓練模型將非結構化的圖片/影片資料轉換為 embedding 向量。例如可使用 ResNet 或 CLIP 模型
互動數據#
- 定義:貼文的按讚數、分享數、回覆數等
- 重要性:反映使用者對貼文的參與程度。使用者更可能與有數千個讚的貼文互動,而非僅有十個讚的貼文
- 處理方式:以數值表示,並進行縮放使其落在相近的範圍內
Hashtag#
- 重要性:使用者透過 hashtag 將內容歸類到特定主題。例如,帶有 “#women_in_tech” 的貼文表示內容與科技和女性相關,模型可能會為對科技感興趣的使用者提高其排名
- 處理方式:
- 分詞(Tokenization):像 “lifeisgood” 或 “programmer_lifestyle” 等 hashtag 包含多個單字,使用 Viterbi 等演算法進行分詞。例如 “lifeisgood” 拆分為 “life”、“is”、“good”
- Token 轉 ID:Hashtag 在社群平台上變化快速。Feature hashing 技術適合此場景,能為未見過的 hashtag 分配索引
- 向量化(Vectorization):使用 TF-IDF 或 word2vec 等輕量方法,而非 Transformer 模型。原因是 hashtag 通常是單一詞彙或短語,不需要上下文理解,因此更快更輕量的方法更為合適
貼文年齡#
- 定義:作者發布貼文至今經過的時間
- 重要性:使用者傾向與較新的內容互動
- 處理方式:將貼文年齡分桶(bucketize)並使用 one-hot encoding 表示:
- 0:少於 1 小時
- 1:1 至 5 小時
- 2:5 至 24 小時
- 3:1 至 7 天
- 4:7 至 30 天
- 5:超過一個月

使用者特徵#
重要的使用者相關特徵包括:
- 人口統計資料:年齡、性別、國家等
- 上下文資訊:裝置、時段等
- 使用者-貼文歷史互動
- 是否在貼文中被提及
人口統計和上下文資訊已在前幾章討論過,以下僅探討後兩項。
使用者-貼文歷史互動#
使用者按讚過的所有貼文以貼文 ID 清單表示,分享和留言同理。
- 重要性:使用者過去的互動行為有助於預測未來的互動
- 處理方式:從使用者互動過的每篇貼文中提取特徵
是否在貼文中被提及#
- 定義:使用者是否在貼文中被提及
- 重要性:使用者通常更關注提及自己的貼文
- 處理方式:以二元值表示。被提及為 1,否則為 0

使用者-作者親和度#
根據研究,親和度特徵(如使用者與作者之間的連結)是 Facebook 上預測用戶參與度最重要的因素之一。以下工程化幾項捕捉使用者-作者親和度的特徵。
按讚/點擊/留言/分享率#
使用者對某作者過去貼文的互動比率。例如,按讚率 0.95 表示使用者對該作者的貼文有 95% 的按讚率。
好友關係時長#
使用者與作者在平台上成為好友的天數,可從好友關係資料中取得。
- 重要性:使用者傾向與好友的內容互動更多
密友與家人#
一個二元值,表示使用者與作者是否互相加入密友和家人清單。
- 重要性:使用者更關注密友和家人的貼文

模型開發#
模型選擇#
選擇神經網路的原因:
- 能良好處理非結構化資料(如文字和圖片)
- 可使用 embedding 層表示類別特徵
- 可微調特徵工程階段使用的預訓練模型,這是其他模型無法做到的
在訓練神經網路前,需選擇架構。有兩種選項:
- N 個獨立 DNN
- 多任務 DNN(Multi-task DNN)
選項一:N 個獨立 DNN
為每種互動類型使用一個獨立的深度神經網路(DNN),如圖 10.8 所示。

此選項有兩個缺點:
- 訓練成本高:訓練多個獨立 DNN 耗費大量運算資源與時間
- 低頻互動資料不足:對於較少出現的互動類型,可能沒有足夠的訓練資料來準確預測其機率
選項二:多任務 DNN
為克服上述問題,採用多任務學習方法(圖 10.9)。

多任務學習在第五章(有害內容偵測)中已詳細說明,此處僅簡要描述:
- 同時學習多個任務,讓模型學習任務間的相似性
- 避免不必要的重複運算
- 架構選擇與超參數通常透過實驗決定:訓練並評估不同架構的模型,選擇效果最佳者
針對被動使用者改進 DNN 架構#
目前的 DNN 預測分享、按讚、點擊、留言等互動。然而,許多被動使用者(passive users)很少與時間軸上的內容互動。對於這類使用者,模型會預測出極低的互動機率。因此需調整 DNN 架構以考量被動使用者。
新增兩項隱性互動任務:
- 停留時間(Dwell-time):使用者在貼文上花費的時間
- 跳過(Skip):若使用者在貼文上停留少於 $t$ 秒(例如 $0.5$ 秒),則視為該貼文被跳過

模型訓練#
建構資料集#
由於 DNN 模型需學習多個任務,需為每種互動類型建立正樣本與負樣本。
以「按讚」為例說明正負樣本的建構方式:
- 正樣本:每當使用者對貼文按讚,就加入一筆資料、計算 $\langle$ user, post $\rangle$ 特徵,並標記為正樣本
- 負樣本:選擇未導致按讚的曝光(impression)。負樣本數量通常遠多於正樣本,為避免資料不平衡,將負樣本數量控制為與正樣本相等

相同流程可用於建立其他互動的正負標籤。但停留時間是迴歸任務,建構方式不同——如圖 10.12 所示,ground truth 標籤即為曝光的停留時間。

選擇損失函數#
多任務模型同時學習多個任務,需分別計算各任務的損失再合併為整體損失:
- 二元分類任務:使用 binary cross-entropy loss
- 迴歸任務(停留時間預測):使用 MAE、MSE 或 Huber loss
- 整體損失:組合各任務的損失

評估#
離線指標#
離線評估衡量模型預測各種互動的表現:
- 對個別互動類型,使用二元分類指標如 precision 和 recall
- 單一指標不足以全面了解模型效能,因此使用 ROC 曲線理解 true positive rate 與 false positive rate 之間的權衡
- 計算 ROC-AUC(ROC 曲線下面積)以數值方式總結分類效能
線上指標#
從多個角度衡量用戶參與度:
- 點擊率(CTR)
- 互動率(Reaction rate)
- 總花費時間
- 使用者滿意度(來自問卷調查)
CTR(點擊率)
$C T R=\frac{\text { number of clicked posts }}{\text { number of impressions }}$
- 點擊數與曝光數的比率
- 高 CTR 不一定代表高參與度。例如使用者可能點擊了低價值的標題黨貼文後迅速離開
- 儘管有此限制,仍是重要的追蹤指標
互動率(Reaction rates)
反映使用者互動行為的一組指標。例如按讚率衡量被按讚的貼文佔所有顯示貼文的比例:
$\text { Like rate }=\frac{\text { number of liked posts }}{\text { number of impressions }}$
同理,還追蹤分享率、留言率、隱藏率、封鎖率、跳過率等。這些是比 CTR 更強的訊號,因為使用者明確表達了偏好。
上述指標針對的是主動互動的使用者,但對於被動使用者——那些幾乎不對貼文做出任何反應的人——需要額外的指標來捕捉系統的有效性。
總花費時間(Total time spent)
使用者在固定期間(如 1 週)內花在時間軸上的總時間。此指標能同時衡量被動與主動使用者的整體參與度。
使用者滿意度調查(User satisfaction rate)
直接詢問使用者對動態消息的看法,或對貼文的吸引力評價。由於尋求的是明確的回饋,這是衡量系統有效性最準確的方式。
上線服務#
在服務時,系統輸出排序後的貼文清單。圖 10.14 為個人化動態消息系統的架構圖,包含以下管線:
- 資料準備管線(Data preparation pipeline)
- 預測管線(Prediction pipeline)

資料準備管線與第八章(社群平台廣告點擊預測)相似,此處不再贅述。以下探討預測管線。
預測管線#
預測管線由以下元件組成:
- 檢索服務(Retrieval service):檢索使用者未讀的貼文,或含有未讀留言的貼文。關於高效檢索未讀貼文的方法,參閱
- 排序服務(Ranking service):為每篇檢索到的貼文計算參與度分數並進行排序
- 重排序服務(Re-ranking service):結合額外邏輯與使用者篩選條件調整貼文順序。例如,若使用者明確表示對足球感興趣,此服務會提高相關貼文的排名
其他討論主題#
若面試尚有剩餘時間,可探討以下進階主題:
- 如何處理正在爆紅的貼文
- 如何為新使用者個人化動態消息(冷啟動問題)
- 如何緩解系統中的位置偏差(positional bias)
- 如何決定適當的模型重訓練頻率