基礎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種可能的問題
- CV split data方法出錯
- Train — test data本來就不一致
第二個問題很難解,尤其在Kaggle的時候我們更多是看出第二個問題,然後提醒自己不要overfitting而已。
第一個問題稍微比較好解一點,我們就是要讓我們split data的方法跟train/test split的方法盡量一致。
除了一般的CV方法以外,我另外介紹3個
1. 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的目的是讓特定性質的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的目的是讓每一次split裡,training裡面所有data時間序上都比validation裡面所有的data更早。
TimeSeriesSplit的使用場景就在Time series data,這會避免我們的模型學會看未來的資料來預測過去的資料(一樣幾乎等於看到解答)
這次shopee的競賽就很多人用GroupKfold來得到更精準的CV score,來避免自己overfitting。
多models混和調整方法
最後來快速談一下,如果今天有2個模型以上,要怎麼調threshold。
最常見的方法有兩個
- 先把兩個model的prediction混合起來,變成一個model再挑threshold。(這裡最常做的就是「平均」多個prediction,或是用各自的validation score來加權,讓表現好的model比較強勢一點)
- 兩個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研究相關知識