分類器報告 92% 的準確率,可它漏掉的 8% 全是投訴。準確率把失敗藏起來了。哪個指標能把它露出來?
模型在記住的資料上表現好,並不能證明什麼。評估需要獨立的測試集、明確的正類,以及與錯誤代價比對的指標。準確率只是起點,不是完整報告。 你還會用 F1 綜合精準率和召回率,並檢查分組切片。
留出測試集
在配適或調參之前先劃分樣本。測試集不應影響特徵選擇、縮放或門檻值選擇。資料很小時,應使用多折交叉驗證並報告波動,而不是相信一次幸運劃分。
rows = [("a", 1), ("b", 0), ("c", 1), ("d", 0), ("e", 1)]
cut = 3
train = rows[:cut]
test = rows[cut:]
print(len(train), len(test))
print(test)明確、固定的劃分
統計四種結果
二分類預測會落入真正例、真負例、假正例或假負例。要顯式構造混淆矩陣。類別名稱取決於你把哪一類稱為正類,因此報告裡要寫清楚。
actual = [1, 1, 0, 0]
predicted = [1, 0, 0, 1]
tp = sum(a == 1 and p == 1 for a, p in zip(actual, predicted))
tn = sum(a == 0 and p == 0 for a, p in zip(actual, predicted))
fp = sum(a == 0 and p == 1 for a, p in zip(actual, predicted))
fn = sum(a == 1 and p == 0 for a, p in zip(actual, predicted))
print(tp, tn, fp, fn)四個計數,而不是一個
計算精準率與召回率
精準率問的是預測為正的樣本中有多少正確;召回率問的是真實正例中找到了多少。兩者都可能被退化分類器操縱,因此要同時報告類別比例和判定門檻值。
tp, fp, fn = 8, 2, 4
precision = tp / (tp + fp)
recall = tp / (tp + fn)
print(round(precision, 2))
print(round(recall, 2))兩個不同的問題
警惕不平衡資料上的準確率
如果一百個樣本裡只有五個正例,全部預測為負會得到 95% 準確率,卻一個正例也沒找到。任何亮眼數字都應先與簡單基線比較,並檢查每個類別的結果。
actual = [0] * 95 + [1] * 5
predicted = [0] * 100
accuracy = sum(a == p for a, p in zip(actual, predicted)) / len(actual)
print(round(accuracy, 2))
print(sum(1 for a, p in zip(actual, predicted) if a == 1 and p == 1))高準確率,零召回
F1 平衡精準率與召回率
F1 是精準率和召回率的調和平均。只有兩者都高時 F1 才高,因此當偽陽性和偽陰性都不能忽視時很有用。也要報告組成指標;F1 會掩蓋到底是哪一側失敗。
tp, fp, fn = 8, 2, 4
precision = tp / (tp + fp)
recall = tp / (tp + fn)
f1 = 2 * precision * recall / (precision + recall)
print(round(precision, 2), round(recall, 2), round(f1, 2))一個數字,兩個成分
檢查分組切片,而不只看總分
總體指標看起來尚可時,某個群體可能表現很差。按相關切片分組統計,但每組要有足夠樣本,避免過度解讀雜訊。切片是診斷手段,不是收集不必要個人資料的許可。
rows = [
("new", 1, 1), ("new", 1, 0), ("new", 0, 1),
("returning", 1, 1), ("returning", 0, 0), ("returning", 0, 0),
]
for group in sorted({row[0] for row in rows}):
subset = [row for row in rows if row[0] == group]
correct = sum(actual == predicted for _, actual, predicted in subset)
print(group, correct, "/", len(subset), round(correct / len(subset), 2))切片會藏在漂亮的平平均值裡
本課要點
- 在訓練和調參都沒有使用過的資料上評估。
- 混淆矩陣展示四種可能結果。
- 精準率衡量預測為正的準確程度,召回率衡量正例被找到的比例。
- 類別不平衡時,準確率可能看起來很高。
- 報告分數時同時說明類別比例、門檻值和簡單基線。
- F1 概括精準率與召回率的權衡;分組檢查能暴露隱藏的失敗。
常見錯誤
- 反覆在測試集上調參,直到它不再是測試集。
- 報告準確率卻不說明哪一類是正類。
- 漏掉一個正例代價很高,卻忽略假負例。
- 只報告一個總體準確率,忽視一個雖小但重要的失敗群體。
給定真實和預測的二分類標籤,計算混淆矩陣、準確率、精準率和召回率,並處理除零情況。
動手試試
改改變數、先預測輸出,再執行程式碼。第一次點擊「執行程式碼」時會下載 Python 執行時,可能需要幾秒鐘。
練習本課
12 道題,作答後立即看到解釋。