Day 145 — コンペ戦略⑤ — Gold 3枚達成プラン総括

2026-09-04 金 / Phase 6(Grandmaster、テーマ4群 の 5日目・最終日) 戦略→コーディング 統合シミュレーション / 4戦略比較

📚 背景知識(読んでから問題へ)

🔁
Day141〜144は、コンペ終盤で直面する4つの意思決定をそれぞれ独立に扱ってきた。今日はこれらを1つの統合シミュレーションにまとめ、「それぞれ単独では正しい判断」が「全体として最良の一手」を保証しない、という点を実測で確認する。Phase6テーマ4「コンペ戦略・Gold 3枚達成プラン」の最終日。
Dayテーマ出した答え
141最終提出2枠の選び方Public LBの見た目ではなく、CVスコアを信じて選ぶべき
142探索と活用のトレードオフCVが伸び悩んだら、一定の確率で当たる「探索」に賭ける価値がある
143チームマージの意思決定実力差より相関の低さ(多様性)が価値を生む。ブレンドの質が最重要
144メダル圏内までの距離の見積もりシェイクアップとカットオフラインの変動を組み込んで逆算する
⚠️
なぜ統合が必要か: Day141-144はそれぞれ独立した比較軸(P(beat_solo)など)を使っていた。実際の意思決定には「複数の戦略の選択肢を、同じ最終評価指標(今日ならGold圏内到達確率)で横並びに比較すること」が必要である。今日はDay142の探索メカニズム・Day143のマージメカニズム・Day144のシェイクアップメカニズムをすべて1本のコードに統合し、4つの現実的な戦略を同一の物差しで比較する。

🎯 問題

タスクA(戦略・記述)

以下3点をそれぞれ2〜3文で説明する。

1
Day141〜144の4つの意思決定を、それぞれ単独で「正しい判断」を出しただけでは「今のコンペでどの戦略を選ぶべきか」に答えられない理由は何か
2
タスクBの実測で、最もP(medal)が高かった戦略とそうでなかった戦略の差を踏まえ、「探索」と「マージ」のうちどちらがより強い武器だったか、その理由
3
最良の戦略を選んでもなおTARGET_PROBにわずかに届かなかった場合、Day141の「CVを信じる」結論はこの状況でどう位置づけられるか(成長の一手ではなく何の役割を果たすか)

タスクB(実装・シミュレーション)

項目値
残り日数・現在のPublic LBD_TOTAL=10 / PUBLIC_LB_NOW=0.803
Goldカットオフ・シェイクアップ(Day144と同型)GOLD_CUTOFF_PUBLIC_EST=0.815 / SHAKEUP_STD=0.006
カットオフの上昇・目標確率CUTOFF_DRIFT_MEAN=0.003 / TARGET_PROB=0.70
活用(exploit)の逓減改善EXPLOIT_GAIN_BASE=0.0018 / EXPLOIT_DECAY=0.88
探索(Day142方式)EXPLORE_DAYS=4 / P_BREAKTHROUGH=0.25
マージ(Day143方式)MERGE_DAY=2 / P_MERGE_FAIL=0.15
import numpy as np

N_SIM = 20000
D_TOTAL = 10

PUBLIC_LB_NOW = 0.803
GOLD_CUTOFF_PUBLIC_EST = 0.815
SHAKEUP_STD = 0.006
CUTOFF_DRIFT_MEAN = 0.003
CUTOFF_DRIFT_STD = 0.004
TARGET_PROB = 0.70

# 活用(exploit): 逓減する改善(Day141-144と同じ構造)
EXPLOIT_GAIN_BASE = 0.0018
EXPLOIT_DECAY = 0.88

# 探索(explore, Day142方式)
EXPLORE_DAYS = 4
P_BREAKTHROUGH = 0.25
BREAKTHROUGH_LOW, BREAKTHROUGH_HIGH = 0.006, 0.010
MISS_GAIN = 0.0005

