Day 143 — コンペ戦略③ — チームマージ(チーム戦)の意思決定

2026-09-02 金 / Phase 6(Grandmaster、テーマ4群 の 3日目) 戦略→コーディング チームマージ / 多様性ボーナス / ブレンドの質

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

🔁
Day141「最終提出2枠の選び方」、Day142「探索と活用のトレードオフ」に続き、今日はコンペ進行中のもう一つの重要な意思決定 — チームマージ(他の参加者とチームを組むかどうか) — を扱う。「1人で最後まで戦うか、途中でパートナーと合流するか」を、精神論ではなく実力・多様性・統合コスト・失敗リスクをシミュレーションして数値で比較する。
⏰
重要な事実: ほとんどのコンペにはチームマージ期限が設定されており、これは最終提出期限より数日〜1週間ほど前に来る。「終盤で急にパートナーを探す」ことはできず、マージするなら比較的早めに動く必要がある。マージの本質的な価値は「モデルの本数が増えること」ではなく、自分とは違うアプローチを取るパートナーの予測を組み合わせることで生まれるアンサンブル効果にある。
キーワード直感的な説明
チームマージ(team merge)複数の参加者が一つのチームとして合流し、以降は共同で最終提出を決める仕組み。マージ期限は最終提出期限より前に来る
多様性ボーナス(ensemble diversity gain)予測の相関が低い(間違え方が違う)モデル同士を混ぜるほど得られる、単独のスコアの平均以上の改善効果
相関(correlation, ρ)2つのモデルの予測がどれだけ似た間違え方をするかの指標。今日は0に近いほど多様性ボーナスが大きいと設定する
統合コスト(integration cost)マージ後、コード・CV・特徴量をすり合わせるのに使う日数。この間は実質的に改善が止まる
ブレンドの質実力差を考慮して重み付けする「最適ブレンド」か、単純に平均する「素朴ブレンド」かの違い。同じパートナーでも結果が変わる

🎯 問題

タスクA(戦略・記述)

コンペ終了まで残り10日、CVスコアは伸び悩んでいる。あなたよりやや実力が上か下かはっきりしない、手法の異なる参加者からマージの誘いが来ている。以下3点をそれぞれ2〜3文で説明する。

1
実力の上下がはっきりしない不確実性の中でも、マージを検討する価値があるとしたら、その根拠は何か(実力差ではなく何に着目すべきか)
2
マージするなら「早め(2日目)」と「遅め(7日目)」のどちらが望ましいか、統合コストと残り日数の関係から説明する
3
「単純平均」ブレンドと「実力差を考慮した重み付け」ブレンドとで、マージのリスクはどう変わるか

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

項目値
残り日数D_TOTAL = 10
自分の現在のCV・ソロの逓減曲線OWN_SCORE=0.800 / SOLO_GAIN_BASE=0.0020 / SOLO_DECAY=0.85
パートナーの実力Normal(PARTNER_MEAN=0.800, PARTNER_STD=0.015)
相関・多様性ボーナスρ ~ Uniform(0.3, 0.9) / bonus = ENSEMBLE_GAIN_MAX(0.010) × (1-ρ)
統合コスト・失敗確率INTEGRATION_DAYS = 2 / P_MERGE_FAIL = 0.15
比較する条件m=2(早め)/m=7(遅め) × blend=optimal/naive
反復回数N_SIM = 20000
import numpy as np

N_SIM = 20000
D_TOTAL = 10

OWN_SCORE = 0.800
SOLO_GAIN_BASE = 0.0020
SOLO_DECAY = 0.85

PARTNER_MEAN = 0.800
PARTNER_STD  = 0.015

RHO_LOW, RHO_HIGH = 0.3, 0.9
ENSEMBLE_GAIN_MAX = 0.010

INTEGRATION_DAYS = 2
TEAM_GAIN_BASE = SOLO_GAIN_BASE * 1.5

P_MERGE_FAIL = 0.15
B1
gain(base, decay, start, length)で「day番号startからlength日分、逓減しながら積み上げた改善」を計算する。途中で計算を打ち切っても再開時に逓減がリセットされないようstartを使う
B2
マージ時点`m`・ブレンド方式(optimal/naive)を引数に取るsimulate_mergeを実装。マージ失敗(確率P_MERGE_FAIL)ならソロの逓減曲線をm日目から継続、成功ならブレンド後に新しい枠組みとして逓減する
B3
m=2/7 × optimal/naiveの4通りで平均最終CV・標準偏差・P(beat_solo)を比較する
B4
naiveブレンドについて、パートナーが弱かった場合/強かった場合それぞれのP(beat_solo)を分けて計算する
B5
(追加検証)P_MERGE_FAILとINTEGRATION_DAYSを変化させたときのP(beat_solo)の変化を調べる
B6
(考察): マージのタイミングとブレンドの質、P(beat_solo)への影響が大きいのはどちらか、実測を根拠に150字程度で結論づける

💡 ヒント

ヒント1方向性

タスクAの1.は「実力の上下は事前に分からない」という不確実性をリスクではなく多様性の情報源として捉え直せるかがポイント。2.は統合コストで残り日数を消費することと、残った日数でどれだけ取り返せるかを天秤にかけること。タスクBは、Day142の「逓減する改善」を日数をまたいで継続的に計算する部分と、マージ時点で新しく始まる「多様性ボーナス」を組み合わせる2階建ての設計がポイント。マージ失敗時にソロの逓減曲線をリセットしないよう特に注意する。

ヒント2アプローチ
  • gain()はbase * decay**start * (1 - decay**length) / (1 - decay)という閉じた式でも書けるが、np.arange(start, start+length)を使ったループ和の方が今日は分かりやすい
  • マージ失敗かどうかはrng.random(N_SIM) < P_MERGE_FAILの真偽値配列として扱い、np.where(fail, fail_final, success_final)でベクトル演算にまとめる
  • 「弱いパートナーに絞ったP(beat_solo)」はweak = partner_score < own_at_mergeのブールマスクを作り、final[weak]に対して集計する
  • 感度分析は他の設定を固定し、m=2・naiveブレンドに揃えて比較すると読み取りやすい
ヒント3コード骨格
def gain(base, decay, start, length):
    if length <= 0:
        return 0.0
    i = np.arange(start, start + length)
    return np.sum(base * (decay ** i))

def simulate_merge(m, rng, blend_mode="optimal",
                    integration_days=INTEGRATION_DAYS, p_fail=P_MERGE_FAIL):
    own_at_merge = OWN_SCORE + gain(SOLO_GAIN_BASE, SOLO_DECAY, 0, m)
    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 - m - integration_days, 0)
    fail = rng.random(N_SIM) < p_fail

    success_final = blended + gain(TEAM_GAIN_BASE, SOLO_DECAY, 0, remaining)
    fail_final = own_at_merge + gain(SOLO_GAIN_BASE, SOLO_DECAY, m, remaining)  # リセットしない

    final = np.where(fail, fail_final, success_final)
    return final, own_at_merge, partner_score

✅ 模範解答

for m, label in [(2, "merge_early"), (7, "merge_late")]:
    for mode in ["optimal", "naive"]:
        rng = np.random.default_rng(0)
        final, own_at_merge, partner_score = simulate_merge(m, rng, mode)
        weak = partner_score < own_at_merge
        print(f"{label} blend={mode} mean={final.mean():.5f} P(beat_solo)={(final>solo_final).mean():.3f}")

# ============ 実測結果 ============
# solo_only final=0.81071
#
# merge_early(m=2) blend=optimal  mean=0.82224 std=0.00878 P(beat_solo)=0.850 | weak_share=0.595 P(beat_solo|weak)=0.855 P(beat_solo|strong)=0.841
# merge_early(m=2) blend=naive    mean=0.81701 std=0.00771 P(beat_solo)=0.713 | weak_share=0.595 P(beat_solo|weak)=0.626 P(beat_solo|strong)=0.841
#
# merge_late(m=7)  blend=optimal  mean=0.81722 std=0.00627 P(beat_solo)=0.850 | weak_share=0.722 P(beat_solo|weak)=0.853 P(beat_solo|strong)=0.840
# merge_late(m=7)  blend=naive    mean=0.81125 std=0.00710 P(beat_solo)=0.460 | weak_share=0.722 P(beat_solo|weak)=0.314 P(beat_solo|strong)=0.840
🧭
タスクB-6: 考察 — ブレンドの質(optimal vs naive)の方がマージのタイミング(早め vs 遅め)よりP(beat_solo)への影響が大きかった。optimalブレンドはタイミングによらずP(beat_solo)≈0.850(≈1−P_MERGE_FAIL)で一定だったのに対し、naiveブレンドはタイミングによって0.713(早め)〜0.460(遅め)まで大きく変動した。「マージして損をしない」ブレンド設計そのものが、タイミングの巧拙より重要だと言える。

📊 結果の可視化

4条件それぞれの P(beat_solo)(ソロを上回った確率) 0 0.850早め+optimal 0.850遅め+optimal 0.713早め+naive 0.460遅め+naive → optimalブレンドはタイミング不問で0.850。naiveブレンドはタイミング次第で大きく劣化する

naiveブレンドを、パートナーの強弱で分けたP(beat_solo):

早め・パートナー弱い
0.626
早め・パートナー強い
0.841
遅め・パートナー弱い
0.314
遅め・パートナー強い
0.840

