Dcard 機器學習指南 (II) — 機器學習專案的技術規劃

Dcard Tech
Dcard Tech Blog
Published in
14 min readMay 17, 2022

Written By ML team lead Bruce

上一篇裡面,我們聊到了 Dcard 的團隊做一個機器學習專案,大概會經過的過程,以及怎麼拆解產品問題到機器學習團隊可以解決的問題。

複習一下上一篇的一些內容

在上一篇裡面,我們有提到的一個文章推薦的例子(圖一),後來我們把它轉化成提升點擊率的問題,在這篇裡面我們會先假設把這個問題用分類問題的方式來解決,並繼續做後續的思考及設計去協助大家理解我們在跑專案的方式及概念。

圖一:你可能感興趣的文章

在這一篇裡面,我們會分享轉化成機器學習問題之後,在實際動手做之前會需要怎麼去想哪一些類型的問題以避免做歪(如下圖二),導致整個專案出來之後效果不如預期的問題,主要會討論在 step 3 ~ step 6 中的一些細節以及我們的思考過程,如果有想討論的地方也歡迎大家留言~

圖二:機器學習專案流程

Step 3. 思考如何評估好壞 (online / offline evaluation)

呈上一篇的 Step 2. 提到的,在定義好機器學習的問題之後,我們需要去評估模型的好壞,這一步我們會思考以下的問題:

  1. 線上想要提升的指標是什麼?(Online metrics,通常是產品指標,在上面的例子裡也就是點擊率,但延伸可能還有我們一些關心的指標)
  2. 線下的指標應該要觀測什麼?(Offline metrics,在評估模型好壞時,需要先知道線上想要提升怎樣的指標,我們在線下模擬狀況時,才會知道要怎麼訂以符合實際標準)
  3. 線下的指標是否能夠反映線上的指標呢?應該怎麼做去讓線下指標和線上指標盡量成正比?

a. Online Metrics:

這個階段,我們會定義上線之後要觀測的線上指標,並且跟 PM 有很多的來回跟上線後的再修正,探討各個數值對產品的意義,是重要的前置步驟。選定觀測的指標會分為主要指標、次要目標及健康指標:

  • 主要指標:主要指標通常較單純,是我們在解機器學習問題時最主要優化的指標。以 CTR prediction 為例,CTR 就是主要指標。一般在建立模型前所設的 objective 沒辦法很直接的連接到主要指標,像 CTR 是看點擊及曝光的次數,但在 modeling 時我們判定的則是有點和沒點,嚴格來說只是預測點擊的機率,而不是預測最終這個文章或一組人的 CTR,我們只能盡可能地提高點擊機率。
  • 次要目標:如題,是我們第二關心的點。

更進一步說明如何分辨主要以及次要指標,我們用前面把推薦問題轉為 CTR 最佳化問題為例:假設做分類問題時,我們會觀測 CTR 作為主要指標,但為了保持好的使用者體驗,我們不希望因為增加點擊率而造成用戶瀏覽時有負面觀感,造成大家不想上來 Dcard,在算法上線後我們會觀測文章檢舉量或是 DAM 是否受影響,來當作次要指標。

需要主要指標和次要指標原因除了這些指標對產品是重要的之外(知道上線做得好不好),另外一個也是幫助我們在做 A/B test 的時候幫助我們做分組的檢定以及實驗的數據觀測。由於 Dcard 做實驗是做先驗再實驗的方式(即是在做抽組時做檢定一致性再上線做實驗的),這樣做的話我們就可以確保實驗前 A, B 組的資料基本上分佈會一致,實驗後想要確認的指標有顯著差異的話,就更可以確定做的東西對想要最佳化的指標有幫助。而在抽取實驗樣本時,我們會做統計檢定,先定義一個主要兩個次要。比較的對象 (A/B test 的組別) 的這三個指標在統計檢定上要完全一致,才能拿來做實驗。若大家對這個有興趣的話,日後有機會可以跟大家再開一篇文章介紹,或是看 Etsy 之前介紹做實驗的影片去思考 A/B Testing 實際怎麼做比較好。