# チームマージ(Day143方式)
MERGE_DAY = 2
INTEGRATION_DAYS = 2
PARTNER_MEAN = 0.803
PARTNER_STD = 0.015
RHO_LOW, RHO_HIGH = 0.3, 0.9
ENSEMBLE_GAIN_MAX = 0.010
TEAM_GAIN_BASE = EXPLOIT_GAIN_BASE * 1.5
P_MERGE_FAIL = 0.15
B1
gain(base, decay, start, length)(Day142-144と同じ)を実装する
B2
4つの戦略関数を実装(exploit_only / explore_then_exploit / merge(optimal) / merge(naive))。いずれもN_SIM件の「シェイクアップ前の最終CV」を返す
B3
Day144と同じp_medal(own_final, rng)を実装し、全戦略に共通で適用する
B4
4戦略のown_final平均・標準偏差・P(medal)を計算し、最も高い戦略を特定する
B5
(追加検証1)EXPLORE_DAYSを0〜8で変化させP(medal)の変化を調べる
B6
(追加検証2)MERGE_DAYを1〜8で変化させ、optimal/naive両方のP(medal)を調べる
B7
(追加検証3)最良戦略を起点にDay144と同じ二分探索でrequired_deltaを求める
B8
(考察): 個別の結論を統合してみて、単独の結論だけでは見えなかった何が分かったか、150字程度で結論づける

💡 ヒント

ヒント1方向性

タスクAの1.は「Day141-144それぞれの結論は"その意思決定の中でどちらが良いか"にしか答えていない」点に気づけるかがポイント。2.と3.はタスクBの実測結果を先に出してから、数値を根拠に説明する構成になる。タスクBは、これまで別々の日に書いたコードを1つのファイルに集約し、同じp_medal関数をすべての戦略に適用する点が新しい。Day143のstrategy_mergeは「シェイクアップ前の最終CV」を返すところまでで止め、Day144のp_medalにそのまま渡せる形にすることが設計のポイントである。

ヒント2アプローチ
  • strategy_exploit_onlyは乱数を使わないため、np.full(N_SIM, final)で同じ値をN_SIM件に複製し、他の戦略と同じ形式(N_SIM件の配列)で扱うと後続のp_medalを共通化できる
  • 戦略ごとの比較では、戦略内部の乱数をrng=np.random.default_rng(0)、p_medal内のシェイクアップ乱数をrng2=np.random.default_rng(1)と、独立したシードで固定すると戦略間の違いだけが見やすくなる
  • EXPLORE_DAYSやMERGE_DAYの感度分析は、対象パラメータ以外を固定して関数を呼び出し直せばよい(Day143-144と同じやり方)
  • required_deltaの二分探索は、最良戦略のown_finalに+ deltaを加えてからp_medalに渡す形で実装する
ヒント3コード骨格
def strategy_merge(rng, blend_mode):
    own_at_merge = PUBLIC_LB_NOW + gain(EXPLOIT_GAIN_BASE, EXPLOIT_DECAY, 0, MERGE_DAY)
    partner_score = rng.normal(PARTNER_MEAN, PARTNER_STD, N_SIM)
    rho = rng.uniform(RHO_LOW, RHO_HIGH, N_SIM)
    ensemble_bonus = ENSEMBLE_GAIN_MAX * (1 - rho)

    if blend_mode == "optimal":
        blended = np.maximum(own_at_merge, partner_score) + ensemble_bonus
    else:
        blended = (own_at_merge + partner_score) / 2 + ensemble_bonus

    remaining = max(D_TOTAL - MERGE_DAY - INTEGRATION_DAYS, 0)
    fail = rng.random(N_SIM) < P_MERGE_FAIL

    success_final = blended + gain(TEAM_GAIN_BASE, EXPLOIT_DECAY, 0, remaining)
    fail_final = own_at_merge + gain(EXPLOIT_GAIN_BASE, EXPLOIT_DECAY, MERGE_DAY, remaining)
    return np.where(fail, fail_final, success_final)

def p_medal(own_final, rng):
    own_private = own_final + rng.normal(0, SHAKEUP_STD, N_SIM)
    cutoff_private = (GOLD_CUTOFF_PUBLIC_EST
                       + rng.normal(CUTOFF_DRIFT_MEAN, CUTOFF_DRIFT_STD, N_SIM)
                       + rng.normal(0, SHAKEUP_STD, N_SIM))
    return (own_private > cutoff_private).mean()

✅ 模範解答

for name, fn in strategies.items():
    rng = np.random.default_rng(0)
    own_final = fn(rng)
    rng2 = np.random.default_rng(1)
    p = p_medal(own_final, rng2)
    print(f"{name:24s} mean_final={own_final.mean():.5f} P(medal)={p:.3f}")

