本章設計一個類似 Eventbrite 的活動推薦系統。Eventbrite 是一個熱門的活動管理與票務平台,使用者可以建立、瀏覽及報名活動。推薦系統能為使用者呈現個人化的相關活動列表。

釐清需求#
以下是候選人與面試官之間的典型對話:
候選人: 商業目標是什麼?是否可以假設主要目標是增加售票量? 面試官: 是的,沒問題。
候選人: 除了參加活動,使用者是否能在平台上預訂飯店或餐廳? 面試官: 為求簡化,假設只支援活動。
候選人: 活動屬於一次性的短暫事件,結束後即失效,這個假設正確嗎? 面試官: 觀察得很好,沒錯。
候選人: 有哪些活動屬性可用?可否假設包含文字描述、價格範圍、地點、日期時間等? 面試官: 可以,這些假設合理。
候選人: 是否有標註資料? 面試官: 沒有人工標註的資料集,但可以利用活動與使用者的互動資料來建構訓練資料集。
候選人: 是否能取得使用者的當前位置? 面試官: 是的。由於此問題聚焦於基於位置的推薦系統,假設使用者同意分享位置資料。
候選人: 使用者是否能在平台上建立好友關係?好友資訊對建構個人化推薦系統很有價值。 面試官: 好問題。假設使用者可以建立好友關係,且好友關係是雙向的(若 A 是 B 的好友,則 B 也是 A 的好友)。
候選人: 使用者是否能邀請他人參加活動? 面試官: 是的。
候選人: 使用者是否能 RSVP 活動? 面試官: 為求簡化,假設只有報名選項。
候選人: 活動是免費還是付費的? 面試官: 兩者都需要支援。
候選人: 有多少使用者和活動? 面試官: 每月約有 100 萬場活動。
候選人: 每日活躍使用者有多少? 面試官: 假設每日有 100 萬名不重複使用者。
候選人: 由於我們在建構基於位置的推薦系統,高效計算兩地之間的距離和交通時間非常重要。可否使用外部 API(如 Google Maps)來取得此類資料? 面試官: 好的,假設可以使用第三方服務取得位置資料。
問題摘要: 設計一個活動推薦系統,為使用者顯示個人化的活動列表。活動結束後無法再報名。使用者可以報名活動、邀請他人及建立好友關係。訓練資料從使用者互動中建構。主要目標是增加售票收入。
將問題框架化為 ML 任務#
定義 ML 目標#
根據需求,商業目標是增加售票量。將其轉化為明確的 ML 目標:最大化活動報名數量。
指定系統的輸入與輸出#
- 輸入: 一位使用者
- 輸出: 依據與使用者的相關性排序的前 k 個活動
選擇合適的 ML 類別#
解決推薦問題的不同方法:
- 簡單規則: 推薦熱門活動
- 基於 Embedding 的模型: 依賴內容過濾(content-based)或協同過濾(collaborative filtering)
- 重新框架化為排序問題
規則方法適合作為 baseline,但 ML 方法通常表現更好。本章將任務重新框架化為排序問題,使用 Learning to Rank(LTR) 來解決。

LTR 是一類將監督式機器學習應用於排序問題的演算法技術。排序問題的正式定義為:「給定一個查詢和一組項目,如何從最相關到最不相關地對項目進行最佳排序?」LTR 主要有三種方法:pointwise、pairwise 和 listwise。以下簡要說明。詳細解釋可參閱。
Pointwise LTR#
逐一對每個項目預測其與查詢之間的相關性,使用分類或回歸方法。每個項目的分數是獨立預測的,最終透過排序預測分數來得到排名。

Pairwise LTR#
模型接收兩個項目,預測哪個項目與查詢更相關。

常見的 pairwise LTR 演算法包括 RankNet、LambdaRank 和 LambdaMART。
Listwise LTR#
給定查詢,直接預測整個項目列表的最佳排序。