遅めマージ・naive・弱いパートナーの組み合わせが最悪(0.314)。統合後に取り返す時間がほぼ残らないため

条件平均最終CVstdP(beat_solo)
早め + optimal0.822240.008780.850
遅め + optimal0.817220.006270.850
早め + naive0.817010.007710.713
遅め + naive0.811250.007100.460
(参考)solo_only0.81071——

🪜 Step-by-Step 解説

1なぜgain()にstart引数を持たせるのか

success_final = blended + gain(TEAM_GAIN_BASE, SOLO_DECAY, 0, remaining)
fail_final = own_at_merge + gain(SOLO_GAIN_BASE, SOLO_DECAY, m, remaining)
🧵
なぜこうするか: マージが失敗しても「振り出しに戻る」わけではなく、それまでソロで積み上げた実力の続きから再開する。gain()が常にstart=0から計算する実装だと、「マージに失敗して統合日数を失ったのに、ソロの逓減曲線だけは若返る」という非現実的な有利さが生まれてしまう。失敗時はstart=mとしてm日目の続きから逓減を継続させ、「統合日数だけ純粋に損をする」現実的なペナルティにしている。成功時はチームとして新しい枠組みが始まるとみなしstart=0から改めて逓減曲線を描く。

2なぜoptimalブレンドは「成功すれば必ずソロに勝つ」のか

# merge_early optimal P(beat_solo)=0.850
# merge_late  optimal P(beat_solo)=0.850   ← タイミングによらずほぼ同じ
⚖️
なぜこうするか: blended = max(own_at_merge, partner_score) + ensemble_bonusは、パートナーがどれだけ弱くても少なくとも自分の実力は下回らない上、相関が1未満なら正の多様性ボーナスが上乗せされる。マージが技術的に成功しさえすれば理論上必ずソロ以上からスタートできるため、P(beat_solo)はほぼ「マージが成功する確率(1-P_MERGE_FAIL=0.85)」と一致する。実力差に応じて重みを調整するブレンドさえ徹底できれば、パートナー選びの巧拙よりマージ自体の技術的信頼性の方が結果を左右するという直感をこの一致が裏付けている。

3なぜnaiveブレンドは遅めマージで特に弱いのか

# merge_late naive  P(beat_solo)=0.460  P(beat_solo|weak)=0.314
⏳
なぜこうするか: m=7でマージするとremaining=10-7-2=1日しかチーム活動期間が残らない。単純平均でパートナーに実力を薄められた場合、それを挽回する時間がほとんどない。一方m=2ならremaining=6日あり、多少ブレンドで損をしてもその後のチームとしての改善で取り返せる。「マージのタイミングが遅いこと」の本質的な問題は、統合コストの絶対値というより、ブレンドの失敗を取り返す時間的余裕がなくなることにある。

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

m=2・naiveブレンドに固定し、マージ失敗確率と統合日数をそれぞれ変化させた。

# --- P_MERGE_FAILを変えた場合 ---
# P_MERGE_FAIL=0.00  mean=0.81834  P(beat_solo)=0.841
# P_MERGE_FAIL=0.05  mean=0.81791  P(beat_solo)=0.800
# P_MERGE_FAIL=0.15  mean=0.81701  P(beat_solo)=0.713   ← 今日のメイン設定
# P_MERGE_FAIL=0.30  mean=0.81567  P(beat_solo)=0.586
# P_MERGE_FAIL=0.50  mean=0.81393  P(beat_solo)=0.417

# --- INTEGRATION_DAYSを変えた場合 ---
# INTEGRATION_DAYS=0  mean=0.81894  P(beat_solo)=0.763
# INTEGRATION_DAYS=1  mean=0.81805  P(beat_solo)=0.741
# INTEGRATION_DAYS=2  mean=0.81701  P(beat_solo)=0.713   ← 今日のメイン設定
# INTEGRATION_DAYS=3  mean=0.81578  P(beat_solo)=0.675
# INTEGRATION_DAYS=4  mean=0.81434  P(beat_solo)=0.618
どちらも増えるほどP(beat_solo)は単調に低下する 最小 最大 P_MERGE_FAIL軸 INTEGRATION_DAYS軸
🎚️
マージ失敗確率(P_MERGE_FAIL)を増やすほど、また統合日数(INTEGRATION_DAYS)を増やすほど、P(beat_solo)は単調に低下した。特にP_MERGE_FAILの感度の方がやや大きい(0.00→0.50で0.841→0.417、約半減)。マージ候補の技術的な相性(過去に共同作業した経験、コード規約の近さ、レスポンスの速さ)を事前に見極めることが、統合コストを削る工夫と同じかそれ以上に重要だと言える。

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

