【Kaggle】2021 Shopee商品分類競賽 Part4:如何挑選閾值(threshold) !?

倢愷 Oscar
May 20, 2021

--

這是Shopee的商品分類競賽系列分析文的第四篇,如果還沒看前3篇的話推薦先回去補足基礎知識。part1part2part3

這篇講一個比較小但是很有用的主題,也就是從前面不論是part1的baseline還是part3的arcface,我們在train完model後都有一件事情要做,決定多近的距離要當成同一個商品

所有的分類問題我們最終都必定要調閾值(threshold)

這篇文章我會介紹調整threshold的重點1. 基礎threshold調整方法
2. Cross Validation的準確性
3. 多models混和調整方法

基礎threshold調整方法

說到調整threshold,我想大家其實最最直覺會想到的方法,或是會做的方法,就是直接依照Score來挑選。

問題是要用什麼Score來挑?

很多人用卻最糟糕的1個方法,就是用Test Score來挑,以這次的Shopee比賽,就是先設定多種threshold,每一種都submit一個結果,然後用Public Leaderboard分數來挑選。

如果使用的是這個方法我非常推薦回去補林軒田老師的課程

直接使用Test Score來挑基本上絕對會導致我們overfit,只是這個是overfit在test score上,所以看起來很漂亮,但是實際系統上線時運行的結果通常會偏爛,以Kaggle而言就是private leaderboard會很差。

因此我們挑選threshold就像是挑選hyperparameters一樣,要使用Validation Score來挑選。

Cross Validation的準確性

既然說要用到Validation Score,那最直覺的就會是使用Cross Validation,當然有些情況會用3-fold split、4-fold split(為甚麼會切4份,可以參考這篇),但是在這篇我就專注講解Cross Validation(CV)。

當我們想要使用CV score來挑選threshold或是hyperparameters的時候,我們最重要的就是希望CV score跟test score有一致性。

在part1中我有稍微解釋這點,如果我們的CV score跟public leaderboard score呈現下面的趨勢的話(橫軸是不同model,縱軸是分數),那我們基本上用CV Score挑出來的model,在leaderboard(Testing)上大概率表現不會好。

那上圖有可能是來自於什麼問題?

那就是 Validation / Test Distribution Mismatch!!!

也就是說我們的Validation data的性質跟Test data的性質不同。

常見來說,這有2種可能的問題

  1. CV split data方法出錯
  2. Train — test data本來就不一致

第二個問題很難解,尤其在Kaggle的時候我們更多是看出第二個問題,然後提醒自己不要overfitting而已。

第一個問題稍微比較好解一點,我們就是要讓我們split data的方法跟train/test split的方法盡量一致。

除了一般的CV方法以外,我另外介紹3個

1. Stratified Kfold

Stratified Kfold

Stratified Kfold的目的是讓每一個class的data,平均分配在各個fold裡面。
簡單來說,如果我們Class A有30筆、B有70筆、C有50筆,然後我們要分成5個fold,那Stratified就會讓我們每一個fold裡面都包含著6筆A、14筆B、10筆C的資料。

Stratified Kfold最常使用的場景就是class imbalanced很嚴重的時候,讓我們imbalanced的狀況平均出現在各個fold裡面。

2. GroupKfold

GroupKfold

GroupKfold的目的是讓特定性質的data在同一個Fold裡面,這裡的Group是我們自定義的。

GroupKfold最常使用的場景是在我們「Data之間相似度極高的時候」,我會把相似的Data切到同一個Group裡面。如果有兩個非常相似的data A B,而分在不同fold裡面,那就代表每一次training的時候我們A跟B之間一定最少有一個會在train裡面,而這種時候如果另一個在validation裡面,會導致我們算的CV score被高估(相當於我們直接train在Validation set的Data上)

3. TimeSeriesSplit

TimeSeriesSplit

TimeSeriesSplit的目的是讓每一次split裡,training裡面所有data時間序上都比validation裡面所有的data更早。

TimeSeriesSplit的使用場景就在Time series data,這會避免我們的模型學會看未來的資料來預測過去的資料(一樣幾乎等於看到解答)

這次shopee的競賽就很多人用GroupKfold來得到更精準的CV score,來避免自己overfitting。

多models混和調整方法

最後來快速談一下,如果今天有2個模型以上,要怎麼調threshold。

最常見的方法有兩個

  1. 先把兩個model的prediction混合起來,變成一個model再挑threshold。(這裡最常做的就是「平均」多個prediction,或是用各自的validation score來加權,讓表現好的model比較強勢一點)
  2. 兩個model分別挑threshold,再用OR或是AND的邏輯整理多個結果。(如果兩個model之間有任意一個過threshold就當成positive)

這裡提供第三個我很喜歡的方法。

先回頭想第二個方法,第二個方法其實相當於是用下圖來挑選。(兩個商品的圖片的距離在0.3以下 OR 兩個商品的文字距離在0.17以下 就當作positive)

但是如果今天圖片距離在0.35、文字距離在0.22,其實兩者都很靠近threshold,但是我們卻還是會把它當成negative(如下圖)。

這裡更靠近我們直覺的可能是類似下圖的分類法,中間兩者分數「都還OK」的時候,也應該變成positive。

但是這個斜線區間要如何取得?

用兩個model的CV score來畫!!

簡單來講我們兩個model的各種threshold都試試看,然後看每一個「組合threshold」的CV score都記錄下來(如下圖)。

然後再從CV score去挑出比較複雜的組合threshold。

用TFIDF跟ArcFace還有這個方法來挑threshold,實際上可以直接衝到0.75左右,大約2%~3%的排名。

是非常推薦大家使用的方法!!

如果喜歡這篇文章可以幫我多拍手幾次XD,或是對於哪個類型文章有興趣都可以在留言區跟我講~ 後續會以中難度的ML/DS/AI知識為主,以及AI/HCI研究相關知識

參考資料

--

--

倢愷 Oscar

我是倢愷,CTO at TeraThinker an AI Adaptive Learning System Company。AI/HCI研究者,超過100場的ML、DL演講、workshop經驗。主要學習如何將AI落地於業界。 有家教、演講合作,可以email跟我聯絡:axk51013@gmail.com