【Kaggle挑戦記】Spaceship Titanic 攻略 #8:アルゴリズムの「換装」。LightGBM投入で自己ベストを更新せよ
1. 今回の戦略:データの加工ではなく「エンジン」を変える
前回、外れ値を削りすぎてスコアを落とすという「情報の欠損」を経験しました。そこから得た教訓は、「複雑なデータは、より強力なアルゴリズムに委ねるべき」ということ。 今回は、データのクリーニングは最高得点(0.792)時の最小限に留め、学習器を「ランダムフォレスト」から、現代のKaggle三種の神器の一つ「LightGBM」へと載せ替えました。
なぜ LightGBM なのか?
- 勾配ブースティングの威力: 一度に学習するランダムフォレストと違い、前のミスを修正するように段階的に学習するため、より緻密な境界線を見極められます。
- 外れ値への耐性: データの「歪み」を無理に直さなくても、アルゴリズム側で最適に処理してくれます。
2. 【実装】最高得点ロジック + LightGBM
支出の論理補完は維持しつつ、学習エンジンを最新鋭に積み替えたコードです。
import pandas as pd
import lightgbm as lgb
# データの読み込み
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
# 支出補完とCryoSleepの推論(最高スコア時のロジックを継承)
spend_cols = ["RoomService", "FoodCourt", "ShoppingMall", "Spa", "VRDeck"]
for df in [train, test]:
df[spend_cols] = df[spend_cols].fillna(0)
total_spend = df[spend_cols].sum(axis=1)
df.loc[(df['CryoSleep'].isnull()) & (total_spend > 0), 'CryoSleep'] = False
df.loc[(df['CryoSleep'].isnull()) & (total_spend == 0), 'CryoSleep'] = True
df['Age'] = df['Age'].fillna(df['Age'].median())
# 特徴量準備
features = ["CryoSleep", "Age", "RoomService", "FoodCourt", "ShoppingMall", "Spa", "VRDeck"]
X = pd.get_dummies(train[features], drop_first=True)
y = train["Transported"].astype(int)
X_test = pd.get_dummies(test[features], drop_first=True)
# アルゴリズム変更:LightGBM
model = lgb.LGBMClassifier(n_estimators=100, learning_rate=0.05, random_state=1)
model.fit(X, y)
# 予測・提出
predictions = model.predict(X_test)
output = pd.DataFrame({'PassengerId': test['PassengerId'], 'Transported': predictions.astype(bool)})
output.to_csv('sub_lightgbm_v1.csv', index=False)
3. 実行結果:壁を突き抜ける一撃
Macのターミナルで実行し、生成されたファイルをKaggleへ。結果は、これまでの停滞を吹き飛ばすものでした。
Random Forest (Best) : 0.79214 LightGBM (New) : 0.79611 (UP! )
ついに **0.796**。0.8という大台まで、あとわずか **0.004** ポイント。データの切り分け方を変えるのではなく、計算の「深さ」と「正確性」を上げたことが、この微差にして大きな前進を生みました。
4. まとめ:エンジニアとしての決断
「データの質」を追及することも大切ですが、時には「使う道具」を進化させることも重要だと痛感しました。LightGBMという新しい武器を手に入れた今、視界が開けました。 次は、この強力なエンジンに、これまで温めてきた「Cabin(客室)の分解データ」を流し込みます。物理的な位置情報が加われば、0.8突破は確実です。
道具を磨き、知識を積み、一歩ずつ。Kaggleの頂は見え始めてきた。
PR