# ============ 実測結果(タスクB-4) ============
# A_exploit_only           mean_final=0.81382 std=0.00000 P(medal)=0.327
# B_explore_then_exploit   mean_final=0.81731 std=0.00659 P(medal)=0.467
# C_merge_optimal          mean_final=0.82472 std=0.00875 P(medal)=0.697   ← 最良
# D_merge_naive            mean_final=0.81951 std=0.00765 P(medal)=0.545
#
# best strategy = C_merge_optimal  P(medal)=0.697(TARGET_PROB=0.70にわずかに届かない)
#
# --- 追加検証3: 最良戦略(C_merge_optimal)起点でrequired_deltaを二分探索 ---
# required_delta(C_merge_optimal起点) = 0.00010
🧭
タスクB-8: 考察 — 個別に見ていたときは「今日のコンペで結局どの戦略を選べば良いか」「その戦略で目標確率に届くのか」は分からないままだった。今日1つのシミュレーションに統合したことで、探索(P(medal)=0.467)よりマージ×最適ブレンド(0.697)が大きく優れていること、そしてその最良の戦略でさえTARGET_PROB=0.70にわずか0.003届かず、追加でrequired_delta=0.0001程度の小さな上乗せが必要だったことが実測で分かった。

📊 結果の可視化

4つの戦略の Gold到達確率 P(medal) 比較 TARGET=0.70 A 活用のみ 0.327 B 探索して活用 0.467 C 早期マージ×最適 0.697 ← 最良 D 早期マージ×素朴 0.545 0.0 → 最良のCでもTARGET_PROB=0.70にわずかに届かない(required_delta=0.0001で到達)
戦略mean_finalstdP(medal)
A_exploit_only0.813820.000000.327
B_explore_then_exploit0.817310.006590.467
C_merge_optimal0.824720.008750.697(最良)
D_merge_naive0.819510.007650.545

🪜 Step-by-Step 解説

1なぜ4つの戦略を「同じp_medal関数」に通す設計にするのか

strategies = {
    "A_exploit_only": strategy_exploit_only,
    "B_explore_then_exploit": strategy_explore_then_exploit,
    "C_merge_optimal": lambda rng: strategy_merge(rng, "optimal"),
    "D_merge_naive": lambda rng: strategy_merge(rng, "naive"),
}
🎯
なぜこうするか: Day141-144はそれぞれ異なる比較軸(P(beat_solo)、required_deltaなど)を使っていた。すべての戦略が返す「シェイクアップ前の最終CV(own_final)」という共通の中間形式を経由し、同じp_medal関数に通すことで、初めて4つの戦略を同一の物差し(P(medal))で横並びに比較できる。この「複数の意思決定ロジックの出口を1つの共通形式に揃える」設計は、実務の意思決定システムでも頻出する考え方である。

2なぜB(探索して活用)はC(マージ×最適)に及ばないのか

# B_explore_then_exploit   P(medal)=0.467
# C_merge_optimal          P(medal)=0.697
⚖️
なぜこうするか: Bの探索メカニズムは、当たればUniform(0.006, 0.010)の改善が得られるが、外れればMISS_GAIN=0.0005とほぼ横ばいになる「上振れのみ」の賭けである。一方Cのマージ(optimal)はblended = max(own_at_merge, partner_score) + ensemble_bonusという式により、パートナーがどれだけ弱くても自分の実力を下回らない上に、相関が1未満である限り正の多様性ボーナスが上乗せされる。探索が「上振れ狙い」であるのに対し、マージ(optimal)は「下振れを防ぎながら上振れも取りにいく」非対称に有利な設計になっている。

3なぜ最良の戦略でもTARGET_PROBにわずかに届かないことがあるのか

# C_merge_optimal  P(medal)=0.697   (TARGET_PROB=0.70)
# required_delta(C_merge_optimal起点) = 0.00010
🔬
なぜこうするか: TARGET_PROB=0.70はあらかじめ決めた目標値であり、用意した戦略の実力の範囲内に必ず収まる保証はない。実測では最良の戦略でも0.697と目標にわずか0.003足りなかった。ここで重要なのは「大体近いから良しとする」のではなく、Day144と同じ二分探索の手法をそのまま最良戦略に適用し、「あと具体的にどれだけの上乗せ改善(required_delta)が必要か」を数値で出すことである。今日の実測ではrequired_delta=0.00010とごくわずかであり、「最適に組み合わせれば目標まであと一押し」という具体的で行動可能な結論が得られる。

🔁 追加検証(EXPLORE_DAYS・MERGE_DAYを変化させた場合)

# --- EXPLORE_DAYSを変えた場合(B_explore_then_exploit) ---
# EXPLORE_DAYS=0  mean_final=0.81382  P(medal)=0.327  (=exploit_onlyと同じ)
# EXPLORE_DAYS=2  mean_final=0.81515  P(medal)=0.388
# EXPLORE_DAYS=4  mean_final=0.81731  P(medal)=0.467   ← 今日のメイン設定
# EXPLORE_DAYS=6  mean_final=0.82003  P(medal)=0.557
# EXPLORE_DAYS=8  mean_final=0.82319  P(medal)=0.645

# --- MERGE_DAYを変えた場合 ---
# MERGE_DAY=1 mode=optimal  mean_final=0.82502  P(medal)=0.698
# MERGE_DAY=1 mode=naive    mean_final=0.81991  P(medal)=0.559
# MERGE_DAY=2 mode=optimal  mean_final=0.82472  P(medal)=0.697   ← 今日のメイン設定
# MERGE_DAY=2 mode=naive    mean_final=0.81951  P(medal)=0.545
# MERGE_DAY=4 mode=optimal  mean_final=0.82352  P(medal)=0.671
# MERGE_DAY=4 mode=naive    mean_final=0.81804  P(medal)=0.497
# MERGE_DAY=6 mode=optimal  mean_final=0.82135  P(medal)=0.603
# MERGE_DAY=6 mode=naive    mean_final=0.81556  P(medal)=0.414
# MERGE_DAY=8 mode=optimal  mean_final=0.81800  P(medal)=0.480
# MERGE_DAY=8 mode=naive    mean_final=0.81192  P(medal)=0.301
MERGE_DAYを遅らせるほどP(medal)は低下する(optimal / naive とも) 0 1.0 MERGE_DAY=1 =8 optimal naive
🎚️
EXPLORE_DAYSを増やすほどP(medal)は単調に増加(0.327→0.645)、MERGE_DAYを遅らせるほどoptimal/naiveともP(medal)は単調に減少する(0.698→0.480、0.559→0.301)。ただしMERGE_DAY=1と2の差はごくわずか(optimalで0.698→0.697)であり、「早ければ早いほど際限なく良くなる」わけではなく、統合後の残り日数が十分確保できる範囲では効果が頭打ちになることが分かる。

🧮 数学・統計の補足(文系向け)

🧳
「個別最適の積み上げ」と「共通指標での統合比較」の違いを、旅行プランの例えで理解する:

旅行の計画を立てるとき、「交通手段は新幹線が飛行機より快適」「ホテルはA館がB館より部屋が広い」というように、個々の要素を単独で比較しても、「結局この旅行プラン全体でいくらかかって、何日で行けるのか」は分かりません。旅行プラン全体を比較するには、「総費用」「総所要時間」という共通の物差しで、複数の組み合わせ(新幹線+A館、飛行機+B館、…)を横並びに評価する必要があります。今日のシミュレーションで4つの戦略すべてをP(medal)という同じ指標に通したのは、まさにこの「共通の物差しでプラン全体を比較する」という考え方です。
🛡️
「非対称な賭け」を保険の例えで理解する:

探索(当たれば大きいが外れてもほぼ横ばい)とマージ(optimal, 下振れを防ぎながら上振れも狙う)の違いは、「宝くじを買う」と「損害保険付きの投資をする」の違いに似ています。宝くじは当たれば大きいですが、外れれば掛け金がほぼ戻りません。一方、max(own_at_merge, partner_score)という式は、「パートナーが弱くても自分の実力は失わない」という保険がかかった上で、「相性が良ければボーナスも得られる」投資に近い構造です。同じ「不確実な相手に賭ける」行為でも、下振れの設計次第で全く違うリスク・リターンになることが今日の実測で数値として現れています。

🏆 Kaggleでの実践的な使い方

