L3.2 從一百個學生裡挑最好的,他下次會考得更好嗎?
本篇重用M5.0保險為什麼存在:Convex Function 與 Jensen 不等式
起點:從一百個學生裡挑第一名
一百個學生考同一份試卷。你挑出考最高分的那一個,派他去比賽。
他在比賽時會考得比這次好,還是比這次差?
如果一百個學生的實力其實完全一樣,答案很清楚:這次的第一名純粹是那天運氣最好的那個,而運氣不會重現,所以他在比賽時會退回平均。你挑出來的那個「最好」的分數,是實力加上一次特別好的運氣。
麻煩的是,真實情況介於兩者之間:學生有實力差距,也有運氣成分。挑出來的那個第一名,同時是「實力比較好」與「運氣比較好」的混合,而你沒辦法從那張成績單上分開這兩件事。
這正是超參數搜尋結束時的處境。同樣試一百次:排成格子,還是隨便丟? 教你怎麼搜,搜完你有 組設定與 個驗證分數,挑了最低的那個。那個分數可以拿來報告嗎?
挑出來的那一個,分數裡有多少是實力、多少是運氣?
這兩件事分得開嗎?
如果分不開,那個數字還能報告嗎?
課堂提問Q1
把「挑最好的」翻成數學。為什麼「挑出來的那個的分數」是有偏的,而且偏的方向固定?如果候選之間的真實品質完全相同,那個偏差會是多少——它從哪裡來?
先想一想,再展開看整理後的答案
寫下來。 候選 ,每個的真實風險是 ,驗證分數是 。每一個分數各自是無偏的:。
我們挑 ,然後想用 當成績。
取最小值不是無偏的。 是一個凹函數,所以由 Jensen(保險為什麼存在:Convex Function 與 Jensen 不等式)
不等號的方向是固定的——回報的數字在期望上不高於候選中最好的真實風險。這不是「有時偏高有時偏低」,是一個系統性的往下漂。
候選品質完全相同時,偏差是純粹的選擇偏差。 設 ,每個分數是 , 是均值為零、標準差 的估計誤差。那麼
(最後一步是 個獨立同分布的最小值的標準漸近式。)兩件事要記住:偏差隨 成長(所以候選從 5 個變 400 個,偏差只成長約兩倍,不是八十倍),而且它正比於 ——驗證集越小、估計越抖,同樣的 偏得越多。
而這時 :你挑出來的那個,真實品質和其他所有候選一模一樣。回報的數字變好看了,拿到的模型完全沒有變好。 下一節把這個極端情形做成一個實驗。
把「實力」拿掉,只留「運氣」
要把選擇偏差量乾淨,最好的辦法是讓候選之間沒有實力差距。這樣任何看起來的「贏」都只能來自運氣,偏差就被孤立出來了。
做法: 個候選都是同一個 degree 的多項式擬合,差別只在它們各自看到一份不同的訓練資料。它們在期望上品質相同(同一個演算法、同樣的樣本數),但實際的分數會不同。所有候選共用同一份驗證集(),挑最低的那一個。重複 300 次取中位數:
m n_val 勝出者的驗證分數 勝出者的真實風險 全體平均真實風險 樂觀量
1 30 0.0256 0.0261 0.0261 0.0004
5 30 0.0225 0.0251 0.0273 0.0025
20 30 0.0206 0.0251 0.0277 0.0046
100 30 0.0187 0.0257 0.0280 0.0070
400 30 0.0185 0.0260 0.0283 0.0075
三欄一起讀才看得出重點。
第一欄(回報的數字)一路變好:, 從 1 到 400 「改善」了 。
第二欄(勝出者真正的風險)紋風不動:、、、、——在抖動範圍內完全平坦。
你比較得越多,回報的數字越好看,而你拿到的模型沒有變好。
那一列是對照組:不選擇時樂觀量只有 ,實質為零。這確認了偏差確實來自「選」這個動作,不是實驗設計的某個瑕疵。
樂觀量的成長符合 : 從 5 到 400 是 80 倍,,而實測的樂觀量從 到 是 3 倍——同一個數量級(實測略高,因為候選之間有相關,不完全獨立)。
第三欄還有一個附帶的觀察:全體平均的真實風險隨 略微上升()。那不是選擇造成的,是這個實驗裡候選數變多時我用了更多不同的訓練子集,抽到較差子集的機會跟著變多——一個提醒:讀這種表時要確認每一欄各自在測什麼。
修法:把「選擇」也包進流程裡
偏差的來源是「用同一份資料做選擇又做評估」。修法因此只有一個形狀:找一份沒有參與選擇的資料來評估。
最簡單的版本是三份切分(老師用考古題教學又出題:為什麼要切資料 已經講過):訓練選權重、驗證選超參數、測試只讀一次。這在資料夠多時就夠了。
資料不夠時要用巢狀驗證(nested cross-validation)。 關鍵在於認清一件事:
「挑超參數」是訓練流程的一部分,不是訓練之前的準備工作。
一旦這樣看,做法就自動出來了——把整個「訓練 + 挑超參數」當成一個演算法 ,然後對 做交叉驗證:
外層 K 折:
把第 k 折留出來當「測試折」
在剩下的 K−1 折裡:
內層 CV:挑超參數(這一步完全看不到測試折)
用選出的超參數在那 K−1 折上重訓
在測試折上評估 ← 這個分數沒有參與過任何選擇
把 K 個外層分數平均
最常見的錯誤是把「挑超參數」放在外層迴圈外面——先用全部資料做一次 CV 挑好超參數,再用同一份資料做 CV 報告分數。那樣做時,超參數已經看過所有資料,整個外層 CV 都被污染了(這和 老師用考古題教學又出題:為什麼要切資料 那個 的特徵選擇洩漏是同一個錯誤,只是換一層)。
注意巢狀驗證估的是「流程」,不是你最後交出去的那個模型
巢狀驗證的每一個外層折,都選出了它自己的超參數—— 個折可能選到 組不同的設定。所以那 個分數的平均估的是:
「這整套流程(含挑超參數)用 筆資料跑出來的期望表現。」
它不估「我最後用全部資料重訓、用某一組特定超參數的那個模型」的表現。這和 只有三十筆資料:交叉驗證 的結論是同一件事往上推一層:CV 估的永遠是演算法,不是某個模型。
實務上的用法因此是:巢狀驗證用來回報一個誠實的數字、或比較兩套流程;最終要交付的模型則用全部資料、照同樣的流程再跑一次。 那個最終模型的表現沒有被直接估計過——這聽起來不安,但它是小資料下唯一誠實的做法。
另外一個常被忽略的成本:巢狀驗證要跑 次訓練。 就是 1250 次。這是它在實務上常被跳過的原因,而跳過的代價就是上面那張表。
回到情境:那個 到底是多少
上面所有的算式都依賴 ——你實際比較過的候選數。而這是實務上最常被低估的量。
不是你寫在論文裡的那個數字。 它包含:
- 網格或隨機搜尋裡的每一組設定。
- 你手動試過又丟掉的每一個想法。
- 每一次「改一下再看看驗證分數」。
- 每一個你看過驗證分數之後才決定不做的方向。
一個跑了三個月、每天看幾次驗證分數的專案, 是幾百。代入 : 給 , 給 ——偏差大約翻倍。而 是驗證集的抖動,該收資料、換模型,還是多訓幾輪:學習曲線 量過, 時它的 區間寬度是被估量的 。
兩個實務推論。 一,記錄你試了幾組——那個數字是讀懂自己分數的必要資訊,也是 同一個實驗跑三次結果都不同,該報哪一個? 要一起報告的東西。二,驗證集要夠大:偏差正比於 ,而 ,所以驗證集加大四倍會讓選擇偏差減半——這通常比減少候選數便宜得多(候選數只以 進來)。
這一切依賴什麼。 一, 那條漸近式假設候選的估計誤差獨立;實務上相鄰的設定高度相關,所以真實的偏差比它小(本篇實測略高於漸近式是因為 小時漸近式本身不準)。二,實驗裡候選品質完全相同是刻意造出來的極端;真實情況下偏差與真實改善混在一起,而分開它們的唯一方法就是一份沒參與選擇的資料。三,測試集也只能用一次——用它比較過三個方案之後,它就變成了一個 的驗證集。
回到情境:一個五分鐘的自我檢查
上面的實驗可以直接搬成一個對自己流程的健康檢查,而且不需要任何新資料:
把標籤打亂,重跑整個超參數搜尋。 標籤打亂之後所有候選的真實品質都是「亂猜」,所以:
- 誠實的流程會回報一個接近亂猜的分數。
- 有選擇偏差的流程會回報一個明顯好於亂猜的分數,而且你搜得越用力,那個數字越好看。
這是 老師用考古題教學又出題:為什麼要切資料 那個「把標籤打亂」檢查的第二種用法:那裡用來抓洩漏,這裡用來量選擇偏差。兩者的訊號不同——洩漏會給出一個誇張的分數(實測 vs ),選擇偏差給出的是一個溫和但穩定的高估。
把兩個檢查一起跑,就能回答「我這個 裡面有多少是真的」。
候選數、驗證集大小、與那條漂掉的線
互動 demo:樂觀量隨 √log m 成長、正比於驗證集的抖動——所以「把驗證集加大」比「少試幾組」有效。
先消化一下
參考文獻
- Cawley, G., Talbot, N. On Over-fitting in Model Selection and Subsequent Selection Bias in Performance Evaluation. JMLR 2010.(模型選擇造成的偏差有多大、巢狀驗證的正確做法,以及文獻裡常見的錯誤形式。)
- Varma, S., Simon, R. Bias in error estimation when using cross-validation for model selection. BMC Bioinformatics 2006.(在小樣本的生醫資料上量出這個偏差,並示範巢狀 CV 把它修掉。)
- Dwork, C. et al. The reusable holdout. Science 2015.(把「重複使用同一份留出資料」形式化成適應性資料分析的問題,並給出一個有保證的機制。)