training accuracy 1.00、validation accuracy 0.72——中間裂開一條 0.28 的縫。題目給了三個設定值(500 棵、深度不限、每葉 1 筆)和四種處置,考的是你能不能看著設定就指出病灶:哪個旋鈕在放任單棵樹長到「把訓練資料背起來」,而哪些處置只是在旁邊瞎忙。本頁把四個選項全部實跑給你看。
某 Tree Ensemble 出現 training accuracy=1.00、validation accuracy=0.72,原始設定如下。若其他資料流程已確認無洩漏,下列調整何者最能直接降低單棵樹的複雜度並改善過擬合?
from sklearn.ensemble import RandomForestClassifier # 拿出隨機森林分類器 model = RandomForestClassifier( # 開始組模型(括號先不關) n_estimators=500, # 樹的數量:500 棵 max_depth=None, # 樹深上限:不設限,想長多深就多深 min_samples_leaf=1, # 每片葉子最少要有幾筆:1 筆也行 random_state=42 # 固定亂數種子 ) # 設定收尾——注意:題目連 .fit 都沒呼叫
一個學生把三年份考古題的答案背得滾瓜爛熟:模擬考(訓練集)次次滿分。大考(驗證集)出了新題,只考 72 分——因為他背的是「答案」,不是「解法」。這就是過擬合(overfitting):模型把訓練資料的細節連同雜訊一起記下來,換一批沒看過的資料就原形畢露。
診斷的關鍵是兩個數字一起讀:train 高不是問題、val 低也不一定是過擬合——「train 很高、val 明顯低、中間裂縫很大」三件事同時成立,才是過擬合的招牌長相。本題 1.00 vs 0.72,裂縫 0.28,教科書級的病例。
點擊後出現漸進式說明:白話說明 → 說清楚一點 → 常見錯誤與考點。
點擊後出現漸進式說明。這題的程式只有「設定」,一個動作都沒做——正因如此,每個設定值的意義就是全部。
七行裡有五行是「設定值」。右上角的「看位置」可以把這一行放回完整程式裡看。
model = RandomForestClassifier( ... ) ← 只是把一台機器組好、放在桌上
沒有 .fit():一筆資料都還沒看
題目的 1.00 / 0.72 是「之後訓練完」量到的
所以這題考的不是流程,是看設定值診斷病灶:
n_estimators=500、max_depth=None、min_samples_leaf=1 —— 哪個在縱容過擬合?
from sklearn.ensemble import RandomForestClassifier # 從「集成方法」抽屜拿出隨機森林
sklearn.ensemble 是集成方法的抽屜。題目說「Tree Ensemble(樹的集成)」,隨機森林就是最典型的一種:一大群決策樹各自判斷、投票表決。
重點先講:集成(很多棵樹平均)能降低結果的波動,但每一棵樹自己有多會「背答案」,是另一件事——那由第 4、5 行的設定決定。這個分工是整題的鑰匙。
model = RandomForestClassifier( # 呼叫開始,括號先不關
呼叫 RandomForestClassifier(...) 組一台森林,貼上 model 的名牌。括號沒關——第 2 到第 7 行其實是同一句話,只是把四個設定值排成一行一個,好讀。
這種「一行一個參數、行尾逗號」的排版是 sklearn 教學裡最常見的寫法。逗號的意思是「還有下一項」,最後一項後面可加可不加。
n_estimators=500, # 森林裡種 500 棵樹
500 棵不少,但先把話說死:樹的「數量」跟單棵樹的「複雜度」是兩個獨立的旋鈕。數量多=找更多評審來投票,平均起來更穩;複雜度高=每一位評審都在背答案。500 個都在背答案的評審,平均出來的還是背答案。
max_depth=None, # 深度不設上限,長到分不動為止
None =「不設上限」:每棵樹可以一路分岔,直到每片葉子都純了(或碰到其他限制)為止。這是過擬合的第一個放任條款——樹越深,能刻出的規則越細,細到可以為單一筆訓練資料量身打造一條路徑。
None 是 Python 的正式值(「不設定」的明確寫法),不是空白也不是忘了填。它是預設值——你什麼都不寫,隨機森林本來就是深度不設限。
min_samples_leaf=1, # 每片葉子最少 1 筆就合法
min_samples_leaf 規定「分岔之後,每片葉子至少要包含幾筆訓練資料」。設成 1,代表樹可以為了一筆資料切出一片專屬葉子——這等於發給每棵樹一張「逐筆記憶執照」:連標錯的雜訊點,都能被切成自己的小房間。
它也是預設值(預設就是 1)。所以題目的設定其實是「全預設的放任狀態」——這在實務上非常常見:用預設值訓練,然後發現 train 1.00。
random_state=42 # 固定所有抽籤,結果可重現 ) # 括號關上,model 組裝完成
random_state=42 把森林裡所有抽籤(抽資料、抽特徵)固定住,讓 1.00/0.72 這組數字可以被重現。第 7 行關括號,這句六行長的「組裝指令」結束。
注意程式到這裡就停了——沒有 .fit()、沒有評分。題目給的 1.00 和 0.72 是「之後訓練並評估」的結果,這段程式只負責交代造成那兩個數字的設定。考題常這樣只給關鍵段落。
為了把四個選項全部做出來對照,本站造了一份會誘發過擬合的資料:300 筆、60 個特徵,其中只有 6 個真的帶訊號(4 個有效+2 個冗餘),其餘 54 欄全是干擾;再摻 5% 的標籤雜訊。切 7:3 之後,用題目的原始設定訓練:
把 max_depth 從 2 一路開到 None,train 和 val 各自怎麼走?這條「複雜度曲線」是過擬合考題的心臟:
三個讀點。第一,train 在深度 5 就衝到 1.000,之後永遠貼著天花板。第二,val 在深度 5~6 達到峰值 0.767,再深就往下掉、一路掉回 0.722——複雜度越過甜蜜點之後,多出來的容量全部拿去背雜訊。第三,光看裂縫也會被騙——全場 gap 最小的其實是 depth 2(0.115),但那是「兩個都低」的欠擬合;gap 一定要跟 val 一起讀,甜蜜點是「val 最高」的深度 5~6(gap 0.233),不是「gap 最小」的地方。
max_depth 是「限制樓層數」,min_samples_leaf 則是「規定每個房間至少要住幾個人」——房間不能為一筆資料獨開,樹自然就刻不出那些為雜訊量身打造的細枝。把它從 1 調到 50(深度保持 None):
曲線同樣有甜蜜點:val 峰值在 leaf=5(0.756);再往上調,train 一路掉到 0.767、val 也回落——剪過頭就是欠擬合:leaf=50 時每棵樹平均只剩 2 片葉子、1 層深,變成 500 根「樹墩」,連真訊號都學不了。判讀口訣:train 高 val 低=過擬合;train val 一起低=欠擬合;兩個都不錯且接近=剛剛好。
min_samples_split(少於幾筆就不准再分岔)、max_leaf_nodes(葉子總數上限)、ccp_alpha(成本複雜度後剪枝)。它們都在做同一件事——讓樹的每個決定都必須有「一群樣本」背書,而不是為單筆資料服務。這類參數統稱樹的「預剪枝」,是樹家族的正則化。「維持 max_depth=None 與 min_samples_leaf=1,只增加 n_estimators」——直覺上「更多樹=更強」,實跑看看:
結果一目了然:train 永遠 1.000;val 從 50 棵的 0.678 爬到 100 棵的 0.733 之後,就停在 0.72~0.74 的平台抖動——500、1000、2000 棵都突破不了,永遠到不了剪枝後的 0.767。
「移除驗證集,改以 training accuracy 選參數」——這是四個選項裡唯一連方向都沒有的。用同一個 8 × 5 的參數網格(max_depth × min_samples_leaf,共 40 組),兩種選法對照:
把 D 選項一字不漏做出來:「以交叉驗證限制 max_depth,並提高 min_samples_leaf 等葉節點限制」——正好接上上一頁的 GridSearchCV:8 個深度 × 5 個葉限制 = 40 組合,5 折交叉驗證(40 × 5 = 200 次 fit,上一頁的乘法)。
{'max_depth': 5, 'min_samples_leaf': 1}(CV 分數 0.743;前三名 0.743/0.743/0.738 全是深度 4~6 的淺樹設定,原設定 (None, 1) 的 CV 只有 0.729、排第 22 名)。用最佳設定重訓:
| train | val | gap | 單棵樹平均深 | 平均葉數 | 每葉筆數 | |
|---|---|---|---|---|---|---|
| 原設定(None, 1) | 1.000 | 0.722 | 0.278 | 9.3 層 | 29.0 | 7.2 |
| CV 最佳(depth 5) | 1.000 | 0.767 | 0.233 | 5.0 層 | 16.8 | 12.5 |
加樹降的是「變異」,不動單棵樹的複雜度——實跑 500→2000 棵,train 恆為 1.000、val 卡在 0.72~0.74 平台,永遠到不了剪枝後的 0.767。穩定器,不是剪枝刀。
training accuracy 永遠偏向複雜、也分不出好壞——實跑 40 組裡 12 組並列滿分(val 卻差 4.5 個百分點),原設定正是滿分席裡 val 墊底的。沒有驗證訊號,過擬合連被發現的機會都沒有。
實跑:深度越過 5~6 之後 train 卡 1.000、val 一路下滑——越加深兩條線越開。而 val 想升到 1.0 也不可能(資料有 5% 標籤雜訊)。把「兩個數字相等」當目標,是拿手段當目的。
兩把剪枝刀直接作用在「單棵樹複雜度」上(9.3 層→5.0 層、29 葉→16.8 葉),用 CV 這把可靠量尺挑設定——val 0.722 → 0.767、gap 0.278 → 0.233。對症(複雜度)、下對藥(葉節點與深度限制)、用對量尺(CV)。
再看一次同一段設定。這次你知道每個旋鈕在管什麼了。
某 Tree Ensemble 出現 training accuracy=1.00、validation accuracy=0.72。若其他資料流程已確認無洩漏,下列調整何者最能直接降低單棵樹的複雜度並改善過擬合?
model = RandomForestClassifier( # 組模型 n_estimators=500, # 數量:穩定器 max_depth=None, # 放任條款一:深度不限 min_samples_leaf=1, # 放任條款二:一筆也能自成一葉 random_state=42 # 固定抽籤 ) # 組裝完成
八題,全部都是本題的延伸。答錯會直接告訴你錯在哪。
None 是「不設上限」的正式寫法;max_depth=None 和 min_samples_leaf=1 都是預設值——題目的設定就是「全預設的放任狀態」。過擬合診斷與樹的複雜度控制是中級科目三「機器學習技術與應用」的必考區,跟科目二的模型評估互相支援。最常見的五種問法:① 給 train/val 兩個分數問診斷(高+低+裂縫大=過擬合;一起低=欠擬合);② 給一組 RF 設定問「哪個參數在放任過擬合」(max_depth=None、min_samples_leaf=1 這對組合);③ 問哪些調整能降低樹複雜度(深度/葉節點/分裂門檻類參數,而 n_estimators 不是);④ 問為什麼用 CV 而不是 training accuracy 或單一驗證集選參;⑤ 給「調整後 train 掉、val 也掉」問發生什麼事(剪過頭、欠擬合方向)。記住一句:數量(n_estimators)管穩定、複雜度(depth/leaf)管背不背答案——考題就是在測你分不分得開這兩個旋鈕。
不一定,要看 val。資料乾淨好分時,一個大小剛好的模型也可能訓練全對、驗證也很高——那不是病。真正的病徵是組合條件:train 很高、val 明顯低、裂縫大。本站實跑還給了一個微妙的例子:CV 挑出的最佳設定(depth=5)train 仍然是 1.000,但 val 從 0.722 升到 0.767——所以「把 train 壓下來」從來不是目標,val(或 CV 分數)才是判準。反過來說,看到 train 0.75、val 0.73 這種「一起低」的組合,該想的是欠擬合或特徵不夠,而不是繼續剪枝。
因為隨機森林的平均(Bagging)降低的是變異:單棵樹的判斷很飄,幾百棵平均起來就穩定。但「每棵樹都把訓練資料背起來」是系統性的——500 棵樹背的是同一份資料的雜訊,平均之後那些雜訊記憶並不會互相抵銷乾淨。本站實跑:50 棵時 val 只有 0.678(樹太少、平均不穩,加樹確實有幫助),100 棵後就進入 0.72~0.74 的平台,到 2000 棵都突破不了,而剪枝後是 0.767。結論:加樹「有用但有天花板」,且它的用途是穩定,不是治過擬合——考題問「降低單棵樹複雜度」時,它就是答非所問。
兩把刀從不同角度限制同一件事。max_depth 管「問幾層問題」:深度 d 的樹最多能刻出 2^d 個區域,直接卡住規則的精細度;min_samples_leaf 管「每個結論要有多少樣本背書」:葉子至少要裝 k 筆,樹就無法為單筆雜訊開專屬房間,而且它會自動適應資料密度(樣本稀疏的地方剪得更兇)。實跑中兩把刀各自都有效(depth 5 → 0.767;leaf 5 → 0.756),CV 最後挑了深度。實務上建議兩個都放進網格讓 CV 決定——這正是題目 D 的寫法「限制 max_depth,並提高 min_samples_leaf 等葉節點限制」。
會從過擬合直接滑進欠擬合:模型簡單到連真訊號都學不了。實跑的 leaf 掃描很直觀——leaf=50 時每棵樹平均只剩 1 層深、2 片葉(500 根樹墩),train 從 1.000 掉到 0.767、val 也從峰值 0.756 回落到 0.733。發現的方法就是看曲線不看單點:把候選值掃一排(驗證曲線),train 與 val 的走勢會告訴你甜蜜點在哪一段;只試一個值就下結論,很容易剛好落在過頭的那一側。判讀口訣:train 高 val 低=過擬合;兩個一起低=欠擬合;兩個都不錯且接近=剛剛好。
兩個理由。第一,驗證集通常很小(本站實跑只有 90 筆),分數本身有 ±0.02 左右的雜訊——40 組參數之間的差距常常就這個量級,單一驗證集分不乾淨。第二,更隱微:如果你反覆拿同一批驗證集試幾十組參數、挑分數最高的,你其實在對驗證集調參——挑出來的設定會過擬合到這 90 筆身上,之後上線的表現又會掉一截。交叉驗證把訓練集內部切成 k 折輪流當考官,分數更穩,而驗證集保留到最後只做一次最終確認。這就是題目 D 特別寫「以交叉驗證」五個字的原因——它不是裝飾,是流程的一部分。
它是分數,但量錯了東西。訓練分數量的是「模型跟看過的資料貼多緊」,而你要的是「模型對沒看過的資料多準」。兩者在複雜度足夠時會徹底脫鉤:複雜度越高 train 只會越高,所以這把尺永遠偏向最複雜的設定、永遠不會懲罰過擬合。實跑還揭露它的第二個缺陷——無鑑別度:40 組參數有 12 組 train 同為 1.000,但它們的 val 從 0.722 到 0.767 都有。移除驗證集之後,你不但選不對,連「自己選錯了」都無從得知——過擬合最可怕的不是發生,是發生了卻沒有任何儀表板會亮燈。
本題聚焦「單棵樹複雜度」,但完整的工具箱還有幾層。樹內:min_samples_split、max_leaf_nodes、min_impurity_decrease,以及成本複雜度後剪枝 ccp_alpha(先長滿再修)。森林層:max_features 調小讓樹更不相像、max_samples 限制每棵樹的抽樣量。資料層:更多訓練資料是最實在的解(過擬合本質是「資料不夠撐起這個複雜度」);特徵篩選拿掉純雜訊欄位也直接有效(本站的資料 60 欄裡 54 欄是干擾)。流程層:用 OOB 分數當免費的內部檢查(實跑:原設定 OOB 0.729,跟它的 CV 分數 0.729 幾乎一致)。梯度提升樹(GBDT/XGBoost)另有 learning_rate 與早停等自己的煞車,考題會分開考。