📚 背景知識(読んでから問題へ)
今の決め方。 決定15(lr0.1・300本の葉 31/63/127/255 を補正CVで比べ、端の255が勝ったら511を足す)で葉を選び、決定18 でその葉を学習率 0.05・600本で作り直して提出する。Day178 の1 fold モデルの曲線では、葉255 以上で 600本は多すぎた(中雑音 s255 は450本付近、s511 は300本付近が山)。ただし提出は 5本平均 で、平均で過学習が和らぐ分だけ山が後ろにずれるかもしれない。これは測っていなかった。
比べる止め方。 Kaggle の公開ノートブックで最も多いのは、fold ごとに検証 fold の誤差を見て early_stopping(stopping_rounds=50〜100) で止める書き方。LightGBM 公式も early_stopping コールバックを「検証スコアが stopping_rounds 回改善しなければ止める」と説明している(lightgbm.early_stopping、参照 2026-10-12)。この書き方は 止める本数を選んだのと同じ fold で OOF を測る ので、CV が楽観的になりうる。
用語整理:
| 用語 | 意味 |
|---|---|
s31〜s511 | 学習率 0.05・最大600本・葉 31〜511 の乱数なし LightGBM(Day178 と同じ) |
| 途中本数 n | 50, 100, …, 600 の12点。学習し直さず、木の塊ごとの予測を足し上げて作る |
| T5 | 5本平均の truth 60,000行 RMSLE(真) |
| Ca | 補正CV √(C² − A_test)(決定13)。C は生の OOF RMSLE、A_test は test 2万行での5本の分散 |
| 早期打ち切り(忍耐50 / ∞) | fold ごとに val fold の l2 が最良の本数で止める。忍耐50 は「50本改善が無ければ打ち切り」、∞ は600本までの最良 |
| 損 | 規則で選んだ本数の T5 − その葉の12点の T5 の最良 |
数値はすべて縮小シミュレータの上の実測(S5E5 の構造を写した合成データ、Day163〜)。
データ・保存物の構造(スキーマ)
| 名前 | 形・型 | 意味・作り方 | 使う場所 |
|---|---|---|---|
| Sex … Body_Temp, Dur_x_HR, Keytel_kcal | int / float(9列) | Day163〜178 と同じ合成(ワールドの乱数 3000+番号)。今日測れたのは低雑音(Calories の雑音 0.05/0.03)の w0・w1 | 全候補 |
| raw179_w*.npz(今日、消失) | oof (5,12,30000) float32・oof_es (2,5,30000)・S (5,12,3)・S_es (2,5,3)・best_it (2,5,5)・vcurve (5,5,600) | 葉5種 × 途中本数12点の OOF と、5本平均の T5・T1・A_test。早期打ち切り2通り。val の l2 を1本ごと | 表1〜6 |
| raw178(Day178、消失) | oof (6,30000)・evk (6,5,80000) | 600本の予測の一致確認(fold 別予測 最大差 0.0) | 再現 |
| raw175 / raw176(lr0.1、消失) | oof・evk | 決定15 の葉選び(補正CV)に使う | 表5 |
| T5 / C / A / Ca | float | 5本平均の truth RMSLE(真)/生の OOF RMSLE/test 側5本の分散/補正CV √(C²−A) | 全表 |
評価指標(RMSLE)と、今日の問い
RMSLE は log1p 空間の RMSE(小さいほど良い)。差はすべて ×10⁻⁴。下の図は、提出と同じ5本平均で、本数を変えたときの真の誤差を葉ごとに重ねたもの。600本より良い本数があるのは葉255・511 だけだった。
❓ 問題
タスクA(予想を書いてから測る)
- 5本平均の山(最良の本数)は、葉ごとにどこにあると思うか。1 fold の曲線(Day178 表6)より前か後ろか
- 補正CV で本数を選ぶと、600本固定よりどれくらい得か
- fold ごとの早期打ち切りは、補正CV で本数を選ぶのと比べて良いか悪いか。生CV はどう見えるか
- 葉と本数を同時に60点から選ぶと、決定18+本数選びより良いか
タスクB(コーディング)
day178.pyの生成部を変えずに、s31〜s511 を学習しながら val fold の l2 を1本ごとに記録し、途中本数12点の OOF と fold 別予測を作るday179.pyを書く(全体を12回予測せず、start_iterationで塊ごとに足す)- 600本の予測が Day178 の保存物と一致することを確かめる
analyze179.pyで、5本平均の本数曲線・本数を選ぶ規則の損・CV が本数の曲線を正しく写すか・早期打ち切りの止まる本数と楽観・方針全体の損・費用を出す
タスクC(分析・戦略)
- 決定18 の「600本」を、葉ごとの本数選びに替えるべきか
- fold ごとの早期打ち切りを最終提出に使ってよいか
- 今日の結果で、どの決定の印を動かせるか
💡 ヒント
ヒント1(方向性)
本数を選ぶ得は「選んだ葉」によって大きく違うはず。葉ごとの表と、決定15 を通した方針全体の表を分けて見る。
ヒント2(アプローチ)
LightGBM の回帰では、predict(X, start_iteration=a, num_iteration=b-a, raw_score=True) が a〜b 本目の木の寄与だけを返す。塊を足し上げれば12点の予測が1回分の手間で取れる。早期打ち切りは record_evaluation で val の l2 を1本ごとに取っておけば、学習後に「忍耐50ならどこで止まったか」を再現できる(止め方の違いでモデルを作り直す必要がない)。
ヒント3(コード骨格)
rec = {}
m = lgb.LGBMRegressor(**LG, num_leaves=L, random_state=k).fit(
X, y, eval_set=[(XV, yv)], eval_metric="l2", callbacks=[lgb.record_evaluation(rec)])
sv, se_ = np.zeros(len(va)), np.zeros(len(XE)); a = 0
for i, b in enumerate(IT):
sv += m.predict(XV, start_iteration=a, num_iteration=b - a, raw_score=True)
se_ += m.predict(XE, start_iteration=a, num_iteration=b - a, raw_score=True)
oof[j, i, va] = sv; ev[j, i, k] = se_; a = b
✅ 模範解答
タスクA(予想。測る前に書いたもの、04:35 記入)
- 5本平均の山は1 fold の曲線より後ろ。中雑音 s255 は500本前後、s511 は350〜400本、低雑音 s255/s511 は200〜300本。葉31/63 は600本が最良
- 大きい葉で −0.5〜−1.5 の得、小さい葉では差なし
- 早期打ち切り(忍耐50)は生CV が +0.5 以上楽観になるが、真の損は補正CV 最小とほぼ同じ
- 候補が増えた分だけ損が増え、決定18+本数選びより悪い
→ 1 は低雑音の s511(約225本)は当たり、s255 は 450本で外れ(後ろ)。2 は葉511 で −3.66 と予想より大きい。3 は外れ: 真の損も +2.17 悪化した。4 は2ワールドでは逆(−0.35)だが差は1SE。
タスクB(完全なコード)
day179.py(生成部 keytel_rate・make_original・synth_from・add_feats・BASE は day178.py と1文字も同じなので省略):
LG = dict(objective="regression", learning_rate=0.05, n_estimators=600, min_child_samples=20, n_jobs=1, verbose=-1) LEAVES = [31, 63, 127, 255, 511] names = [f"s{L}" for L in LEAVES] IT = list(range(50, 601, 50)) R8 = np.load(sys.argv[4]) # Day178 の raw178_w<W>.npz assert list(R8["names"]) == ["lgb_det"] + names # 決定9 # ...生成(seed 3000+W)、train / evalset を作り、R8 の ytr・yev と一致を assert... oof = np.zeros((nM, nI, N_TRAIN), np.float32) # 途中本数ごとの OOF(保存) ev = np.zeros((nM, nI, 5, N_TEST + N_TRUTH), np.float32) # 途中本数ごとの fold 別予測(保存せず集計だけ残す) vcurve = np.zeros((nM, 5, 600)) # fold ごとの val l2(1本ごと) ES = {"es_inf": None, "es_p50": 50} def es_pick(c, pat): # 忍耐 pat で止めたときの最良本数 best, bi = np.inf, 0 for i, v in enumerate(c): if v < best: best, bi = v, i elif pat is not None and i - bi >= pat: break return bi + 1 for k, (tr, va) in enumerate(KFold(5, shuffle=True, random_state=0).split(train)): tr_df = pd.concat([train.iloc[tr], orig], ignore_index=True) X, y, XV = tr_df[BASE].values, np.log1p(tr_df.Calories.values), train.iloc[va][BASE].values yv = np.log1p(train.Calories.values[va]) for j, L in enumerate(LEAVES): rec = {} m = lgb.LGBMRegressor(**LG, num_leaves=L, random_state=k).fit( X, y, eval_set=[(XV, yv)], eval_metric="l2", callbacks=[lgb.record_evaluation(rec)]) vcurve[j, k] = rec["valid_0"]["l2"] sv, se_ = np.zeros(len(va)), np.zeros(len(XE)); a = 0 for i, b in enumerate(IT): sv += m.predict(XV, start_iteration=a, num_iteration=b - a, raw_score=True) se_ += m.predict(XE, start_iteration=a, num_iteration=b - a, raw_score=True) oof[j, i, va] = sv; ev[j, i, k] = se_; a = b full = m.predict(XE) rep[j, 2] = max(rep[j, 2], np.abs(full - se_).max()) # 塊の和 対 一括 rep[j, 0] = max(rep[j, 0], np.abs(sv - R8["oof"][j + 1, va]).max()) # 対 raw178 OOF rep[j, 1] = max(rep[j, 1], np.abs(full.astype(np.float32) - R8["evk"][j + 1, k]).max()) # 対 raw178 fold別 for e, pat in enumerate(ES.values()): bi = es_pick(vcurve[j, k], pat); best_it[e, j, k] = bi oof_es[e, j, va] = m.predict(XV, num_iteration=bi); ev_es[e, j, k] = m.predict(XE, num_iteration=bi) def agg(E): # (5, N_TEST+N_TRUTH) -> T5, T1, A_test t5 = np.sqrt(((lp_clip(E[:, N_TEST:].mean(0)) - ltru) ** 2).mean()) t1 = np.sqrt(((lp_clip(E[:, N_TEST:]) - ltru) ** 2).mean()) return t5, t1, E[:, :N_TEST].var(axis=0).mean() S = np.array([[agg(ev[j, i]) for i in range(nI)] for j in range(nM)]) S_es = np.array([[agg(ev_es[e, j]) for j in range(nM)] for e in range(len(ES))]) np.savez_compressed(f"raw179_w{W}.npz", oof=oof, oof_es=oof_es, S=S, S_es=S_es, best_it=best_it, ...)
analyze179.py(要点):
def choose(g, col, lo=50): # 本数を CV(Ca か C)の最小で選ぶ gg = g[g.it >= lo]; return gg.loc[gg[col].idxmin()] # 決定15 の葉(lr0.1・300本の補正CV、一覧 31/63/127/255+端なら511) L15 = fca[[31, 63, 127, 255]].idxmin() if L15 == 255: L15 = fca[[31, 63, 127, 255, 511]].idxmin() P = {"決定18(葉は決定15、600本)": gl[gl.it == 600].T5.iloc[0], "決定18+本数を補正CVで(50-600)": choose(gl, "Ca").T5, "決定18+本数を補正CVで(200-600)": choose(gl, "Ca", 200).T5, "決定18+早期打ち切り(忍耐50)": el.loc["es_p50"].T5, "決定18+本数を生CVで": choose(gl, "C").T5, "葉も本数も補正CVで(60点)": g.loc[g.Ca.idxmin()].T5, "葉は600本の補正CVで(lr0.05の5本)": g600.loc[g600.Ca.idxmin()].T5} loss = (P[k] - g.T5.min()) * 1e4 # 対 その世界の 5葉×12本=60点の真の最良
実行:
# 18ワールド(3世界 × w0-5)を 6 並行で作る予定で起動した(run.sh は Day177 の uv venv と scikit-learn 同梱の libomp を使う) xargs -P 6 -L 1 ./run.sh < jobs.txt # 集計(引数: 今日の出力・Day175 の保存物・Day176 の保存物・Day177 で足した Day176 の残り) python analyze179.py r <d175> <d176> <d177/r176>
実行結果(実測。低雑音 w0・w1 の2ワールドだけ)
# ============ 実行環境: macOS (M1, メモリ8GB)・Day177 の uv venv(Python 3.13.12・lightgbm 4.7.0)
# OMP_NUM_THREADS=1・n_jobs=1、6並行。1ワールド 1,127〜1,130 秒(低雑音)
# 18ワールドで起動したが、低雑音 w0・w1 の2つが終わった後(約1時間後)に /private/tmp が丸ごと片付けられ、
# 実行中のジョブ・今日の保存物・Day175〜178 の保存物と venv がすべて消えた(理由は「扱わなかった範囲」)。
# 下の表は、消える前に analyze179.py を2ワールドで回した出力。
ワールド数: {'低雑音': 2}
再現(600本 対 raw178、最大絶対差): OOF 2.3e-14 fold別予測 0.0 塊の和 対 一括予測 3.0e-14
=== 表1 5本平均の真の RMSLE の本数曲線(同じ葉の600本との差、×1e-4、2ワールド平均)===
[低雑音] 100 200 300 400 500 600 最良本数(w0,w1) 600本が最良
葉31 +23.24 +11.05 +6.44 +3.41 +1.34 0.00 600, 600 2/2
葉63 +19.93 +8.70 +4.64 +2.31 +0.87 0.00 600, 600 2/2
葉127 +16.72 +5.95 +2.95 +1.34 +0.52 0.00 600, 600 2/2
葉255 +12.19 +1.85 -0.13 -0.79 -0.72 0.00 400, 500 0/2
葉511 +3.86 -4.80 -4.32 -2.93 -1.44 0.00 200, 250 0/2
=== 表2 葉ごとに本数を選ぶ規則(損 / 600本固定との対の差±SE、×1e-4)===
葉31 葉63 葉127 葉255 葉511
600本固定 0.00/ 0 0.00/ 0 0.00/ 0 0.86/ 0 4.94/ 0
補正CV最小(50-600) 0.00/+0.00 0.00/+0.00 0.00/+0.00 0.00/-0.86±0.25 1.28/-3.66±0.48
補正CV最小(200-600) (50-600 と同じ)
生CV最小 0.36/+0.36 0.10/+0.10 1.06/+1.06 1.42/+0.56±1.37 0.14/-4.80±0.35
早期打ち切り(忍耐∞) 1.02/+1.02 0.54/+0.54 1.02/+1.02 1.18/+0.32±0.80 0.33/-4.61±0.16
早期打ち切り(忍耐50) 1.83/+1.83 2.58/+2.58 1.93/+1.93 2.59/+1.74±0.62 0.71/-4.22±0.23
=== 表3 CV は本数の曲線を正しく写すか((CV[200]−CV[600]) − (真[200]−真[600])、×1e-4)===
補正CV Ca 葉31 +2.38 葉63 +4.14 葉127 +5.27 葉255 +2.55 葉511 +3.04 (本数の少ない側を悪く見せる)
生CV C 葉31 -2.68 葉63 -2.24 葉127 -2.46 葉255 -6.34 葉511 -6.77 (本数の少ない側を良く見せる)
=== 表4 早期打ち切りが止まった本数(fold ごと10個の中央値[最小-最大])と生CV の楽観 ===
忍耐50 葉31 506[243-590] 葉63 350[242-600] 葉127 364[263-438] 葉255 199[159-281] 葉511 172[131-234]
忍耐∞ 葉31 572[408-600] 葉63 570[312-600] 葉127 444[263-593] 葉255 280[197-353] 葉511 180[139-234]
忍耐50 の生CV の楽観の増分((C_es−真_es) − (C600−真600)): 葉31 -2.41 葉63 -2.23 葉127 -3.10 葉255 -7.16 葉511 -8.28
=== 表5 方針全体の損(×1e-4、対 その世界の 5葉×12本=60点の真の最良)と決定18 との対の差 ===
決定18(葉は決定15、600本) 1.46
決定18+本数を補正CVで(50-600) 1.46 +0.00(決定15 は w0=葉63・w1=葉127 を選び、どちらも600本が最良)
決定18+本数を補正CVで(200-600) 1.46 +0.00
決定18+本数を生CVで 1.78 +0.32±0.32(悪い1/2)
決定18+早期打ち切り(忍耐50) 3.63 +2.17±0.28(悪い2/2)
葉も本数も補正CVで(60点) 1.11 -0.35±0.35(良い1/2)
葉は600本の補正CVで(lr0.05の5本) 1.11 -0.35±0.35(良い1/2)
=== 表6 費用(1ワールド5fold、中央値秒)===
学習(val の記録込み): 葉31 6 葉63 8 葉127 13 葉255 21 葉511 42
予測(途中本数12点+早期打ち切り2通り): 葉31 46 葉63 67 葉127 197 葉255 330 葉511 397
タスクC(分析・戦略の模範)
- 決定18 の「600本」は、低雑音では替えても何も変わらない。 決定15 が低雑音で選ぶ葉は 63/127 で、その葉の5本平均は 2/2 で 600本が最良(表1)。補正CV で本数を選んでも 600本を選び、損は 1.46 のまま(表5)。本数選びが効くのは葉255 以上だけで、葉255 は −0.86±0.25、葉511 は −3.66±0.48(表2)。決定15 が葉255 を選ぶ小得・中雑音で同じ得が出るかが本題だが、今日は測れなかった。決定18 は変えず、本数選びは「葉255 以上を選んだときだけ補正CV で 200〜600本から選ぶ」を仮の決定19(印 △)として置く
- fold ごとの早期打ち切り(忍耐50)は最終提出に使わない。 対で +2.17±0.28(2/2 悪化)。止まる本数が早すぎ(葉63 で中央値 350本、真の山は600本)、しかも生CV は止めた fold の上で測るので 2〜8 楽観に見える(表4)。早期打ち切りの CV で候補を比べると、葉が大きい候補ほど得に見える(楽観が 葉31 −2.41 → 葉511 −8.28 と育つ)ので、比べる段階にも使えない。忍耐∞ でも小さい葉で +0.5〜+1.0 悪い。原因は、1 fold の val 6,000行の l2 の揺れで本数を決めることと、5本平均では山が後ろにずれること(1 fold の山 ≠ 5本平均の山)
- 補正CV は本数の比較では偏る。 (CV[200]−CV[600]) − (真の差) は 補正CV で +2.4〜+5.3(少ない本数を悪く見せる)、生CV で −2.2〜−6.8(良く見せる)。補正CV の偏りは「600本へ寄せる」向きなので、葉63/127 のように真の山が600本にあるときは害がない。葉511 では偏りがあっても真の山(約225本)の近くを選べた(損 1.28)。決定13(補正CV)は「葉の比較」で ◎ だが、「本数の比較」では偏りが残ることを CV設計書に書き足す
- 印を動かせる決定は無い。 2ワールド・1世界だけでは、決定18(○)を ◎ にも ✕ にもできない。暫定値として残し、次回やり直す
タスクD(決定)
| # | 決定 | 採った案 | 採らなかった案と理由 | 前提が変わったら |
|---|---|---|---|---|
| 18(印 ○ のまま) | 最終提出は決定15 の葉を lr0.05・600本で作り直した1本 | 低雑音2ワールドでは、本数を選んでも 600本と同じ(損 1.46) | — | 小得・中雑音(決定15 が葉255 を選ぶ世界)で本数選びが −0.5 以上の得を出したら、決定19 と合わせて「600本」を「葉255 以上は補正CV で選ぶ」に替える |
| 19(新設、印 △) | 作り直しの葉が255 以上のときだけ、本数を 200〜600 本から補正CV 最小で選ぶ。それ未満は600本 | 葉255 −0.86±0.25・葉511 −3.66±0.48(2/2)。小さい葉では補正CV が600本を選ぶので、規則を全部の葉にかけても害は無い | (a) fold ごとの早期打ち切り(忍耐50): 方針で +2.17(2/2 悪化)、生CV が 2〜8 楽観。(b) 生CV で本数を選ぶ: 少ない本数を良く見せる偏り(−2〜−7)で葉127 で +1.06。(c) 60点から葉と本数を同時に選ぶ: −0.35±0.35 で差なし、費用は5本を全部 lr0.05 で作る分(Day178 で2.6倍) | 2ワールド・低雑音だけなので △。小得・中雑音で葉255 の得が出なければ取り下げる |
| 早期打ち切りの扱い(決定にはしない、メモ) | 比べる段階でも提出でも fold ごとの早期打ち切りは使わない | 楽観が葉とともに育つ(−2.4 → −8.3)ので、大きい葉を選ばせる向きに偏る | 忍耐を100以上にする: 忍耐∞ でも小さい葉で +0.5〜+1.0 悪いので、忍耐の長さだけでは直らない | val fold が大きい(行数10倍)コンペでは val の揺れが小さくなり、結論が変わりうる |
📊 結果の可視化
1枚目: 決定15 が低雑音で選ぶ葉63/127 では600本が最良なので、本数選びは損を変えない。早期打ち切りは +2.17 悪化。2枚目: 早期打ち切りの CV は葉が大きいほど良く見えすぎる。
🪜 Step-by-Step 解説
Step 1: 予想を先に書く
「5本平均の山は1 fold の山より後ろ」「早期打ち切りは CV が楽観になるが真の損は同じ」と書いてから測った。後者は外れ、真の損も悪かった。
Step 2: 学習し直さずに途中本数を作る
木の塊ごとの寄与を足し上げる(start_iteration)と、一括予測との差は最大 3.0e-14、600本の時点で Day178 の保存物と fold 別予測 0.0・OOF 2.3e-14 で一致した(決定9)。OOF の 2.3e-14 は足し算の順序が違うだけの丸め誤差。
Step 3: 5本平均の山を見る
提出の形(5本平均)で12点の真の誤差を出した。葉127 までは 600本でもまだ下がっている。葉255 は 400〜500本、葉511 は 200〜250本が山。
Step 4: 葉ごとの規則と、方針全体を分けて見る
葉ごとの表(表2)だけ見ると「補正CV で本数を選ぶと −3.66 得」と言いたくなるが、決定15 は低雑音で葉511 を選ばない。方針全体(表5)では得0。どの葉で効くかと、その葉が実際に選ばれるかは別の問い。
Step 5: 早期打ち切りがなぜ負けたかを分ける
止まった本数(表4)と、CV の楽観(表4 最下行)を別々に出した。「早く止まりすぎる」と「止めた fold で測るので良く見える」の2つが重なっている。
Step 6: データが消えたときの書き方
2ワールドしか無いので、決定の印は動かさず、△ の決定19 だけ置いた。予定と実際の差(18 → 2ワールド)と原因を「扱わなかった範囲」に書いた。
📐 数学・統計の補足(文系向け)
なぜ5本平均の山は1本の山より後ろにずれるのか。 本数を増やすと、1本のモデルは偶然まで覚え始める(過学習)。5本の fold モデルは学習データの8割ずつが違うので、覚えた偶然も少しずつ違う。平均するとその偶然の部分が打ち消し合うので、5本平均では「まだ過学習の害が小さい」ところが長く続く。だから山が後ろにずれる。Day178 の1 fold の曲線で「多すぎ」に見えた本数が、5本平均では最良(葉63/127 の600本)だったのはこのため。
早期打ち切りの楽観は「選んだ人が採点する」問題。 val fold で一番良かった本数を選び、同じ val fold で点数をつけると、偶然良かった分まで点数に入る。テストで答えを見てから「この問題だけ採点して」と言うのと同じ。葉が大きいほど本数ごとの点数の揺れが大きく、偶然の上振れも大きくなる(−2.4 → −8.3)。
補正CV が本数比較で偏る理由(仮説)。 補正CV は「5本の予測のばらつき(A_test)」を引く。本数が少ないほどモデルは似通い、A_test が小さくなるので引く量も小さい。一方で、少ない本数の OOF と truth の差の構造は多い本数と違うので、引き算が釣り合わない。今日はこの仮説を3項分解(Day177)で確かめていない。
🏆 Kaggleでの実践的な使い方
- fold ごとの early stopping の CV を、そのまま比較や提出の判断に使わない。 今日のデータでは CV が 2〜8×10⁻⁴ 楽観で、その楽観は大きい木ほど育った。比べるなら本数を固定するか、止める本数を CV の外(別の分割)で決める
- 本数は「提出と同じ形(fold 平均)」で選ぶ。 1 fold の曲線より山が後ろに来る。葉が小さい(〜127)なら、学習率 0.05 の600本は短すぎるくらい
- 本数の調整が効くのは大きい木だけ。 葉255 以上で 600本固定は損(低雑音で 0.86〜4.94)。自分の選ぶ葉がそこに入るかを先に確かめる
- 実験の保存物は /tmp に置かない。 今日は OS 側の片付けで、1時間の計算と過去4日分の保存物が消えた
⚠️ よくある誤解・ミス
| 誤解・ミス | なぜ起こるか | 正しい理解 |
|---|---|---|
| early stopping を使えば本数の調整は済む | 公開ノートブックの定番で、CV も良く見える | 低雑音2ワールドで方針の損が +2.17 悪化。CV は 2〜8 楽観 |
| 1 fold の学習曲線で本数を決める | 1本の曲線が一番手軽 | 提出は5本平均で、山は後ろにずれる(葉63: 1本では 450本付近、5本平均では600本) |
| 補正CV は何を比べても偏らない | 葉の比較で ◎ だった | 本数の比較では少ない本数を悪く見せる(+2.4〜+5.3)。向きが「多い本数」寄りなので害が出にくいだけ |
| 葉ごとの表で得が出れば方針でも得 | 表2 だけ見る | 決定15 がその葉を選ばなければ得は0(表5) |
| 2ワールドの結果で決定を更新する | 数字が出ると使いたくなる | 2ワールド・1世界では印を動かさない。△ の仮決定に留める |
🧭 扱わなかった範囲と理由
- 小得・中雑音と、低雑音 w2-5(予定18 → 実際2ワールド): 6並行で起動し、低雑音 w0・w1 が終わった後(起動から約1時間後、2026-10-12 05時台)に
/private/tmpが丸ごと片付けられた(直前はディスク空き 3.1GB・使用率99%、片付け後は空き 36GB)。今日のジョブ・スクリプト・raw179 に加えて、Day175〜178 の保存物(raw175/176/178)と Day177 の uv venv も消えた。決定15 の葉選びに要る lr0.1 の保存物が無いため、残りは今日のうちに回し直せなかった。本題(決定15 が葉255 を選ぶ世界で本数選びが効くか)は未計測 - 作り直しの手順: 次回は保存物を
/tmpではなく~/AI/lab/学習/Engineer/DataScience/Kaggle/work/(今日作成。HTML 生成のwork/d179/mk_html179.pyを置いた)に置き、lr0.1 の葉31〜511(決定15 用)と lr0.05 の途中本数を1本のスクリプトで作る。1ワールド約20〜40分 × 18 で、Mac mini なら半日以内の見込み(M1 での実測 1,130秒/ワールドから導出、中雑音は未実測) - 補正CV の本数方向の偏りの分解(Day177 の3項): 未計測
- 学習率 0.02 以下、seed を変えた独立な10分割、mcs 5・10、乱数ありの候補(決定14)、候補数 K と選択の上振れ、系統別の m、公開LB と2本目の枠、avg3、OOF側とtest側の seed の揺れ、noKeytel・raw7、入れ子CV との比較、Day170 の出し直し、Day165 の SE 個数差、Day162 の選択バイアス、真の効果0の偽採用率: 持ち越し
- 原典照合: LightGBM の
early_stoppingAPI の説明は今日照合した。Nadeau & Bengio・Krogh & Vedelsby は未照合のまま - 実データ(S5E5): 縮小シミュレータの上の数字のみ
🚀 次のステップ
- 発展: 早期打ち切りの止める本数を「別の分割の OOF」で決めると、楽観と早すぎる停止の両方が消えるか
- 発展: 補正CV の本数方向の偏り(+2.4〜+5.3)を Day177 の3項に分けて、どの項が作っているか
- 次回予告: Day 180 — Playground Series 実戦投入⑮(今日消えた分のやり直し: 保存先を tmp の外に移し、lr0.1 の葉31〜511 と lr0.05 の途中本数12点を1本のスクリプトで、小得・中雑音から先に回す。決定19 を小得・中雑音で確かめ、決定18 の「600本」を替えるか決める)。月替わりテーマ3「画像(CV)系コンペへの応用」は 10/25 から
📝 自己評価(解いた後に記入)
自分の回答・気づき・メモ: