Day 078 — Kaggleのコンペ構造 — データ・評価指標・提出形式の読み方

2026-06-28 水 / Phase 3 戦略 Kaggle入門 / 評価指標 / 提出形式 / RMSLE

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

🏆
Kaggleのコンペページには「何を・どうやって・何で評価するのか」が全て書いてあります。ページの読み方を知ることが、コンペ参加の最初の一歩です。

📋 コンペページの構成

Overview
コンペ概要・背景・評価指標・賞金・締切
Data
データの説明・ダウンロード・ファイル一覧
Notebooks
参加者が公開したノートブック(インサイトの宝庫)
Discussion
参加者の議論・有効な特徴量のヒント
Leaderboard
現在の順位 (Public LB)
Rules
参加規約・提出上限・チームサイズ制限

最初の5分でやること

  • 1️⃣ Overview タブ → 評価指標を確認(最重要)
  • 2️⃣ Data タブ → ファイル一覧・説明を確認
  • 3️⃣ sample_submission.csv をダウンロード → 提出形式を確認
  • 4️⃣ train.csv を shape / dtypes / describe で把握
  • 5️⃣ Rules タブ → 1日の提出上限・チームサイズを確認

📏 評価指標一覧

⚠️
評価指標を間違えると全ての努力が無駄になります。コンペ開始直後に Overview で必ず確認してください。
評価指標タスク意味最適化の方向対策
RMSE 回帰 予測誤差の二乗平均平方根 最小化 そのまま学習
RMSLE 回帰(価格・量) 対数変換後の RMSE 最小化 log1p(y) → 学習 → expm1
MAE 回帰 予測誤差の絶対値平均 最小化 Huber Loss / Quantile
Log Loss 2値分類 確率予測の誤差 最小化 predict_proba 出力
AUC-ROC 2値分類 ランキング精度 最大化 predict_proba 出力
F1 Score 不均衡分類 Precision × Recall のバランス 最大化 閾値最適化
MAP@K 推薦 上位K件の精度 最大化 ランキング最適化

📊 RMSE vs RMSLE — 誤差の捉え方の違い

住宅価格のような広範囲の値には RMSLE が適切です。なぜか可視化で確認しましょう。

住宅価格の予測誤差: RMSE vs RMSLE の比較 RMSE (絶対誤差) 実際: 500万 予測: 550万 (+50万) 実際: 5000万 予測: 5500万 (+500万) RMSE ペナルティ: +50万 → 小さいペナルティ +500万 → 100倍のペナルティ! 高額物件の誤差がスコアを支配してしまう RMSLE (相対誤差) 実際: 500万 予測: 550万 (10%誤差) 実際: 5000万 予測: 5500万 (10%誤差) RMSLE ペナルティ: +50万 → 同じペナルティ +500万 → 同じペナルティ (10%) 相対誤差が同じなら同等に扱われる

RMSLE: 「10%の誤差」なら高額・低額問わず同じペナルティ。公平な評価。

RMSLE 実装

import numpy as np
from sklearn.metrics import mean_squared_error

def rmsle(y_true, y_pred):
    """Root Mean Squared Logarithmic Error"""
    y_pred = np.maximum(y_pred, 0)  # 負の値をクリップ
    return np.sqrt(mean_squared_error(
        np.log1p(y_true),   # log(1 + y_true)
        np.log1p(y_pred)    # log(1 + y_pred)
    ))

# RMSLE 最適化のための log1p 変換
y_log = np.log1p(y_train)     # 学習時: y を変換
model.fit(X_train, y_log)
preds_log = model.predict(X_test)
preds_final = np.expm1(preds_log)  # 予測後: 逆変換

評価指標別の RMSLE スコア感

ベースライン(平均値のみ)
RMSLE ≈ 0.40
0.40
シンプル線形回帰
RMSLE ≈ 0.20
0.20
log変換 + 特徴量工学
RMSLE ≈ 0.14
0.14
LightGBM + Optuna
RMSLE ≈ 0.12
0.12
上位1% (Gold圏)
RMSLE ≈ 0.10
0.10

House Prices コンペの参考スコア感(値は低いほど良い)

📄 提出形式(Submission Format)

sample_submission.csv を必ずダウンロードして確認します。これがそのまま提出フォーマットです。

典型的な提出形式

タスク種別フォーマット例値の種類
回帰(連続値) Id, SalePrice float(例: 169000.0)
2値分類 PassengerId, Survived 0 or 1
多クラス分類(確率) Id, cat_0, cat_1, cat_2 確率値(合計≒1)
推薦 Top-K customer_id, product_ids スペース区切りのID列
正しい submission.csv の作り方 ベストプラクティス
import pandas as pd
import numpy as np

