Classification 與 Threshold
學習目標:理解機率分數、threshold、confusion matrix、precision、recall、specificity。
分類模型輸出的不是「是」或「否」,而是一個 0 到 1 之間的機率分數。要把它變成一個可以行動的決策,還需要選一個 threshold:分數高於這個門檻就判定為「將超過容量門檻」。改變 threshold 不會改變模型本身,卻會大幅改變 precision 與 recall 之間的取捨。
| 預測 \ 實際 | 實際為超過門檻 | 實際為未超過門檻 |
|---|---|---|
| 預測為超過門檻 | True Positive(抓到) | False Positive(誤報) |
| 預測為未超過門檻 | False Negative(漏抓) | True Negative(正確排除) |
from sklearn.metrics import precision_score, recall_score
proba = model_clf.predict_proba(valid[feature_cols])[:, 1]
for threshold in [0.3, 0.5, 0.7]:
pred = (proba >= threshold).astype(int)
precision = precision_score(valid["target_binary"], pred)
recall = recall_score(valid["target_binary"], pred)
print(threshold, round(precision, 3), round(recall, 3))選擇 threshold 之前,先把兩種錯誤的實際成本寫下來:漏抓一個真的會超過容量的據點,可能代表服務品質下降或緊急調度成本;誤報一個其實還好的據點,則是浪費了提前調度的資源。把這兩個成本量化後,threshold 的選擇就從「感覺」變成可以被檢視的決策。
Precision(精確率)
- 問的是:被模型判為超過門檻的案例中,有多少真的超過門檻
- threshold 拉高,precision 通常上升
- 重視「不要誤報」的情境優先看這個指標
Recall(召回率)
- 問的是:所有真的超過門檻的案例中,有多少被模型抓到
- threshold 拉低,recall 通常上升
- 重視「不能漏抓」的情境優先看這個指標
假設漏抓一次的代價是臨時調度的加班成本,估計約為誤報一次成本的三倍。這種情況下,團隊通常會選擇較低的 threshold,犧牲一些 precision 來換取更高的 recall,因為漏抓的代價明顯更高。這個選擇必須寫進部署文件,並說明背後的成本假設。
- 選 threshold 時只看哪個數字「看起來順」,沒有對照實際的業務成本
- 用同一個 threshold 套用到所有據點,卻沒有檢查不同據點的成本結構是否一樣
- 只報告 accuracy,沒有同時報告在選定 threshold 下的 precision 與 recall
- threshold 選定後沒有重新檢查在各 group_attribute 子群上是否公平
注意
把分類 threshold 從 0.5 調低到 0.3,最可能觀察到什麼變化?