除了主要及次要指標,心有餘力的話我們還會觀察健康指標。健康指標與次要指標相似,是跟產品相關的其他指標,他相對來說並不是那麼重要,主要是輔助我們去觀察主要目標的細節項目,他的含義較廣,也可以想成是主要 + 次要以外的指標。例如我們會關心曝光的看板數,給使用者看到的東西夠不夠多元,不要都是某看板或類型的文章。

b. Offline Metrics:

訂定完 online metrics 之後,另外一個需要思考的問題,就是在線下要怎麼去評估一個模型做的好不好?一個好的 offline metric 是可以跟線上的指標成長對得上的,以上面的例子來說,如果 online key metric 訂為 CTR,那好的 offline metric 的定義就是,在 A/B test 上如果實驗組比控制組好,在 offline metric 我們也可以得到一樣的結論,反之亦然。而能夠能夠訂定一個好的 offline metric 的價值,在於他可以加速我們做快速的模型推進。因為每次線上實驗都需要跑好幾天,才能夠收集統計數據來觀察模型對產品指標的影響,假如只能做線上實驗,因為一次能跑的實驗有限,那開發模型跟推進的速度一定會變慢,或是做起來也會很像在瞎猜,因此好的 offline metric 是可以幫助我們很有信心的做模型的開發,以及加速團隊推薦機器學習專案的速度的,以 Dcard 的機器學習團隊來說,2020 年只做幾十個線上模型實驗(把 offline 驗證機制做好之前可能只有十來個),但 2021 年就做了超過 150 個線上模型相關的實驗,絕大的原因就是因為我們對自己的 offline 機制有信心才有辦法讓整個產品運轉跑的這麽快,然後提供更好的使用者體驗。

而在找尋 offline metric 的時候,我們通常會先根據產品情境 & 想觀測的指標出發,去思考有哪些既有的 offline metrics 可以用,或是應該怎麼自己設計一個 metric 來符合我們想要的需求,然後先做一些簡易的模型,會實際上線做 A/B test 去觀察,以圖一的推薦系統為例,我們會去思考在看這個推薦區塊的時候,可能需要考慮的因素有哪些,像是:

  • 排列的順序有沒有差異,在圖一裡面,通常看起來整個區塊會一起出現,可以假設一次區塊的曝光跟點擊是等價的,沒有越上面越好的問題
  • 但一次只有六個曝光機會,表示模型最終出來的前六名可能很重要

根據上面的觀察,我們可能可以考慮的指標有:

  • precision@k (k=6)
  • MRR@k (k=6)
  • MAP@k (k=6)
  • NDCG@k (k=6)
  • AUC

而因為我們剛剛討論到同一次的曝光是等價的,以 MRR / MAP / NDCG 都是排序類的指標來說,也許就不適合用在當前的評估裡面,而 AUC 通常是看 overall ranking 的狀態,比較沒有考慮到位置的資訊在裡面,所以如果在這個情境下,也許比較適合拿來衡量的指標是 precision@k 這種指標。根據這樣的推論跟觀察之後,我們再去作線上實驗去對齊看看我們的 offline metric 設計跟 online metric 是否是吻合的。但如上所說,有些時候傳統的 offline metrics 也很難實際對應到線上的結果,這時候我們就會自己設計一些 offline 的指標,幫助我們在訓練時可以更貼近線上的使用者。

Step 4. 設計 Dataset

在討論完指標的設計之後,另外一個重要的議題就是如何設計你的 dataset,這點在驗證線下指標和線上指標變化是否一致的時候,扮演相當重要的角色。如果沒有設計好 dataset 的話,基本上線下的指標是沒有辦法跟線上掛勾到的,因為線下的指標都是拿 dataset 來做模擬。這一點在一般公開資料中或是比賽裡是比較少討論到的,以 Kaggle 為例,Kaggle 上都是做好的 dataset,較少需要參賽者或是使用者設計整個資料集的機會。但 dataset 設計得好的話才有機會讓模型對產品發揮正面的影響力,完美反應線上結果。

在設計 dataset 的內容時,我們分別會定義 4 個部分:

1. 定義資料母體
2. 定義一筆資料
3. 定義 label
4. 設計 train / eval / test dataset

1. 定義資料母體:

如果將所有的相關資料都當作資料母體,很容易會產生雜訊,因此根據專案的需求,我們只將需要的資料納入母體。例如起初在做相似文章推薦時,最經典的思考是我們需要將哪些資料納入資料集?一開始最直覺的想法是把全站的曝光跟點擊當作訓練資料,但經修正後,我們只拿相似文章推薦版位的資料來當作資料母體,才能夠比較忠實反映到時候在產品效果的好壞。以一篇文章來說,他可能會曝光在很多地方(例如在看板內可能會有同樣一篇文章的曝光),如果我們把在每個地方的曝光跟點擊納入資料集的設計,那可能對模型有很大的偏差(因為收的資料不是那個版位的資料),做出來的模型無法直接反映在線上的實驗裡面,就會造成線上實驗及線下實驗有所誤差。而在切分 train / eval / test dataset 的時候基本上會根據資料母體來做切分,因此定義資料母體的好壞,會大幅影響測試資料集跟整體專案的成效以及迭代速度。

2. 定義一筆資料:

在思考完資料母體定義之後,接著我們會去想像要怎麼定義一筆資料來做 train / test。我們自己的做法會從想要分析的主體或指標出發,思考訓練模型需要的資料點樣貌,例如推薦系統主要衡量的基礎會是 <user, item, rating> ,確定這個主軸之後再延伸一些好分析的維度參進這個 dataset 裡面 (例如平台或是時間),但延伸的維度不應該太多,因為他比較像是一個驗證的基礎,舉例來說:像在圖一是我們會想評估這個人有沒有點這篇文章,所以基本上可能只有 <user, item, is_click>,但可能日期不同會影響我們算分的正確性,所以會加上日期這個維度當作一筆資料的基礎單元,最終變成 <user, item, is_click, date>。

在這一步我們要思考的是需要篩選出資料的條件,而不是思考篩選出的資料要有什麼樣的特性,因此不會先去考慮需要用什麼樣子的 feature。常見的錯誤在是定義一筆資料時,會把 feature 混在一起作為一筆資料的定義,但因爲 feature 內容較為複雜,如果在這邊已經開始把 feature 思考進去了,蠻容易在拉取資料的時候就下了一些奇怪的處理,把本應在 dataset 裡面的資料濾掉,或是有意外的資料產生,造成模型的資料集跟真正的資料集不一樣,進而造成後續的線上線下實驗不對齊的狀況。因此定義一筆資料時,建議不要將 feature 那納入考慮,避免造成混亂。

3. 定義 label:

思考了這麼多,接下來需要思考的是 Label 的定義。在實務中,反覆思考 label 的定義能幫助得出更好的 dataset,幫助產品演進。以 CTR prediction 為例,我們需要思考正例跟負例的定義是什麼?為了方便思考,我們會把自己或同事們當使用者,想像什麼行為會歸類為正例或負例,像是使用者喜歡一篇文章就是正例,相反地覺得文章不怎麼樣就是負例。

當然,正例跟負例的定義會根據線上實驗的結果而有所改變,如果結果和我們想像有很大的差距,除了改變母體或是一筆資料的定義,我們也會去修正 label 的定義,而藉由修正定義也有機會提升我們的線上指標。舉例來說:推薦 Netflix 的電影,如果只考慮點擊而不考慮看了多久的話,可能會推很多看起來很吸引人但點進去很爛的爛片,導致於使用者體驗不好。或是以新聞推薦來說,如果沒有考慮大家按讚或是更深層的互動行為,只單純看有沒有點擊的話,是很容易推薦到標題跟殺人相關的文章,長期下來反而對使用者體驗是一種傷害。

4. 設計 train / eval / test dataset

思考了上面這麼多的問題之後,接下來應該就是比較經典的 — 怎麼去切分 train / eval / test 的資料集了。這些資料集的切分大多是需要一些經驗來決定的,以在學校或是線上的課程來說,大多會切 70 / 10 / 20 的比例。但實務上我們可能要注意的有幾個點:

  • 時間是不是需要切分的一個維度?舉例來說像是 youtube 推薦系統,他需要去猜測你未來可能會想看什麼影片,如果在 training data 裡面沒有把未來時間點的資料包含在內的話,有可能會有 data leakage 的問題產生,因此建議在切分資料集的同時,也考慮到這個問題。
  • test dataset 必須要盡量維持不變。因爲 test dataset 的表現,是最終衡量一個算法好不好的方式,所以一旦 test 變了就會失去比較基準,也就不會知道上線後 online 跟 offline 結果是否一致,需要重新做驗證。一般來說,好的 test dataset 設計要能和 online 表現對齊,也表示這組 dataset 有鑑別力。
  • 在 train dataset 的設計上我們會做客製化的調整,嘗試在 test dataset / online 上取得好成績。像是根據不同 sampling 的方法,我們可以挑出的樣本數可能會不同,或是只照顧到某特定族群的人。比如說我們可以選擇先把要訓練的資料挑出,再挑選哪些曝光或點擊要納入 train dataset;或是直接從 1000 筆資料中隨機挑出 500 筆資料,兩者所挑出的 train dataset 數量就會不同。

Step 5. 決定 Baseline Algorithm

Baseline 是比較基準,也是指較適合現在的做法,或是公認標準的做法。基本上產品的資料就能當作是目前算法的 baseline ,以圖一的例子來說,我們可以知道現在線上的做法大概點擊率或是 offline metric 是多少,然後去跟目前的做法比較。Baseline 會不斷改變,每次經過不同模型的計算和實驗之後,成效最好的模型結果會更替為新的 baseline,之後再繼續發展其他模型。藉由不斷迭代 baseline 做比較讓整個機器學習的產品越來越好。

而在初期做第一版的演算法時,會找一些簡單的作法先來確定成效的低標,像是我們可以藉由簡單的分析產生一個單純的 rule-based model,可以做 offline metrics 和 online metrics 的驗證比較,也可以快速得到一些算法方向的驗證。而後續在迭代 baseline 的過程中,無論是哪種算法,都要可以在 test dataset 上得到比較基準,也要能夠直接算出一個分數,用這個分數去做比較,才能讓整個模型迭代的速度更加順暢。

Step 6. 迭代模型

做完前面的思考後,就可以開始做實作以及迭代,做大量的實驗跟分析進行演進。進行線下實驗時,我們會訂一個 guideline,決定是否做線上實驗。舉例而言,如果 offline performance 能達到標準以上,我們就會考慮進行 online 實驗。而後續實作的細節或是之後會遇到的問題我們會在別篇文章討論。

小結

以上是 Dcard 這邊在開始一個機器學習專案或是思考一個需求時所會經過的過程,這些過程幫助我們讓機器學習或是資料科學的能力優化使用者體驗以及讓產品取得更好的成果,創造實質上的 impact。我們大概花了兩年的時間把專案運行的過程調整到文章裡分享,希望可以跟大家一起分享也請大家指教~

另外想工商一下 XD,Dcard 機器學習團隊也在徵才中~我們團隊目前專注在以下幾個領域(推薦, 推播, 搜尋, 廣告, Data infrastructure),如果你對我們在做的事情有興趣的話,歡迎找我們聊聊或是直接投遞職缺!

Machine Learning Engineer — https://dcard.link/y8BfU1

Machine Learning Engineer, Advertising — https://dcard.link/IjIoR0

Machine Learning Backend Engineer — https://dcard.link/BCFJ8y

Machine Learning Engineer, Search — https://dcard.link/xaynlA

Junior Machine Learning Engineer — https://dcard.link/4BDFZ6

Data Engineer, Advertising — https://dcard.link/S7XrNU

--

--