iPAS AI 應用規劃師 中級 科目三 機器學習技術與應用

KNN 搭配交叉驗證,哪幾組程式碼能正確執行?

原題 47

KNN 連題組第二題:研究人員在對 digits 資料集進行分類時,決定使用 KNN 並搭配交叉驗證來評估模型準確率。他們撰寫了四組不同的程式碼來進行 KNN 訓練與交叉驗證,但不確定哪幾組程式碼能正確執行並輸出準確率。請問哪幾組程式碼能正確使用 KNN 搭配交叉驗證,對 digits 資料集進行訓練並輸出準確率?

程式碼 A:使用 StratifiedKFold(n_splits=5, shuffle=True),scoring="accuracy"
程式碼 B:同 A,但 scoring="f1"
程式碼 C:使用 cv=5(整數),scoring="accuracy"
程式碼 D:同 C,但 scoring="f1"

白話

郵遞區號辨識專案的研究人員要用 KNN 分類手寫數字(digits 資料集,10 個類別:0-9),搭配 5 折交叉驗證評估準確率。他們寫了四組程式碼,兩組用 StratifiedKFold、兩組用整數 cv=5,差別在評估指標:accuracy 或 f1。

問你:四組程式碼中,哪幾組能不出錯地執行並輸出準確率?

點選你的答案。

01 總結

一句話總結

能正確執行的只有程式碼 A 和程式碼 C(使用 scoring="accuracy"):digits 是 10 類別的多分類問題,scoring="f1" 的預設是二元分類用法,對多類別問題會報錯或警告,必須改成 "f1_macro" 或 "f1_weighted" 才能正常執行。

02 情境

先感受問題:f1 指標的「二元預設陷阱」

郵遞區號辨識系統要分辨 0-9 共 10 種數字,這是標準的多分類(multiclass)問題。研究人員用 sklearn 的 cross_val_score 評估 KNN,試了兩種評估指標:accuracy 和 f1。

accuracy 很直觀:答對幾題除以總題數,10 類別也適用。

f1 就有問題了:sklearn 的 cross_val_score 傳入 scoring="f1" 時,預設假設這是「二元分類」問題(只有正例和負例兩類)。一旦偵測到是多類別問題,就會拋出錯誤:「Target is multiclass but average='binary'. Please choose another average setting, one of [None, 'micro', 'macro', 'weighted']。」

程式碼 B 和 D 都是 scoring="f1" 的版本,兩個都會出錯。

03 對照

f1 指標用錯場景,為什麼會出錯?

  1. f1 預設是 average='binary':sklearn 的 f1_score 函數,average 參數預設是 'binary',只適合兩類別(0 和 1)的分類問題。
  2. digits 是 10 類別(0-9):每個樣本的 y 值可以是 0、1、2、...、9,不是二元問題,使用 average='binary' 的 f1 會立刻報錯。
  3. StratifiedKFold 和 cv=5 都是交叉驗證策略,沒有問題:StratifiedKFold 是更精確的版本,確保每折的類別比例一致;cv=5 是整數,sklearn 預設用 StratifiedKFold 處理分類問題,兩者都合法。
  4. 多分類的 f1 需要指定平均方式:scoring="f1_macro"(各類別 f1 取算術平均)或 scoring="f1_weighted"(按類別樣本數加權平均)才能在多分類問題上正確運行。
  5. accuracy 沒有二元/多元的限制:accuracy 是「答對/全部」,對任意類別數的問題都適用,不需要指定平均方式。
04 解法

只有 accuracy 能在多分類上直接用

逐一分析四組程式碼:

  • 程式碼 A(StratifiedKFold + accuracy):兩個設定都正確,能正常執行輸出準確率。
  • 程式碼 B(StratifiedKFold + "f1"):f1 預設 average='binary',digits 是 10 分類,報錯:ValueError。
  • 程式碼 C(cv=5 + accuracy):cv=5 整數在分類問題上等同 StratifiedKFold(5),accuracy 沒問題,能正常執行。
  • 程式碼 D(cv=5 + "f1"):和 B 同樣問題,f1 在多分類上無法使用,報錯。

能正確執行的是 A 和 C,共同特點是都用 scoring="accuracy"。

這就是選項 B 講的:程式碼 A、程式碼 C

技術版:sklearn 的 f1 指標與多分類問題

中級考試大概率會考程式碼跟公式,所以這部分你還是要學。但如果現在學起來很痛苦,可以先跳過,等讀完其他題目回頭再來。