よく使われるコンペカテゴリ: ☑ 表形式データ(Tabular) / ☑ 自然言語処理(NLP) / ☑ 画像認識(CV) / ☑ 時系列(Time Series)

原則

🧩 意思決定の「出口」を揃えたミニシミュレーターを持つ

共通形式で出力する小さな関数群

探索・マージ・提出戦略それぞれの選択肢を「シェイクアップ前の最終CV」という共通形式で出力する関数群を用意しておくと、コンペ終盤で状況が変わるたびにp_medalに通すだけで最新の判断材料が得られる。

実例

📉 「届かない」結果を隠さず直視する

required_deltaに変換して行動計画へ

今日の実測のように、最も良い戦略を選んでもなお目標確率にわずかに届かないことは現実にも起こる。その場合は具体的な追加目標(required_delta)に変換し、残りの日数で何をすべきかの行動計画に落とし込む。

実務

♻️ 過去の検証ロジックはパーツとして再利用する

使い捨てにしない

探索の当たり外れ、マージの成功/失敗、シェイクアップのノイズなど過去に検証したロジックを関数として再利用可能な形にしておくと、新しいコンペでも同じ枠組みを素早く組み立てられる。

⚠️ よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
個別の意思決定をそれぞれ最適化すれば、全体としても最良になると思い込む「部分が良ければ全体も良い」という直感的な単純化今日の実測では、4つの戦略を同じP(medal)という物差しで比較して初めてC_merge_optimal(0.697)が最有力だと分かった。個別の評価軸のままでは戦略同士を直接比較できない
探索はマージよりリスクが高く、避けるべきだと一律に考える「知らない相手・知らない結果」への漠然とした不安今日の実測では確かに探索(B, 0.467)はマージ(C, 0.697)に劣ったが、これは今日のパラメータ設定に依存する結果であり、常にマージが優れているとは限らない
最良の戦略を選べば必ず目標確率に届くと思う「最善を尽くせば目標は達成される」という願望的思考今日の実測では最良のC_merge_optimalでもP(medal)=0.697とTARGET_PROB=0.70にわずかに届かなかった。届かない場合はrequired_deltaで「あとどれだけ必要か」を数値化することが次の一手につながる
マージのタイミングは早ければ早いほど際限なく良いと思うDay143の「早めマージが望ましい」を単純に延長してしまう今日の追加検証ではMERGE_DAY=1(0.698)とMERGE_DAY=2(0.697)の差はごくわずかであり、直線的に良くなるわけではない。統合後の残り日数の下限を確保できていれば効果は頭打ちになる

🚀 次のステップ

  • 発展: 今日は4つの戦略を独立に評価したが、実際には「探索してからマージする」「マージしてから残り日数でさらに探索する」といった戦略の組み合わせも可能である。strategy_mergeのsuccess_finalの中にBの探索メカニズムを組み込んだハイブリッド戦略を実装し、P(medal)がさらに改善するか試してみましょう。また今日はP_MERGE_FAIL=0.15を固定したが、パートナー候補が複数いる場合に「並行して複数人に声をかける」ことで実効的な失敗確率が下がる効果も検証する価値があります
  • 次回予告: Phase6の詳細テーマリスト(1-20、SOTA手法追跡→カスタムアーキテクチャ→高度なアンサンブル→コンペ戦略)を本日で完了しました。roadmap.mdに記載されたPhase6の主要テーマのうち、まだ扱っていない「解法公開・フォーラム — Discussionで上位ソリューションを学ぶ」に次回から取り組む予定です

Phase 6 の学習マップ(全20テーマ・本日で完了)

1-5
SOTA手法追跡・論文実装(完了)
6-10
カスタムアーキテクチャ設計(完了)
11-15
高度なアンサンブル(完了)
16-20
コンペ戦略・Gold3枚達成プラン(本日5/5・完了)

Day141で最終提出の選び方、Day142で探索/活用トレードオフ、Day143でチームマージ、Day144でメダル圏内までの距離の見積もり、Day145でこれら4つを統合して比較した。最良の戦略(早期マージ×最適ブレンド)でもGold到達確率は69.7%と目標の70%にわずかに届かず、あと0.0001程度の上乗せが必要という結論で、Phase6の詳細テーマ表を締めくくった。

📝 自己評価(解いた後に記入)

自分の回答・気づき・メモ: