本系列第 12 篇|這篇回答:機器學習怎麼從資料學到規律?哪些步驟最容易讓評估分數失真? 讀完這篇,你應該能:
- 畫出從切分、訓練、驗證到上線監控的機器學習流程,並說出每一步可以用哪些資訊
- 從情境裡找出資料洩漏與不當驗證,包含切分前的前處理、目標洩漏、時間洩漏,以及同一人跨在訓練與測試兩邊
- 面對不平衡資料時換指標、把重採樣放在正確的位置,並說明特徵儲存庫與漂移監控各自防哪一種上線失敗
一、大數據是機器學習的燃料,也是陷阱來源
模型學到的內容,同時取決於資料裡有什麼,以及訓練步驟被允許看到什麼。資料夠,規律才有機會被學到;資料裡若混進預測當下還沒有的資訊,驗證分數會偏高,上線就對不上。
學習類型
有現成標籤、沒有標籤、靠環境獎勵或自造標籤,學習類型各不相同。
詳細說明
標籤從哪裡來,決定學習類型。
監督式學習(supervised learning)使用現成標籤。預測類別是分類(classification),預測數值是迴歸(regression)。每一筆歷史都已經有答案,才有辦法算預測與答案的差距。
非監督式學習(unsupervised learning)沒有標籤。工作是分群(clustering)或降維(dimensionality reduction):把相似的觀測放在一起,或把很多欄位壓成較少的表示。
強化學習(reinforcement learning)的學習訊號來自環境。學習者採取行動,環境狀態隨之改變,再依獎勵(reward)調整之後的行動。學習紀錄包含獎懲與互動時,學習類型就是這一種。
自監督學習(self-supervised learning)的標籤從資料本身造出來。做法例如把句子裡的字詞遮住,再預測被遮住的部分。大型語言模型的預訓練也屬這一類:用前文預測下一個詞,答案直接來自原文。
三個子集
會估計統計量或做特徵選擇的步驟,只能在切分後對訓練側擬合。
詳細說明
監督式流程把歷史資料分成三份,三份的工作固定。
訓練集(training set)學參數,讓模型在這些筆上的擬合變好。
驗證集(validation set)調超參數(hyperparameter)、比較模型。設定可以更換,驗證表現也可以再看。
測試集(test set)只在最後用一次,估計上線表現。它不參加選模型。看過測試分數又回頭改模型,這一份就轉去承擔驗證的工作,那個數字不再是未參與選擇的估計。
因此,任何會從資料估計統計量或挑選欄位的前處理、特徵選擇,都要放在切分之後,而且只對訓練側擬合。切分前對全體做,測試集就參加了這些估計。
兩種擬合失敗
訓練遠好於驗證表示變異偏高,兩邊都不好表示偏差偏高。
詳細說明
過擬合(overfitting):訓練表現好、驗證表現差。模型把訓練集裡的雜訊也記進去,換一批資料就對不上。
欠擬合(underfitting):訓練與驗證都差。模型太簡單,訓練集裡的規律也沒有抓到。
中間是偏差(bias)與變異(variance)的權衡。模型越複雜,偏差下降、變異上升:它較能跟上彎曲的關係,也較會跟著手邊這一小批樣本搖。模型越簡單,偏差較高、變異較低。訓練遠好於驗證,表示變異已經偏高;兩邊都不好,表示偏差仍然偏高。
資料洩漏從哪進來
訓練用到預測當下拿不到的資訊,測試分數就會偏樂觀。
詳細說明
資料洩漏(data leakage)指訓練時用到預測當下拿不到的資訊。測試分數會偏樂觀,上線沒有那些資訊,表現就下滑。
切分前做前處理或特徵選擇。統計量與被選中的欄位若看過測試集,測試集就參與了訓練用的設定。
切分前做 SMOTE 這類過採樣。合成樣本來自少數類樣本與其鄰居的內插;鄰居後來若落在測試集,合成樣本就與測試筆相關。
目標洩漏(target leakage):特徵其實是結果的後果。用「是否已退款」預測「是否退貨」時,退款多半出現在退貨決定之後,下單當下還沒有這個欄位。
時間洩漏(temporal leakage):用未來資料預測過去或預測當下。本週之後才發生的交易,不能拿來預測本週的違約。
同一個人的多筆資料同時出現在訓練與測試。病患、顧客都是。模型可以記住「這個人」,測試就估不到「下一個沒見過的人」。
二、切分、重採樣、特徵與上線監控
減輕過擬合
過擬合時要讓模型較難記住訓練雜訊,加特徵或加輪數通常讓過擬合更嚴重。
詳細說明
訓練遠好於驗證時,過擬合已經發生,變異偏高。改善的方向是讓模型較難記住訓練雜訊。
增加資料量之後,只存在於少數訓練筆的雜訊較難被當成穩定規律。資料擴增(data augmentation)對影像做翻轉、旋轉,標籤維持不變,畫面變化變多。正則化(regularization)的 L1、L2 懲罰過大的權重:L1 較會把一部分權重壓到零,L2 較會讓權重的平方和變小。提早停止(early stopping)在驗證表現不再變好時停下,其後只討好訓練集的輪次就不會留下。Dropout 在訓練時隨機關掉一部分單元,模型較難靠單一路徑記住特定訓練筆。減少特徵、改用較簡單的模型,直接把容量降低。交叉驗證(cross-validation)用來選超參數,選擇過程不使用測試集。
增加更多特徵,或延長訓練輪數,通常會讓過擬合更嚴重。容量變大,反覆看訓練集的次數變多,記住雜訊的機會也變多。
折怎麼切
類別比例差用分層,沒見過的人用群組,時間序列只用過去預測未來。
詳細說明
K-fold 把資料分成 K 份,輪流以其中一份當驗證集、其餘當訓練集,再綜合 K 次的驗證表現。
類別比例差很多時用分層 K-fold(Stratified K-fold)。每一折的類別比例與整體相同,驗證分數才不會因為某一折幾乎沒有少數類而跳動。
評估對象是沒見過的人時用群組 K-fold(GroupKFold)。同一群組,例如同一位病患、同一位使用者,只出現在同一側。以「筆」為單位隨機切開,守不住這件事。
時間序列用 TimeSeriesSplit。驗證段在訓練段之後,只用過去預測未來。
少數類很少的時候
全猜正常也有 99.5% 準確率,少數類卻可以一筆都沒抓到。
詳細說明
全體準確率在不平衡時會誤導。正常個案佔 99.5% 時,全部猜正常,準確率也是 99.5%,少數類可以一筆都沒抓到。
改看精確率(precision)、召回率(recall)、F1 與 PR 曲線(precision-recall curve)下面積。精確率是判成正例的筆數之中,真正屬於正例的比例。召回率是真正的正例之中,被抓到的比例。兩者合成為 F1 = 2 × 精確率 × 召回率 / (精確率 + 召回率)。PR 曲線以召回率與精確率為兩軸,曲線下面積把不同門檻下的取捨收成一個數。
類別權重(class weight)讓少數類的錯誤在訓練裡佔更重,資料筆數可以維持原樣。欠採樣(undersampling)減少多數類的筆數。過採樣(oversampling)增加少數類。SMOTE 在少數類樣本與其鄰居之間內插,產生合成樣本。重採樣只能做在訓練集,或交叉驗證的訓練折裡面。SMOTE 本身可以用,問題在位置:切分前對全體做就會洩漏。決策門檻(decision threshold)決定模型多容易把一筆判成少數類,從而更換精確率與召回率的組合。門檻若要調,放在驗證階段;用測試集反覆試到分數好看,測試集就參加了選擇。
特徵怎麼共用
共用特徵要與線上同一套計算,並取時間點正確的值。
詳細說明
特徵儲存庫(Feature Store)集中定義、計算、儲存特徵,供多個團隊與多個模型重用。風控與防弊都要「過去 30 天交易行為」時,共用同一段計算。
它對上兩種不一致。訓練/服務不一致(training-serving skew)指訓練用的特徵算法和線上推論不同,上線輸入已經偏離模型學過的數字。時間點正確(point-in-time correct)指取某一天的歷史特徵時,只用該時點之前已經存在的值,從而避開時間洩漏。
MLOps 把實驗到上線做成可重複的過程:實驗追蹤,例如 MLflow 記錄參數、指標與模型檔;模型註冊與版本;自動化訓練與部署;上線監控。監控用來發現漂移。
上線之後什麼在變
偵測到資料漂移或概念漂移,都要重新評估並重新訓練。
詳細說明
資料漂移(data drift)是輸入特徵的分佈改變,例如新客群湧入,金額、時段的分佈與訓練時不同。概念漂移(concept drift)是輸入與標籤的關係改變。特徵分佈可以差不多,同樣的特徵組合所對應的詐欺機率卻變了,因為手法變了。
偵測到其中一種,都要重新評估並重新訓練。
多台機器怎麼拆
資料量很大且模型放得進一台就資料平行,放不下才模型平行。
詳細說明
資料平行(data parallelism):每台機器持有完整模型,各自處理不同資料,再同步梯度。模型放得進一台、資料量很大時,用這種拆法。
模型平行(model parallelism):模型太大,一台放不下,把模型拆到多台機器。拆開的是模型本身。
把切分與 SMOTE 放在對的位置
SMOTE 放在 Pipeline 第一步,每次只送該折的訓練資料。
詳細說明
分層切分要能重現,群組切分要把人留在同一側,時間切分只能由過去預測未來。SMOTE 放在 imblearn.pipeline.Pipeline 的第一步,模型放在後面;交叉驗證每次擬合,只把該折的訓練資料送進 SMOTE。
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import Pipeline
from sklearn.model_selection import GroupKFold, StratifiedKFold, TimeSeriesSplit
stratified = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
grouped = GroupKFold(n_splits=5)
temporal = TimeSeriesSplit(n_splits=5)
# grouped.split(X, y, groups=patient_id): one patient stays on one side.
# temporal.split(X): validation uses a later block; training uses only earlier rows.
def make_resample_pipe(model):
return Pipeline([
("smote", SMOTE()),
("model", model),
])
從資料到上線的順序
先判斷學習類型並切分,測試留到最後,上線後再看兩種漂移。
詳細說明
- 判斷學習類型:現成標籤、沒有標籤、環境獎勵,或從資料自身造標籤。
- 先切分,再做前處理、特徵選擇與重採樣。不平衡用分層,評估新的人用群組,有時間順序用 TimeSeriesSplit。
- 只在訓練集或訓練折上學參數,並在同一範圍內做 SMOTE、欠採樣或類別權重。
- 用驗證表現選模型、決定提早停止,也在這一階段調整決策門檻。測試集留到最後一次。
- 上線特徵走特徵儲存庫,與訓練使用同一套計算,並取時間點正確的值。
- 以實驗追蹤留下參數、指標與模型版本。上線後看資料漂移與概念漂移,發現了就重新評估、重新訓練。
三、容易混淆的地方
實務上常把下表左右兩種方法混在一起。先確認流程要守住的是類別比例、同一個人、時間順序,還是上線後改變的分佈或特徵與標籤間的關係。
| 容易混淆 | 差別在哪 | 實際遇到時的線索 |
|---|---|---|
| 驗證集 vs 測試集 | 驗證集用來調超參數、選模型,可以多次查看;測試集只在最後用一次,估計上線表現 | 評估流程看過測試分數後又改模型,表示測試集已被拿來選模型 |
| 過擬合 vs 欠擬合 | 過擬合是訓練好、驗證差;欠擬合是兩邊都差 | 訓練紀錄顯示 99%、驗證 72% 時是過擬合;兩邊都低才是欠擬合 |
| 資料漂移 vs 概念漂移 | 資料漂移是輸入特徵分佈改變;概念漂移是輸入與標籤的關係改變 | 上線監控若出現新客群湧入、特徵分佈改變,屬資料漂移;分佈變化不大、同樣特徵下的機率改變,屬概念漂移 |
| 分層 K-fold vs 群組 K-fold | 分層維持每折類別比例;群組讓同一人只在同一側 | 驗證需求是讓極少數類別在每折維持接近整體比例時用分層;要評估新病患或新使用者時用群組 |
| SMOTE 在切分前 vs SMOTE 在訓練折內 | 切分前做,合成樣本的鄰居會落到測試集;只在訓練折內做,測試折保持原樣 | 資料流程先對全部資料過採樣再切分,可能出現測試分數高、上線大幅下滑 |
| 資料平行 vs 模型平行 | 資料平行是每台都有完整模型、分不同資料、同步梯度;模型平行是模型太大、拆到多台 | 系統需處理大量資料而模型單台放得下時用資料平行;模型單台放不下時用模型平行 |
四、基礎練習
第 1 題
某銀行的信用卡違約率是 1.6%。分析師拿全部 5 萬筆先做 SMOTE,再切成訓練集與測試集。測試集 AUC 是 0.91,模型上線後表現大幅下滑。這次失敗最合理的解釋是什麼?
- (A) AUC 這個指標本來就不可靠,所以 0.91 不能說明模型好壞
- (B) 測試集太小,把測試集放大後,上線表現就會回到 0.91
- (C) 切分前對全部資料做 SMOTE,合成樣本與測試樣本相關,形成資料洩漏;應先切分,只在訓練集內重採樣
- (D) 模型欠擬合,應改用一個更簡單、故意欠擬合的模型
看答案與解析
答案:C
5 萬筆就是 50000 筆,違約筆數是 50000 × 1.6 ÷ 100 = 800。SMOTE 在這 800 筆與其鄰居之間內插出合成樣本。這一步若做在切分之前,鄰居可以落在後來的測試集,測試 AUC 0.91 是在這種相關之下量到的。上線的新案件沒有這些鄰居,分數就下滑。應先切成訓練集與測試集,只在訓練集內重採樣。
- (A) 情境的落差對上的是合成樣本與測試樣本相關,支持不了「AUC 一律不可靠」。
- (B) 情境沒有給出測試集太小的證據;5 萬筆是被提前做 SMOTE 的全部資料,放大測試集去不掉已經形成的相關。
- (D) 欠擬合是訓練與驗證都差。這裡出現的是切分前重採樣,以及測試分數與上線的落差;換成更簡單的模型仍然留著那層相關。
第 2 題
某支付公司的交易裡,詐欺只佔 2%。團隊要用 5-fold 交叉驗證評估分類模型。哪一種做法對得上這個類別比例?
- (A) 使用一般 K-fold,而且不要打亂,依原始順序切成 5 折
- (B) 改成留一法,因為留一法一定最好
- (C) 只報告訓練集準確率,不必在意每一折的詐欺比例
- (D) 使用分層 K-fold,讓每一折的類別比例都與整體相同
看答案與解析
答案:D
詐欺只佔 2%。某一折的詐欺比例若偏離整體,驗證分數會跟著折跳動,模型本身穩不穩就看不清。分層 K-fold 讓每一折的類別比例相同,5 折都維持接近整體的詐欺比例。
- (A) 這一題要守的是類別比例。一般 K-fold 即使打亂,仍不保證每折都接近 2%;「不要打亂」也不是交叉驗證的要件。
- (B) 留一法沒有處理 2% 這個類別比例,不能當成不平衡時一定最好的切法。
- (C) 詐欺只佔 2% 時,訓練集準確率一樣會被多數類撐高,而且它沒有使用驗證折。
第 3 題
某醫院的資料裡,每位病患有多筆住院紀錄。評估目標是模型對沒見過的新病患表現如何。切分應怎麼做?
- (A) 以住院紀錄為單位隨機切分,讓訓練與測試的筆數都盡量大
- (B) 使用 GroupKFold,以病患為群組,同一位病患只出現在同一側
- (C) 使用分層 K-fold 即可,類別比例正確就完成了對新病患的評估
- (D) 使用 TimeSeriesSplit,同一位病患的紀錄可以同時出現在訓練側與驗證側
看答案與解析
答案:B
新病患指訓練時完全沒出現過的人。GroupKFold 以病患為群組,同一群組只放在同一側,驗證折裡的人在訓練折沒有出現過,估到的才是新病患。
- (A) 隨機逐筆切分會把同一病患的不同住院分到訓練與測試,模型可以記住這個人。
- (C) 分層 K-fold 守的是每折類別比例,同一病患仍可出現在兩邊。
- (D) TimeSeriesSplit 守的是只用過去預測未來;同一病患仍可跨在兩側,回答不了新病患的表現。
第 4 題
某銀行的風控團隊與防弊團隊都需要「過去 30 天交易行為」這組特徵。較合適的做法是哪一個?
- (A) 導入特徵儲存庫,統一定義與計算,供兩邊與多個模型重用,並讓訓練與線上推論使用相同邏輯
- (B) 兩隊各自寫一套特徵程式,保持彈性,上線前再各自核對
- (C) 把算好的特徵存成 Excel,用檔案共享給另一隊
- (D) 用特徵儲存庫取代模型訓練,之後只更新特徵、不再訓練模型
看答案與解析
答案:A
兩邊要的是同一段定義。特徵儲存庫集中定義、計算、儲存,讓多個團隊與模型重用同一套邏輯,訓練與線上推論才對得上,也才能取時間點正確的歷史特徵。
- (B) 各自實作會讓同名特徵算出不同數字,訓練與上線、兩隊之間都會分叉。
- (C) Excel 只交換檔案,沒有統一的計算邏輯,也沒有時間點正確的約束。
- (D) 特徵儲存庫提供特徵,模型仍要在訓練集上學參數,它不取代訓練。
第 5 題
某金流公司遇到詐騙集團改變手法。同一組特徵組合所對應的詐欺機率變了,這些特徵的分佈變化不大。此時最貼近的判斷是什麼?
- (A) 資料漂移:輸入特徵的分佈已經改變
- (B) 過擬合:模型把舊手法的雜訊背下來了
- (C) 概念漂移:輸入與標籤的關係改變,應重新評估並重新訓練
- (D) 資料洩漏:訓練時用了預測當下拿不到的欄位
看答案與解析
答案:C
特徵分佈變化不大,改變的是同樣特徵組合所對應的詐欺機率,也就是輸入與標籤的關係。這是概念漂移。接下來要重新評估並重新訓練。
- (A) 資料漂移指輸入特徵分佈改變,例如新客群湧入;情境寫的是分佈變化不大。
- (B) 過擬合是訓練表現好、驗證表現差,情境描述的是上線後手法與機率關係改變。
- (D) 資料洩漏是訓練時用了預測當下拿不到的資訊,情境沒有這個訓練程序。
第 6 題
某服飾電商同時用商品影像與訂單資料預測退貨。目前訓練集準確率 99%,驗證集準確率 72%。下列何者最無法改善這種過擬合?
- (A) 對商品影像做翻轉、旋轉等資料擴增
- (B) 加入 L1 或 L2 正則化
- (C) 依驗證表現做提早停止
- (D) 再加入大量新特徵,並延長訓練輪數
看答案與解析
答案:D
99 − 72 = 27,驗證比訓練低 27 個百分點:訓練好、驗證差,符合過擬合。再加入大量新特徵並延長訓練輪數,容量與看訓練集的次數都增加,通常會讓過擬合更嚴重,所以這一項最無法改善。
- (A) 影像翻轉、旋轉是資料擴增,用來增加畫面變化、減輕過擬合。
- (B) L1 或 L2 正則化懲罰過大的權重,用來限制擬合。
- (C) 提早停止在驗證表現不再變好時停下,避免後續輪次繼續記住訓練集。
五、重點回顧
- 監督式學習使用現成標籤,做分類或迴歸;非監督式學習沒有標籤,做分群或降維;強化學習的訊號是環境給的獎勵;自監督學習從資料自身造標籤,遮住字詞再預測、以及大型語言模型預訓練,都屬這一類。
- 訓練集學參數,驗證集可以多次用來調超參數與選模型,測試集只在最後用一次以估計上線表現;會看全體資料的前處理與特徵選擇放在切分之後。
- 訓練好、驗證差是過擬合,兩邊都差是欠擬合;模型越複雜,偏差越低、變異越高。加特徵或拉長訓練通常加重過擬合;資料擴增、L1/L2、提早停止、Dropout、減少特徵與簡化模型用來減輕它。
- 正常佔 99.5% 時,全部猜正常也有 99.5% 的準確率。不平衡時改看精確率、召回率、F1 與 PR 曲線下面積;類別權重、欠採樣、SMOTE 與決策門檻可以處理,SMOTE 只做在訓練集或訓練折內。
- 分層 K-fold 守每折類別比例,群組 K-fold 守同一病患或使用者只在同一側,TimeSeriesSplit 守只用過去預測未來。
- 特徵儲存庫統一特徵計算,避開訓練/服務不一致,並提供時間點正確的歷史特徵。輸入分佈改變是資料漂移,輸入與標籤的關係改變是概念漂移;偵測到之後要重新評估與重新訓練。