常見的 listwise LTR 演算法包括 SoftRank、ListNet 和 AdaRank。
一般而言,pairwise 和 listwise 方法結果更準確,但實作與訓練難度較高。為求簡化,本章使用 pointwise 方法,具體採用二元分類模型,逐一接收單個活動並預測使用者報名的機率。

資料準備#
資料工程#
要設計好的特徵,首先須理解系統中可用的原始資料。活動管理平台主要圍繞使用者與活動,假設以下資料可用:
- Users(使用者)
- Events(活動)
- Friendship(好友關係)
- Interactions(互動)
使用者資料#
| ID | Username | Age | Gender | City | Country | Language | Time zone |
|---|
表 7.1:使用者資料 schema
活動資料#
| ID | Host User ID | Category / Subcategory | Description | Price | Location | Date/Time |
|---|---|---|---|---|---|---|
| 1 | 5 | Music Concert | Dua Lipa Tour in Miami | 200-900 | American Airlines Arena Miami, FL | 09/18/2022 19:00-24:00 |
| 2 | 11 | Sports Basketball | Golden State Warriors vs. Milwaukee Bucks | 140-2500 | Chase Center SF, CA | 09/22/2022 17:00-19:00 |
| 3 | 7 | Art Theater | The Comedy and Magic of Robert Hall | Free | San Jose Improv San Jose, CA | 09/06/2022 18:00-19:30 |
表 7.2:活動資料
好友關係資料#
每一列代表兩位使用者之間建立的好友關係及其時間戳記。
| User ID 1 | User ID 2 | Timestamp when friendship was formed |
|---|---|---|
| 28 | 3 | 1658451341 |
| 7 | 39 | 1659281720 |
| 11 | 25 | 1659312942 |
表 7.3:好友關係資料
互動資料#
儲存使用者互動資料,包括活動報名、邀請與曝光。實務上可能分開儲存於不同資料庫,此處為簡化合併於單一表中。
| User ID | Event ID | Interaction type | Interaction value | Location (lat, long) | Timestamp |
|---|---|---|---|---|---|
| 4 | 18 | Impression | - | 38.8951, -77.0364 | 1658450539 |
| 4 | 18 | Register | Confirmation number | 38.8951, -77.0364 | 1658451341 |
| 4 | 18 | Invite | User 9 | 41.9241, -89.0389 | 1658451365 |
表 7.4:互動資料
特徵工程#
活動推薦比傳統推薦更具挑戰性。活動與電影或書籍有根本性差異:活動結束後即無法消費。活動通常存續時間短(從建立到結束的時間短暫),因此單一活動的歷史互動資料有限。活動推薦本質上面臨冷啟動問題,並持續受到新項目問題的影響。
為克服這些問題,須更加努力進行特徵工程,創造盡可能多的有意義特徵。以下僅討論最重要的部分,實務中可建立的預測特徵數量遠多於此。
特徵分為以下類別:
- 位置相關特徵
- 時間相關特徵
- 社交相關特徵
- 使用者相關特徵
- 活動相關特徵
位置相關特徵#
活動地點的可及性
活動地點的可及性是重要因素。例如,若活動在偏遠山丘且遠離大眾運輸,通勤不便可能使使用者卻步。建立以下特徵來捕捉可及性:
- Walk score: 0 到 100 的分數,衡量某地址的步行友善程度。基於與鄰近設施的距離、行人友善度、人口密度等因素計算。可從 Google Maps、Open Street Map 等外部資料源取得。表 7.5 為分桶後的 5 個類別:
| 類別 | Walk score | 描述 |
|---|---|---|
| 1 | 90-100 | 不需要開車 |
| 2 | 70-89 | 非常適合步行 |
| 3 | 50-69 | 尚可步行 |
| 4 | 25-49 | 依賴汽車 |
| 5 | 0-24 | 必須開車 |
表 7.5:Walk score 類別
- Walk score 相似度: 活動的 walk score 與使用者先前報名活動的平均 walk score 之差
- Transit score、transit score 相似度、bike score、bike score 相似度
活動是否與使用者在同一國家和城市?
使用者的重要決策因素之一是活動是否位於同一國家和城市。可建立以下兩個特徵:
- 使用者的國家是否與活動的國家相同(1 或 0)
- 使用者的城市是否與活動的城市相同(1 或 0)
使用者對距離的接受度
部分使用者偏好非常近的活動,其他人則可接受較遠的活動。建立以下特徵:
- 使用者位置與活動地點的距離,可從外部 API 取得並分桶:
- 0:不到 1 英里
- 1:1-5 英里
- 2:5-20 英里
- 3:20-50 英里
- 4:50-100 英里
- 5:超過 100 英里
- 距離相似度: 活動距離與使用者先前報名活動的平均距離之差

時間相關特徵#
活動的剩餘時間是否方便?
部分使用者會提前數天規劃活動,其他人則不會。建立以下特徵:
- 活動開始前的剩餘時間,分桶並進行 one-hot 編碼:
- 0:不到 1 小時
- 1:1-2 小時
- 2:2-4 小時
- 3:4-6 小時
- 4:6-12 小時
- 5:12-24 小時
- 6:1-3 天
- 7:3-7 天
- 8:超過 7 天
- 剩餘時間相似度: 與使用者先前報名活動的平均剩餘時間之差
- 估計交通時間: 使用者位置到活動地點的估計交通時間,從外部服務取得並分桶
- 估計交通時間相似度: 與使用者先前報名活動的平均估計交通時間之差
日期和時間是否方便使用者?
部分使用者偏好週末活動,其他人偏好平日;部分偏好早上,其他人偏好晚上。為捕捉使用者的歷史偏好,建立一個使用者檔案向量(大小為 7),每個值計算使用者在特定星期幾參加的活動次數。除以總參加次數後,得到每日的歷史出席率。圖 7.8 顯示了某使用者先前參加活動的每日分佈。該使用者從未在週一或週三參加活動,因此推薦週三的活動可能不適合此使用者。類似方法也可建立每小時的使用者檔案,並加入日期和小時相似度特徵。

時間相關特徵的摘要如圖 7.9 所示。

社交相關特徵#
有多少人參加此活動?
使用者通常更可能報名有大量出席者的活動。建立以下特徵:
- 已報名此活動的使用者數量
- 已報名使用者數量與曝光次數的比率
- 已報名使用者相似度: 此活動的報名人數與先前報名活動的報名人數之差
好友參加相關特徵
若好友參加某活動,使用者更可能報名。可用特徵:
- 已報名此活動的好友數量
- 已報名好友數量與好友總數的比率
- 好友報名相似度: 此活動的好友報名人數與先前報名活動之差
使用者是否被邀請參加此活動?
被邀請的使用者更可能參加。可用特徵:
- 邀請此使用者參加此活動的好友數量
- 邀請此使用者參加此活動的其他使用者數量
活動主辦者是否為使用者的好友?
使用者傾向參加好友建立的活動。建立一個二元特徵:若活動主辦者是使用者的好友則為 1,否則為 0。
使用者過去參加過此主辦者多少場活動?
部分使用者會持續關注特定主辦者的活動。
使用者相關特徵#
年齡與性別
部分活動針對特定年齡或性別。例如「Women in Tech」和「Life lessons to excel in your 30s」。建立兩個特徵:
- 使用者的性別,使用 one-hot 編碼
- 使用者的年齡,分桶後使用 one-hot 編碼
活動相關特徵#
活動價格
活動價格可能影響使用者的報名決策。可用特徵:
- 活動價格,分桶為幾個類別:
- 0:免費
- 1:$1-$99
- 2:$100-$499
- 3:$500-$1,999
- 4:$2,000 以上
- 價格相似度: 活動價格與使用者先前報名活動的平均價格之差
活動描述與先前報名活動描述的相似度
此特徵反映使用者的興趣。例如,若「concert」一詞頻繁出現在先前報名活動的描述中,可能表示使用者對音樂會感興趣。計算方式:使用 TF-IDF 將描述轉為數值向量,再以 cosine distance 計算相似度。
此特徵可能含有雜訊,因為描述由主辦者手動提供。可透過在模型中加入或排除此特徵來衡量其重要性。
圖 7.10 概覽了使用者特徵、活動特徵與社交相關特徵。