# ① sample_submission を読み込む
sample_sub = pd.read_csv('sample_submission.csv')
print(sample_sub.head())      # フォーマットを把握
print(sample_sub.columns.tolist())  # カラム名を確認

# ② test['Id'] を使って作成(行インデックスは使わない)
submission = pd.DataFrame({
    'Id': test['Id'],          # ← 必ず Id 列を使う
    'SalePrice': preds_final   # ← 予測値
})

# ③ バリデーション
assert len(submission) == len(sample_sub), "行数が違います"
assert not submission.isnull().any().any(), "NaN が含まれています"

# ④ 保存
submission.to_csv('submission.csv', index=False)  # index=False 必須
print(f"保存完了: {len(submission)} 行")

🏅 Public LB vs Private LB

Public LBPrivate LB
見えるタイミング コンペ期間中(リアルタイム) コンペ終了後(最終順位)
使用データ testデータの 約20〜50% testデータの残り 約50〜80%
信頼性 低(サンプルが少ない) 高(これが本当の実力)
注意点 過学習・シェイクアップの罠 CVスコアと相関することが多い
シェイクダウン vs 安定したモデルのスコア推移 Public LB Private LB Top 5 Top 50 Top 200 Public 3位 Private 150位 😱 Public 40位 Private 35位 ✅ Public LB過学習 CV重視の安定モデル

Public LB を追いすぎると Private LB で大幅ダウンする。CV スコアを信頼するのが鉄則。

🎯 問題

📝
シナリオ: House Prices コンペに参加。評価指標 = RMSLE、提出形式 = Id, SalePrice(連続値)

問題1: RMSLEとRMSEの違いを直感的に説明する

なぜ住宅価格にRMSLEが使われるのか、RMSEとの違いを直感的な言葉で説明してください。

問題2: submission.csv を作成する

import pandas as pd
import numpy as np
from sklearn.linear_model import Ridge

train = pd.read_csv('train.csv')
test  = pd.read_csv('test.csv')
sample_sub = pd.read_csv('sample_submission.csv')

features = ['GrLivArea', 'BedroomAbvGr', 'FullBath']
X_train = train[features].fillna(0)
y_train = train['SalePrice']
X_test  = test[features].fillna(0)

model = Ridge()
model.fit(X_train, y_train)
preds = model.predict(X_test)

# ここから: submission.csv を作成してください

問題3: RMSLE 最適化のための log1p 変換

RMSLE を最適化するには、目的変数を log1p 変換してから学習し、予測後に逆変換します。コードを完成させてください。

# 問題3: log1p 変換を使って RMSLE を最適化するコードを書いてください
# ヒント: np.log1p() でlog変換、np.expm1() で逆変換

💡 ヒント

ヒント1 — 方向性
RMSLEの「L」はLogarithmicの意味です。対数を取ることで、高額物件と低額物件の誤差を「割合」ベースで評価するようになります。「1000円の定食を100円外す」のと「10万円の宿泊費を1万円外す」のが同等(どちらも10%の誤差)という直感です。
ヒント2 — アプローチ
  • 問題2: sample_submission.csv と同じ形式のDataFrameを作成し、test['Id'] と予測値を結合する
  • 問題3: np.log1p(y_train) でlog変換し、予測後に np.expm1(preds) で逆変換する
ヒント3 — コード骨格
# 問題2
submission = pd.DataFrame({
    'Id': test['Id'],
    'SalePrice': preds
})
submission.to_csv('submission.csv', index=False)

# 問題3
y_log = np.log1p(y_train)   # log変換
model.fit(X_train, y_log)
preds_log = model.predict(X_test)
preds_final = np.expm1(preds_log)  # 逆変換

模範解答

問題1: RMSLEとRMSEの違い

💬
RMSE: 予測値と実際値の差の大きさを直接測る。高額物件(5000万円の誤差)と低額物件(500万円の誤差)を同等に扱わず、大きな絶対誤差がスコアを支配する。

RMSLE: 予測値と実際値を対数変換してからRMSEを計算。「相対誤差(割合)」ベースで評価するため、高額・低額問わず10%の誤差は同じペナルティ。

住宅価格にRMSLEが適切な理由: 住宅価格は数百万〜数億円と広範囲にわたるため、RMSEだと高額物件の大きな絶対誤差がスコアを支配してしまう。RMSLEなら「相対的な精度」を公平に評価できる。

問題2: submission.csv の作成

問題2 解答 正解パターン
# ... (上のコードの続き)

