搜尋課程與筆記

搜尋筆記

輸入主題、關鍵字或單元編號,例如 Flow Matching、U4。

    按 Esc 關閉 · ⌘ / Ctrl K 開啟搜尋

    L3.2 14 分鐘閱讀 2026年10月

    L3.2 從一百個學生裡挑最好的,他下次會考得更好嗎?

    本篇重用1 篇

    從一百個學生裡挑第一名

    一百個學生考同一份試卷。你挑出考最高分的那一個,派他去比賽。

    他在比賽時會考得比這次好,還是比這次差?

    如果一百個學生的實力其實完全一樣,答案很清楚:這次的第一名純粹是那天運氣最好的那個,而運氣不會重現,所以他在比賽時會退回平均。你挑出來的那個「最好」的分數,是實力加上一次特別好的運氣。

    麻煩的是,真實情況介於兩者之間:學生有實力差距,也有運氣成分。挑出來的那個第一名,同時是「實力比較好」與「運氣比較好」的混合,而你沒辦法從那張成績單上分開這兩件事。

    這正是超參數搜尋結束時的處境。同樣試一百次:排成格子,還是隨便丟? 教你怎麼搜,搜完你有 mm 組設定與 mm 個驗證分數,挑了最低的那個。那個分數可以拿來報告嗎?

    挑出來的那一個,分數裡有多少是實力、多少是運氣?
    這兩件事分得開嗎?
    如果分不開,那個數字還能報告嗎?

    課堂提問Q1

    把「挑最好的」翻成數學。為什麼「挑出來的那個的分數」是有偏的,而且偏的方向固定?如果候選之間的真實品質完全相同,那個偏差會是多少——它從哪裡來?

    先想一想,再展開看整理後的答案

    先固定候選,再抽驗證資料。 f1,…,fmf_1,\dots,f_m 都不能依賴這份驗證集;在同分布、獨立取樣且期望有限時,各自的分數無偏:E[R^val(fj)]=R(fj)\mathbb E[\widehat R_{\text{val}}(f_j)]=R(f_j)。

    我們挑 ȷ^=arg⁡min⁡jR^val(fj)\hat\jmath=\arg\min_j \widehat R_{\text{val}}(f_j),然後想用 R^val(fȷ^)\widehat R_{\text{val}}(f_{\hat\jmath}) 當成績。

    取最小值不是無偏的。 min⁡\min 是一個凹函數,所以由 Jensen(保險為什麼存在:Convex Function 與 Jensen 不等式)

    E[min⁡jR^val(fj)] ≤ min⁡j E[R^val(fj)]=min⁡jR(fj).\mathbb E\Big[\min_j \widehat R_{\text{val}}(f_j)\Big]\ \le\ \min_j\ \mathbb E\big[\widehat R_{\text{val}}(f_j)\big]=\min_j R(f_j).

    不等號的方向是固定的——回報的數字在期望上不高於候選中最好的真實風險。這不是「有時偏高有時偏低」,是一個系統性的往下漂。

    候選品質完全相同時,偏差是純粹的選擇偏差。 設 R(fj)≡RR(f_j)\equiv R,每個分數是 R+ξjR+\xi_j,ξj\xi_j 是均值為零、標準差 σ\sigma 的估計誤差。那麼

    E[R^val(fȷ^)]=R+E[min⁡jξj]≈R−σ2log⁡m.\mathbb E\big[\widehat R_{\text{val}}(f_{\hat\jmath})\big]=R+\mathbb E\big[\min_j \xi_j\big]\approx R-\sigma\sqrt{2\log m}.

    最後一步假設 ξj\xi_j 是獨立同分布的 Gaussian,且 mm 夠大;不是只知道均值與標準差就能套用。共用驗證集會讓誤差相關,適應性搜尋又可能讓候選依賴資料,因此 2log⁡m\sqrt{2\log m} 是簡化模型的尺度,不是任意搜尋的精確校正量。

    而這時 R(fȷ^)=RR(f_{\hat\jmath})=R:你挑出來的那個,真實品質和其他所有候選一模一樣。回報的數字變好看了,拿到的模型完全沒有變好。 下一節把這個極端情形做成一個實驗。

    把「實力」拿掉,只留「運氣」

    理想例子先假設所有 R(fj)R(f_j) 完全相同,這才能把模型改善排除。下面實驗則使用同一演算法、不同訓練資料:它們在抽樣前具有相同的風險分布,但每個已訓練模型的真實風險不一定相等。

    做法:mm 個候選都是同一個 degree 的多項式擬合,差別只在它們各自看到一份不同的訓練資料。它們在期望上品質相同(同一個演算法、同樣的樣本數),但實際的分數會不同。所有候選共用同一份驗證集(nval=30n_{\text{val}}=30),挑最低的那一個。重複 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

    三欄一起讀才看得出重點。

    第一欄(回報的數字)一路變好:0.0256→0.01850.0256\to0.0185,mm 從 1 到 400 「改善」了 28%28\%。

    第二欄(勝出者真正的風險)紋風不動:0.02610.0261、0.02510.0251、0.02510.0251、0.02570.0257、0.02600.0260——在抖動範圍內完全平坦。

    你比較得越多,回報的數字越好看,而你拿到的模型沒有變好。

    m=1m=1 那一列是對照組:不選擇時樂觀量只有 0.00040.0004,實質為零。這確認了偏差確實來自「選」這個動作,不是實驗設計的某個瑕疵。

    驗證分數比勝出者真實風險下降得更明顯,顯示只報最低驗證分數會過度樂觀。但實驗不符合獨立同品質 Gaussian 的全部前提,不能把偏差的差異唯一歸因於相關性。

    若每個候選的抽樣機制相同,全體平均風險的期望不會只因 mm 增加就上升;中位數變化可能來自有限重複與風險分布,需另做分析。

    實力相同的候選,分數為什麼會漂

    圖說: 候選真實品質相同時,勝出者的表面優勢完全來自挑選;驗證集變大只能縮小、不能消除它。

    修法:把「選擇」也包進流程裡

    偏差的來源是「用同一份資料做選擇又做評估」。修法因此只有一個形狀:找一份沒有參與選擇的資料來評估。

    最簡單的版本是三份切分(老師用考古題教學又出題:為什麼要切資料 已經講過):訓練選權重、驗證選超參數、測試只讀一次。這在資料夠多時就夠了。

    資料不夠時要用巢狀驗證(nested cross-validation)。 關鍵在於認清一件事:

    「挑超參數」是訓練流程的一部分,不是訓練之前的準備工作。

    一旦這樣看,做法就自動出來了——把整個「訓練 + 挑超參數」當成一個演算法 A\mathcal A,然後對 A\mathcal A 做交叉驗證:

    外層 K 折:
        把第 k 折留出來當「測試折」
        在剩下的 K−1 折裡:
            內層 CV:挑超參數(這一步完全看不到測試折)
            用選出的超參數在那 K−1 折上重訓
        在測試折上評估   ← 這個分數沒有參與過任何選擇
    把 K 個外層分數平均

    最常見的錯誤是把「挑超參數」放在外層迴圈外面——先用全部資料做一次 CV 挑好超參數,再用同一份資料做 CV 報告分數。那樣做時,超參數已經看過所有資料,整個外層 CV 都被污染了(這和 老師用考古題教學又出題:為什麼要切資料 那個 81%81\% 的特徵選擇洩漏是同一個錯誤,只是換一層)。

    注意巢狀驗證估的是「流程」,不是你最後交出去的那個模型

    巢狀驗證的每一個外層折,都選出了它自己的超參數——KK 個折可能選到 KK 組不同的設定。所以那 KK 個分數的平均估的是:

    「這整套流程(含挑超參數)用 n(1−1/K)n(1-1/K) 筆資料跑出來的期望表現。」

    它不估「我最後用全部資料重訓、用某一組特定超參數的那個模型」的表現。這和 只有三十筆資料:交叉驗證 的結論是同一件事往上推一層:CV 估的永遠是演算法,不是某個模型。

    巢狀驗證可比較整套流程;交付模型則用全部資料照相同流程重訓。外層分數沒有直接評估這個最終模型;有額外獨立資料時仍可另外測試。它是小資料下一種可行方法,不是唯一有效的評估方式。

    另外一個常被忽略的成本:巢狀驗證要跑 K外×K內×mK_{\text{外}}\times K_{\text{內}}\times m 次訓練。5×5×505\times5\times50 就是 1250 次。這是它在實務上常被跳過的原因,而跳過的代價就是上面那張表。

    那個 mm 到底是多少

    上面所有的算式都依賴 mm——你實際比較過的候選數。而這是實務上最常被低估的量。

    mm 不是你寫在論文裡的那個數字。 它包含:

    • 網格或隨機搜尋裡的每一組設定。
    • 你手動試過又丟掉的每一個想法。
    • 每一次「改一下再看看驗證分數」。
    • 每一個你看過驗證分數之後才決定不做的方向。

    這些比較都應記錄,但不能把適應性修改的次數直接代入獨立 Gaussian 候選公式。它提醒我們「看過哪些結果」也是流程的一部分;要量最終表現,最直接的做法是保留未參與調整的資料。

    兩個實務推論。 一,記錄你試了幾組——那個數字是讀懂自己分數的必要資訊,也是 同一個實驗跑三次結果都不同,該報哪一個? 要一起報告的東西。二,驗證集要夠大:偏差正比於 σ\sigma,而 σ∝1/nval\sigma\propto1/\sqrt{n_{\text{val}}},所以驗證集加大四倍會讓選擇偏差減半——這通常比減少候選數便宜得多(候選數只以 log⁡m\sqrt{\log m} 進來)。

    這一切依賴什麼。 一,2log⁡m\sqrt{2\log m} 那條漸近式假設候選的估計誤差獨立;實務上相鄰的設定高度相關,所以真實的偏差比它小(本篇實測略高於漸近式是因為 mm 小時漸近式本身不準)。二,實驗裡候選品質完全相同是刻意造出來的極端;真實情況下偏差與真實改善混在一起,而分開它們的唯一方法就是一份沒參與選擇的資料。三,測試集也只能用一次——用它比較過三個方案之後,它就變成了一個 m=3m=3 的驗證集。

    一個五分鐘的自我檢查

    上面的實驗可以直接搬成一個對自己流程的健康檢查,而且不需要任何新資料:

    把標籤打亂,重跑整個超參數搜尋。 標籤打亂之後所有候選的真實品質都是「亂猜」,所以:

    • 誠實的流程會回報一個接近亂猜的分數。
    • 有選擇偏差的流程會回報一個明顯好於亂猜的分數,而且你搜得越用力,那個數字越好看。

    這是 老師用考古題教學又出題:為什麼要切資料 那個「把標籤打亂」檢查的第二種用法:那裡用來抓洩漏,這裡用來量選擇偏差。兩者的訊號不同——洩漏會給出一個誇張的分數(實測 81%81\% vs 50%50\%),選擇偏差給出的是一個溫和但穩定的高估。

    標籤打亂是檢查異常的工具,不會精確分解原分數有多少來自真實訊號。樣本有限時,接近亂猜也不必等於亂猜;有結構的資料還要使用符合交換性條件的置換方式。

    候選數、驗證集大小、與那條漂掉的線

    互動 demo:樂觀量隨 √log m 成長、正比於驗證集的抖動——所以「把驗證集加大」比「少試幾組」有效。

    檢查理解

    想一想

    一個團隊比較了 200 組超參數,回報最好那一組的驗證準確率 94.1%94.1\%。根據本篇的實驗,最準確的敘述是:

    想一想

    在實驗裡,mm 從 1 加到 400 時勝出者的真實風險是 0.0261→0.0251→0.0251→0.0257→0.02600.0261\to0.0251\to0.0251\to0.0257\to0.0260。這一欄說明:

    想一想

    下列哪一種做法會造成本篇所說的偏差?

    想一想

    下列哪一句不對?

    參考文獻

    1. Cawley, G., Talbot, N. On Over-fitting in Model Selection and Subsequent Selection Bias in Performance Evaluation. JMLR 2010.(模型選擇造成的偏差有多大、巢狀驗證的正確做法,以及文獻裡常見的錯誤形式。)
    2. Varma, S., Simon, R. Bias in error estimation when using cross-validation for model selection. BMC Bioinformatics 2006.(在小樣本的生醫資料上量出這個偏差,並示範巢狀 CV 把它修掉。)
    3. Dwork, C. et al. The reusable holdout. Science 2015.(把「重複使用同一份留出資料」形式化成適應性資料分析的問題,並給出一個有保證的機制。)