🌦️
「相関が低いほど多様性ボーナスが大きい」を、天気予報の例えで理解する:

2人の友人に明日の天気を予想してもらうとします。2人とも「雲の形」だけを見て予想したなら、当たり外れの理由がほぼ同じ(相関が高い)ため、平均を取っても1人だけに聞いた場合とあまり変わりません。一方、1人目は「雲の形」、2人目は「風向きと気圧」というまったく違う手がかりで予想したなら、片方が見落とした変化をもう片方が拾える可能性が上がります(相関が低い)。今日のENSEMBLE_GAIN_MAX * (1 - ρ)は、この「違う手がかりで予想しているほど、平均を取る価値が上がる」という直感を数式にしたものです。
🤝
「単純平均で実力を薄められる」を、綱引きの例えで理解する:

自分1人なら100kgの力を出せるのに、体力が半分しかない人と手をつないで一緒に引っ張ると、単純に力を足して分ければ75kg分の力にしかならない、という状況を想像してください。今日のnaiveブレンド(単純平均)はこれと同じ構造です。実力差を無視して機械的に平均を取ると、強い方の実力の一部が弱い方によって「薄められて」しまいます。optimalブレンド(強い方を軸にする)は、体力が半分の人には軽めのサポート役をお願いし、主に自分の力で引くようなもので、弱いパートナーがいても自分の実力を下回らないようにする工夫に相当します。

🏆 Kaggleでの実践的な使い方

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

原則

📅 マージ期限は最終締切より前

逆算してマージ判断の締切を自分の中で持つ

コンペのルールページでチームマージ期限を確認したら、そこから逆算して「マージするかどうか」を判断する自分の締切を早めに設定しておく。

実例

🧭 実力より先に手法の違いを確認する

相関の低さが多様性ボーナスを左右する

Discussionタブやパートナー候補のノートブックを見て、自分と似た特徴量・モデルか、まったく違うアプローチかを確認する。実力の上下だけでなく相関の低さが価値を左右する。

実務

⚖️ 単純平均で終わらせない

OOF予測で重み付けブレンドを試す

Day141-142までのアンサンブル・Blending・Stackingの技術をチームマージ後のブレンドにもそのまま適用する。ブレンドの質はタイミング以上に結果を左右する。

⚠️ よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
パートナーが自分より弱そうなら、マージしない方が得だと思い込む「実力の合計・平均」で考えてしまう直感今日の実測ではoptimalブレンドの場合、パートナーが弱かったケースでもP(beat_solo|weak)=0.855と、強かったケース(0.841)とほぼ同じ確率でソロを上回った。実力差より相関の低さ(手法の違い)が価値を生む
チームマージはいつでも同じ効果があると思うマージという行為そのものに価値があると考えてしまう今日の実測でnaiveブレンドのP(beat_solo)は早めマージ0.713、遅めマージ0.460と大きく異なった。統合後に残る日数が少ないほどブレンド失敗を取り返せずリスクが高まる
2人の予測を平均するのが最も安全なブレンド方法だと思う「平均を取れば極端な結果を避けられる」という直感今日の実測ではnaiveブレンド(単純平均)はoptimalブレンドよりP(beat_solo)が大きく低い。実力差を考慮しない平均は弱い方に実力を薄められるリスクを常に抱えている
マージのタイミングさえ早ければ、あとは何とかなると思う「早ければ安全」という単純化今日の考察の通り、実測ではブレンドの質(optimal/naive)の方がタイミング(早め/遅め)よりP(beat_solo)への影響が大きかった。タイミングだけでなくブレンド設計にも同じだけ注意を払う必要がある

🚀 次のステップ

  • 発展: 今日はTEAM_GAIN_BASE = SOLO_GAIN_BASE * 1.5(2人分の作業量として1.5倍)と単純化したが、実際には「2人になったからといって改善速度が単純倍になるわけではない」(コミュニケーションコストがかかる)可能性がある。この倍率を1.0〜2.0の範囲で変化させ、マージの価値がどう変わるか試してみましょう。PARTNER_STDを大きくした場合にoptimalブレンドとnaiveブレンドの差がどう変化するかも確認する価値があります
  • 次回予告: Phase6テーマ4「コンペ戦略・Gold 3枚達成プラン」の4日目に入ります。次回はメダル圏内までの距離をどう見積もるか、現在の順位とPublic/Private LBのシェイクアップ幅から、残り日数で必要なCV改善幅を逆算する判断を扱う予定です

Phase 6 の学習マップ(全20テーマ)

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

Day141で最終提出の選び方、Day142で探索/活用トレードオフ、Day143でチームマージの意思決定を実測。次回以降、メダル圏内までの距離の見積もりに進む。

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

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