上述特徵並非詳盡列表,實務中可建立更多預測特徵(如主辦者的熱門程度、使用者搜尋歷史、活動類別、自動產生的活動標籤等)。面試中不必嚴格遵循此節內容,可作為起點並深入討論面試官關注的主題。以下是可能的討論方向:
- Batch vs. streaming 特徵: Batch(靜態)特徵變化較少(如年齡、性別、活動描述),可透過批次處理定期計算並儲存於 feature store。Streaming(動態)特徵變化快速(如報名人數、活動剩餘時間),需即時計算。面試官可能希望深入討論批次與線上處理,可參閱。
- 特徵計算效率: 即時計算特徵效率不高。可考慮將兩個位置分別作為特徵傳入模型,讓模型隱式學習有用資訊,而非直接計算距離。位置資料準備可參閱。
- 使用衰減因子(decay factor): 對基於使用者最近 X 次互動的特徵,給予近期互動更高權重。
- 使用 Embedding 學習: 將每個活動和使用者轉換為 embedding 向量作為特徵。
- 從使用者屬性建立特徵可能引入偏差: 例如依據年齡或性別判斷求職者是否適合某工作可能導致歧視。使用使用者屬性建立特徵時,須注意潛在偏差問題。
模型開發#
模型選擇#
二元分類問題可用多種 ML 方法解決:
- Logistic regression
- Decision tree
- Gradient-boosted decision tree(GBDT)
- Neural network
Logistic Regression(LR)#
LR 使用特徵的線性組合來建模二元結果的機率。詳情可參閱。

優點:
- 推論速度快: 計算特徵的加權組合非常快速
- 訓練效率高: 架構簡單,容易實作、解釋且訓練快速
- 資料線性可分時效果良好(圖 7.12)
- 可解釋性強: 各特徵的權重反映其重要性,提供決策洞察

缺點:
- 無法解決非線性問題: 因為使用線性組合
- 多重共線性(multicollinearity)問題: 當兩個或多個特徵高度相關時,LR 無法良好學習
在本系統中,輸入特徵數量可能非常大,且特徵與目標變數之間常有複雜的非線性關係,LR 可能難以學習。
Decision Tree#
Decision tree 使用樹狀結構的決策模型來進行預測。圖 7.13 展示一個包含年齡和性別兩個特徵的簡單決策樹及其對應的決策邊界。每個葉節點指示一個二元結果(「+」為正類、「-」為負類)。詳情可參閱。

優點:
- 訓練快速
- 推論快速
- 幾乎不需資料前處理: 不需要資料正規化或縮放
- 可解釋性強: 視覺化樹結構提供決策洞察
缺點:
- 非最佳決策邊界: 決策邊界平行於特徵空間的軸(圖 7.13),對某些資料分佈可能不是最佳方式
- 過擬合(overfitting): 對資料的微小變化非常敏感,可能導致不同的預測結果或完全不同的樹結構
實務中很少直接使用 decision tree,因為對輸入資料變化過於敏感。為降低敏感性,常用以下兩種技術:
- Bootstrap aggregation(Bagging)
- Boosting
Bagging#
Bagging 是一種集成學習方法,在訓練資料的多個子集上平行訓練一組 ML 模型,再組合所有模型的預測來做最終預測。此方法顯著降低模型對資料變化的敏感度(variance)。
常見範例是 Random Forest。Random forest 在訓練期間平行建構多棵決策樹。預測時,每棵樹獨立預測輸出類別,再透過投票機制組合預測結果。

Bagging 的優點:
- 降低過擬合(高 variance)的影響
- 不顯著增加訓練時間(決策樹可平行訓練)
- 不顯著增加推論延遲(決策樹可平行處理)
但 bagging 在模型出現欠擬合(高 bias) 時無法幫助。為此引入 boosting。
Boosting#
Boosting 透過依序訓練多個弱分類器來減少預測誤差。「弱分類器」指性能略優於隨機猜測的簡單分類器。Boosting 將多個弱分類器組合為一個強學習模型。