# submission.csv の作成
submission = pd.DataFrame({
    'Id': test['Id'],       # test の Id 列をそのまま使う
    'SalePrice': preds      # 予測値
})

# 確認
print(submission.shape)    # (1459, 2)
print(submission.head())
print(f"予測値の範囲: {preds.min():.0f} 〜 {preds.max():.0f}")

# 負の値チェック(住宅価格が負はあり得ない)
assert (preds > 0).all(), "負の予測値が含まれています!"

submission.to_csv('submission.csv', index=False)
print("submission.csv を保存しました")

問題3: RMSLE 最適化(log1p 変換)

問題3 解答 log1p 変換パターン
import numpy as np
from sklearn.metrics import mean_squared_error

def rmsle(y_true, y_pred):
    y_pred = np.maximum(y_pred, 0)
    return np.sqrt(mean_squared_error(np.log1p(y_true), np.log1p(y_pred)))

# ─── RMSE で学習(基準)───
model_rmse = Ridge()
model_rmse.fit(X_train, y_train)
preds_rmse = model_rmse.predict(X_test)

# ─── log1p 変換で学習(RMSLE 最適化)───
y_log = np.log1p(y_train)     # log(1 + y) ← y=0 でも安全

model_rmsle = Ridge()
model_rmsle.fit(X_train, y_log)
preds_log = model_rmsle.predict(X_test)
preds_final = np.expm1(preds_log)  # exp(pred) - 1 ← log1p の逆変換

# 訓練データで効果確認
preds_train_rmse = model_rmse.predict(X_train)
preds_train_log  = np.expm1(model_rmsle.predict(X_train))

print(f"RMSE モデルの RMSLE:  {rmsle(y_train, preds_train_rmse):.4f}")
print(f"RMSLE モデルの RMSLE: {rmsle(y_train, preds_train_log):.4f}")
# → log変換モデルの方がRMSLEスコアが低い(良い)はず

# 提出
submission = pd.DataFrame({'Id': test['Id'], 'SalePrice': preds_final})
submission.to_csv('submission.csv', index=False)

🪜 Step-by-Step: 初回提出までの流れ

1
コンペページを読む(10分)
Overview → 評価指標 / Rules → 提出上限・チームサイズ / Data → ファイル一覧確認
2
データを探索する(30分)
train/test の shape / dtypes / describe / 欠損値の確認 / 目的変数の分布確認
3
ベースラインを作る(1時間)
シンプルなモデルで初回提出 → Public LB スコアを把握(改善の基準点)
4
公開Notebookを読む(1時間)
高スコアのノートブックを精読 → 有効な特徴量・前処理のアイデアを収集
5
Discussion を確認(30分)
リーク・EDA・有効な特徴量のヒントを拾う。上位の人の考え方を学ぶ

🔍 提出前バリデーション

def validate_submission(sub_df, sample_sub_df):
    """提出ファイルの検証"""
    # カラム名チェック
    assert list(sub_df.columns) == list(sample_sub_df.columns), \
        f"カラム名が違います: {sub_df.columns.tolist()}"

    # 行数チェック
    assert len(sub_df) == len(sample_sub_df), \
        f"行数が違います: {len(sub_df)} vs {len(sample_sub_df)}"

    # Id の一致チェック
    assert (sub_df['Id'].values == sample_sub_df['Id'].values).all(), \
        "Id の順序・内容が sample_submission と一致しません"

    # NaN チェック
    assert not sub_df.isnull().any().any(), "NaN が含まれています"

    print("✅ 提出ファイルの検証OK")

validate_submission(submission, sample_sub)

よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
RMSE でチューニングして RMSLE で提出 評価指標を後から気付く コンペ開始直後に Overview で確認。log1p 変換で揃える
submission.csv の列順を間違える sample_submission を確認しない sample_submission と全く同じカラム名・順序で作成
テストデータの Id に行インデックスを使う Id は連番だと思い込む 必ず test['Id'] を使う(行インデックスでなくId列)
Public LB スコアだけを信じる 見えるスコアを最適化したくなる Private LB で大幅ダウンする危険。CV スコアを重視
提出ファイルに NaN が混入する 前処理で欠損値が残る 提出前に submission.isnull().sum() で確認
to_csv で index=True のまま保存 デフォルト値を意識しない 必ず index=False を指定する

🚀 次のステップ

  • 発展: Kaggle Notebooks タブで上位ノートブックを精読する手順(Day 079)
  • 実践: House Prices コンペに実際に登録し、ベースラインを提出してみる
  • 次回予告 (Day 079): Kaggle ノートブックの読み方 — 上位ノートブック精読の手順

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

← Day 077: データリークとは何か 📋 一覧へ戻る