【Kaggle挑戦記】Spaceship Titanic 攻略 #5:ドメイン知識の投入。支出額から「冷凍睡眠」を逆算せよ
1. 今回の作戦:欠損値を「推理」で埋めるハイブリッド戦略
前回、項目を削ることで 0.79120 まで到達しました。さらなる高みを目指すため、今回は「データの裏側にある事実」をコードに落とし込みます。ターゲットは、最重要項目である「支出額」と「CryoSleep(冷凍睡眠)」の連動性です。
宇宙船の物理法則(ドメイン知識)
- 事実1: 施設利用(Spa等)のデータが欠損しているのは、単に「使っていない(0円)」からではないか?(中央値で埋めるのは不自然)
- 事実2: 冷凍睡眠(CryoSleep)中の乗客はカプセル内で眠っており、物理的に1円も使えないはず。
- 結論: まず支出額の欠損を「0」で埋め、その合計額が1円でもあれば「起きていた(False)」、0円なら「寝ていた(True)」と推論して、CryoSleepの欠損を埋める。
2. 【実装】支出と睡眠をセットで補完する「論理補完」コード全文
「とりあえず埋める」から「根拠を持って埋める」へ。Macのターミナルで実行した、論理的整合性を重視したコードです。
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
# 1. データの読み込み
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
# 2. 支出系とCryoSleepの同時補完ロジック
for df in [train, test]:
spend_cols = ["RoomService", "FoodCourt", "ShoppingMall", "Spa", "VRDeck"]
# 【処理A】支出の欠損は「使っていない(0円)」とみなす
df[spend_cols] = df[spend_cols].fillna(0)
# 支出の合計を計算
total_spend = df[spend_cols].sum(axis=1)
# 【処理B】支出額からCryoSleep(冷凍睡眠)を逆算
# 1円でも使っていれば、寝ているはずがない(False)
df.loc[(df['CryoSleep'].isnull()) & (total_spend > 0), 'CryoSleep'] = False
# 合計0円なら、寝ていた可能性が極めて高い(True)
df.loc[(df['CryoSleep'].isnull()) & (total_spend == 0), 'CryoSleep'] = True
# その他の項目(Ageなど)は中央値で補完
df['Age'] = df['Age'].fillna(df['Age'].median())
# 3. 特徴量の選択(筋肉質な7項目)
features = ["CryoSleep", "Age", "RoomService", "FoodCourt", "ShoppingMall", "Spa", "VRDeck"]
# 学習データの準備(CryoSleepをTrue/Falseの2値に絞り込む)
X = pd.get_dummies(train[features], drop_first=True)
y = train["Transported"]
X_test = pd.get_dummies(test[features], drop_first=True)
X, X_test = X.align(X_test, join='left', axis=1, fill_value=0)
# 4. 学習
model = RandomForestClassifier(n_estimators=100, random_state=1)
model.fit(X, y)
# 5. 提出用ファイル出力
predictions = model.predict(X_test)
pd.DataFrame({'PassengerId': test['PassengerId'], 'Transported': predictions}).to_csv('sub_logic_hybrid.csv', index=False)
3. 結果:論理の正しさが生んだ「微増」の意味
Macのターミナルを叩き、運命の結果を確認しました。
Public Score: 0.79214(前回比 +0.00094)
数値としての伸びはわずかですが、エンジニアとしてこの結果には大きな意味を感じています。
- 確信に変わった「0円」の意味: これまで適当に埋めていた欠損値を論理的に埋めた上でスコアが上がったということは、この宇宙船のルール(ドメイン知識)を正しく捉え始めている証拠です。
- 逃げ道の封鎖: 「Unknown」という不純物を消してなお精度が向上したことは、モデルがより普遍的なパターンを学習できていることを意味します。
4. 次のフェーズ:限界の先へ
「引き算」も「欠損値の論理補完」もやり遂げました。Baselineは今、極限まで磨かれています。これ以上の精度向上を狙うには、いよいよ新しい情報の創造、つまり「特徴量エンジニアリング(足し算)」が必要です。
「個別の支出」ではなく「合計支出」はどう効くのか?あるいは「家族」の存在は? 0.8の壁を突破するための、本質的なクリエイティビティの戦いが始まります。
データの向こう側にある真実を一つずつ拾い集め、コードに落とし込む。地道な作業ですが、これが確実な勝利への唯一の道。さあ、頑張ろう!
PR