Step 1 純故事版(不出現公式)

想像你要評估一個能辨識 10 種動物的 AI。accuracy 就像「幾題答對除以總題數」,不管有幾種動物都能算。

f1 分數原本是為「二選一」的問題設計的(例如:是不是貓?),它需要明確定義哪個是「正例」哪個是「負例」。如果你有 10 種動物,你得先說清楚「以哪種動物為正例計算 f1」,或者「10 種各算一個 f1 再取平均」。直接說「算 f1」而不指定平均方式,就像問「10 個人的平均身高多少?」但你既不說是算術平均還是加權平均,系統就無法計算。

Step 2 中文 ↔ 程式碼對照
白話說法程式碼
使用 StratifiedKFold,準確率(正確)cv = StratifiedKFold(n_splits=5, shuffle=True)
cross_val_score(model, X, y, cv=cv, scoring="accuracy")
使用整數 cv,準確率(正確)cross_val_score(model, X, y, cv=5, scoring="accuracy")
f1 在多分類(會出錯)scoring="f1" ← ValueError(average='binary' 但是多類別)
多分類 f1 的正確寫法scoring="f1_macro" 或 scoring="f1_weighted"
digits 的類別數len(np.unique(y)) → 10(0-9)
Step 3 符號角色表
scoring="accuracy"
答對比例,適用任何分類問題,不需要指定平均方式
scoring="f1"
預設 average='binary',只適用二元分類,多分類會報 ValueError
scoring="f1_macro"
對每個類別各算 f1,取算術平均,各類別權重相等,適合類別不平衡時關注少數類
scoring="f1_weighted"
按樣本數加權的 f1 平均,多數類影響較大,適合整體效能評估
StratifiedKFold
每折保持類別比例的 K-Fold,cv=整數在分類問題上 sklearn 預設也用 Stratified
Step 4 完整公式對應
f1_macro 的計算:
  對每個類別 c ∈ {0,1,...,9},計算二元 f1_c(以 c 為正例)
  f1_macro = (f1_0 + f1_1 + ... + f1_9) / 10

f1_weighted 的計算:
  f1_weighted = Σ_c (support_c × f1_c) / total_samples
  其中 support_c = 類別 c 的樣本數

程式碼 B 和 D 的錯誤:
  sklearn 內部呼叫 f1_score(y_true, y_pred, average='binary')
  当 y_true 包含 10 個類別時,拋出:
  ValueError: Target is multiclass but average='binary'.
  Please choose another average setting, one of
  [None, 'micro', 'macro', 'samples', 'weighted']

正確的多分類 scoring 字串(不用記全部,記住 f1_macro 和 f1_weighted 最常用):
  "f1_macro" / "f1_weighted" / "f1_micro" / "f1_samples"
Step 5 自我複述
  1. scoring="f1" 在多分類問題上為什麼會出錯?需要改成什麼?
  2. StratifiedKFold 和 cv=整數有什麼差異?什麼時候優先用 StratifiedKFold?
  3. f1_macro 和 f1_weighted 有什麼差異?各適合什麼場景?
  4. 如果把 digits 換成二元分類問題(0 和非 0),scoring="f1" 還會出錯嗎?
  5. cross_val_score 的 scores 陣列代表什麼?為什麼要看 scores.mean() 而不只是 scores[-1]?
05 陷阱

為什麼其他選項是錯的

選項 A 全部四組都正確

字面在說什麼:A、B、C、D 四組程式碼都能正確執行並輸出準確率。

為什麼不對:程式碼 B 和 D 使用 scoring="f1",sklearn 的 f1 預設是 average='binary',不適用於 10 類別的 digits 資料集,執行時會拋出 ValueError。四組全部能跑是錯誤的。

誰會選錯:沒注意到 f1 有「二元/多類別」的限制,以為 f1 是萬用的評估指標,任何分類問題都能用 scoring="f1"。

選項 C 只有 A 和 B(StratifiedKFold 那兩組)

字面在說什麼:使用 StratifiedKFold 的 A 和 B 能跑,cv=5 整數的 C 和 D 不行。

為什麼不對:cv=5 整數在分類問題上,sklearn 預設用 StratifiedKFold(5) 處理,效果等同程式碼 A 的設定(不含 shuffle=True,但功能上完全合法)。選項 C 的問題不在 cv=5,而在 scoring="accuracy" 完全沒問題。選項 D 的問題不在 cv=5,而在 scoring="f1"。

誰會選錯:誤以為 cv=整數是「不精確」或「錯誤」的用法,以為只有明確指定 StratifiedKFold 物件才算「正確」,忽視了 sklearn 會自動把整數 cv 轉換成 Stratified 交叉驗證。

選項 D 只有 C 和 D(cv=5 那兩組)

字面在說什麼:使用 cv=5 整數的 C 和 D 能跑,StratifiedKFold 的 A 和 B 有問題。

為什麼不對:StratifiedKFold 完全合法且是更明確的寫法,程式碼 A 絕對能正確執行。選項 D 裡的程式碼 D(cv=5 + scoring="f1")同樣因為 f1 的多分類問題而出錯,和程式碼 B 一樣。

誰會選錯:誤以為 StratifiedKFold 有什麼問題,或者搞錯了哪組用了什麼 scoring,沒仔細對應每組程式碼的設定。

06 變形

同個考點下次怎麼變形

變形 1 換指標

直覺:如果要在多分類問題上使用 f1,scoring 應該怎麼寫?

答案:使用 scoring="f1_macro"(各類別等權重)或 scoring="f1_weighted"(按樣本數加權)。digits 資料集各類別樣本數相當均衡,兩者結果相近;類別不平衡時差異會很大,選 weighted 較常見。

變形 2 StratifiedKFold vs cv=整數

直覺:明確傳入 StratifiedKFold(shuffle=True) 和直接傳 cv=5,有什麼實質差異?

答案:主要差異是 shuffle 參數。cv=5 整數使用的是 StratifiedKFold(n_splits=5),預設 shuffle=False,折的分配按樣本原始順序。加上 shuffle=True 會先隨機打亂再切折,讓每折的樣本更具代表性,通常比不 shuffle 更穩定。時間序列資料不應 shuffle。

變形 3 precision_recall 的多分類問題

直覺:scoring="precision" 和 scoring="recall" 在多分類問題上也會出錯嗎?

答案:是的,同樣問題。scoring="precision" 和 scoring="recall" 預設都是 average='binary',多分類問題需要改成 "precision_macro" / "precision_weighted" 或 "recall_macro" / "recall_weighted"。記住:任何有 f1/precision/recall 的 scoring 字串,在多分類問題上都需要加上 "_macro" 或 "_weighted"。

變形 4 cross_val_score 的輸出

直覺:cross_val_score 回傳的 scores 陣列和 scores.mean() 各代表什麼?

答案:scores 是每一折的評估結果(5 折就有 5 個值),代表模型在不同子集上的效能。scores.mean() 是 5 折的平均效能,是最終報告的標準指標。scores.std() 代表模型穩定性,std 小代表效能穩定,std 大代表對資料分布敏感,可能過擬合。

變形 5 KNN 超參數

直覺:KNeighborsClassifier(n_neighbors=3) 的 n_neighbors 怎麼選最合適?

答案:通常用網格搜尋(GridSearchCV)或交叉驗證掃描多個 n_neighbors 值,選出在驗證集上準確率最高的 K。經驗法則:K = sqrt(n_samples),digits 資料集 1797 筆,K ≈ 42,但實際上小的 K(3-10)也常表現不錯。奇數 K 可避免二元分類時的平票。

07 延伸

想再往下看,這 5 個

  • K 近鄰(KNN)本題主角,透過計算測試點與訓練集的距離、取最近 K 個鄰居投票決定類別,不需要訓練階段。
  • 交叉驗證(Cross-Validation)本題使用的評估框架,StratifiedKFold 和 cv=整數都是實現方式,確保評估結果穩定可靠。
  • F1 分數(F1 Score)本題的核心陷阱,多分類問題必須指定 average 參數(macro/weighted),直接用 scoring="f1" 在多類別上會報錯。
  • 準確率(Accuracy)不受分類數量限制的通用指標,是本題中唯一能直接在多分類問題上使用的 scoring 選項。
  • 資料不平衡(Data Imbalance)理解 f1_macro 和 f1_weighted 差異的關鍵概念,類別不平衡時兩者差異顯著,需要根據目的選擇。
出處

iPAS 經濟部產業人才能力鑑定 ・ 114 年第二梯次 iPAS AI 應用規劃師 中級 科目三 機器學習技術與應用 第 47 題

查看官方原文 PDF