優點:
- 同時降低 bias 和 variance: 組合弱分類器產生對資料變化較不敏感的強模型。偏差/方差取捨可參閱。
缺點:
- 訓練和推論較慢: 因為分類器須依序訓練(基於前一個分類器的錯誤)
實務中 boosting 通常優於 bagging,因為 bagging 無法改善 bias,而 boosting 可同時降低 bias 和 variance。
典型的 boosting 決策樹包括 AdaBoost、XGBoost 和 Gradient Boost。
GBDT#
GBDT 是一種常用的樹模型,利用 Gradient Boost 來改進決策樹。其變體如 XGBoost 在多項 ML 競賽中表現優異。詳情可參閱。

優點:
- 資料準備簡單: 與決策樹類似,不需資料前處理
- 降低 variance: 使用 boosting 技術
- 降低 bias: 利用多個弱分類器,反覆改進先前分類器的錯誤
- 適用於結構化資料
缺點:
- 需調整大量超參數: 如迭代次數、樹深度、正則化參數等
- 不適用於非結構化資料(圖片、影片、音訊等)
- 不適合持續學習(continual learning)
在本案例中,由於建立的特徵為結構化資料,GBDT 或其變體(如 XGBoost)是良好的實驗選擇。
GBDT 的主要缺點是不適合持續學習。活動推薦系統中,新資料持續產生(使用者互動、報名、新活動、新使用者),且使用者興趣可能隨時間變化。沒有持續學習能力,定期從頭重新訓練 GBDT 的成本很高。
Neural Network(NN)#
活動推薦系統有許多特徵與結果之間可能不是線性相關。學習這些複雜關係很困難,且持續學習對適應新資料至關重要。
NN 擅長解決這些挑戰:能學習具有非線性決策邊界的複雜任務,且可輕鬆在新資料上進行 fine-tune,非常適合持續學習。詳情可參閱。

優點:
- 持續學習: 設計上就是從資料中持續學習和改進
- 適用於非結構化資料(文字、圖片、影片、音訊)
- 表達能力強: 大量學習參數使其能學習非常複雜的任務和非線性決策邊界
缺點:
- 訓練計算成本高
- 對輸入資料品質敏感: 若特徵範圍差異很大,模型訓練可能收斂緩慢。資料前處理(正規化、log-scaling、one-hot 編碼等)是重要步驟
- 需要大量訓練資料
- 黑盒本質: 不易理解各特徵對結果的影響,因為輸入經過多層非線性轉換
應該選擇哪個模型?#
選擇正確的模型具有挑戰性,通常需要實驗不同模型來確定最佳選擇。可根據以下因素選擇:
- 任務複雜度
- 資料分佈與資料類型
- 產品需求或限制(如訓練成本、速度、模型大小等)
本問題中,GBDT 和 NN 都是良好的實驗候選。可先從 GBDT 變體 XGBoost 開始(實作和訓練快速),將其結果作為初始 baseline。
有了 baseline 後,再探索以 NN 建構更好模型的可能性。NN 預期在此場景表現良好的原因:
- 大量訓練資料: 使用者持續與系統互動(報名、邀請好友、發布新活動等),產生大量可用訓練資料
- 資料可能非線性可分,NN 能學習非線性資料
設計 NN 架構時,須考慮多項超參數(隱藏層數量、每層神經元數量、激活函數等),可透過超參數調整技術來決定。NN 架構細節通常不是 ML 系統設計面試的重點。
模型訓練#
建構資料集#
建構訓練和評估資料集是模型開發的關鍵步驟。
從互動資料中提取 $\langle$ user, event $\rangle$ 配對,計算輸入特徵,並標記標籤:
- 使用者已報名該活動 → 標籤為 1
- 使用者未報名該活動 → 標籤為 0

類別不平衡問題: 使用者可能瀏覽數十甚至數百個活動才報名一個,導致負樣本遠多於正樣本。可使用以下技術解決:
- 使用 focal loss 或 class-balanced loss 訓練分類器
- 欠採樣(undersample) 多數類別
選擇損失函數#
模型為二元分類模型,使用典型的分類損失函數,例如 binary cross-entropy 來最佳化神經網路。

評估#
離線指標#
評估排序系統的選項:
- Recall@k 或 Precision@k: 不適合,因為不考慮輸出的排序品質
- MRR、nDCG 或 mAP: 這三個指標常用於衡量排序品質
各指標的適用性:
- MRR: 聚焦於列表中第一個相關項目的排名,適合預期只檢索到一個相關項目的系統。活動推薦中可能有多個相關活動,MRR 不適合
- nDCG: 適合使用者與項目之間的相關性分數為非二元的情境
- mAP: 適合相關性分數為二元的情境。由於活動要嘛相關(使用者報名)要嘛不相關(使用者看到但未報名),mAP 最為適合
線上指標#
商業目標是透過增加售票量來提升收入。衡量系統對收入影響的指標:
- Click-through rate(CTR)
- Conversion rate
- Bookmark rate
- Revenue lift
CTR: 使用者看到推薦活動後點擊的比率。
$CTR=\frac{\text{total number of clicked events}}{\text{total number of impressions}}$
高 CTR 表示系統擅長推薦使用者會點擊的活動,更多點擊通常意味更多報名。
僅依賴 CTR 可能不夠充分,因為部分活動可能是標題黨(clickbait)。理想上應衡量推薦活動對使用者的真正相關性。
Conversion rate: 使用者看到推薦活動後實際報名的比率。
$\text{Conversion rate}=\frac{\text{total number of event registrations}}{\text{total number of impressions}}$
高 conversion rate 表示使用者更常報名推薦的活動。例如 conversion rate 為 0.3 表示使用者平均每 10 個推薦活動報名 3 個。
Bookmark rate: 使用者將推薦活動加入書籤的比率(假設平台支援書籤功能)。
Revenue lift: 由活動推薦帶來的收入增長。
服務架構#
本節提出可用於服務請求的 ML 系統設計。如圖 7.20 所示,設計包含兩條主要管線:
- Online learning pipeline
- Prediction pipeline

Online Learning Pipeline#
如前所述,活動推薦本質上面臨冷啟動和持續的新項目問題。模型必須持續 fine-tune 以適應新資料。此管線負責:
- 持續納入新資料訓練新模型
- 評估已訓練的模型
- 部署模型
Prediction Pipeline#
Prediction pipeline 負責為給定使用者預測前 $k$ 個最相關的活動。以下討論最重要的元件。
Event Filtering#
Event filtering 元件以查詢使用者為輸入,基於簡單規則(如活動地點或使用者篩選條件)將活動從 100 萬縮減至小型子集。例如,若使用者加入「僅限音樂會」篩選條件,此元件快速縮小列表至候選活動子集。此類篩選條件可將搜索空間從數百萬個活動顯著縮減至數百個候選活動。

Ranking Service#
此服務接收使用者和 filtering 元件產出的候選活動,為每個 $\langle$ user, event $\rangle$ 配對計算特徵,根據模型預測的機率排序活動,輸出前 $k$ 個最相關的活動。

Ranking service 與特徵計算元件互動。靜態特徵從 feature store 取得,動態特徵從原始資料即時計算。
其他討論主題#
面試剩餘時間可討論的額外主題:
- 此系統中可能觀察到的不同類型偏差
- 如何利用 feature crossing 實現更強的表達能力
- 部分使用者偏好多元化的活動列表,如何確保推薦的多樣性與新鮮度
- 我們使用使用者屬性和即時位置來訓練模型,隱私與安全性的考量
- 活動管理平台通常是雙邊市場(活動主辦者為供給方,使用者為需求方),如何確保系統不僅最佳化單邊?如何對不同主辦者保持公平?
- 建構資料集時如何避免資料洩漏(data leakage)
- 如何決定模型更新的適當頻率