学んだことでTitanic: Machine Learning from Disasterにチャレンジ

前回は書籍「scikit-learnとTensorFlowによる実践機械学習」の2章をやりました。今回はそこで学んだ前処理、パイプラインなどを使って、Kaggleの課題にランダムフォレストでチャレンジしてみます。

できたコードがこちら。


import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import OneHotEncoder, StandardScaler, Imputer
from sklearn.ensemble import RandomForestRegressor

df_train = pd.read_csv('../input/train.csv')
df_test = pd.read_csv('../input/test.csv')

#数値と文字列の属性を分ける
X_train_cat_attributes = ["Sex", "Ticket"]
X_train_num_attributes = ["Pclass", "Age", "SibSp", "Parch", "Fare"]

#不要な属性を削除
X_train = df_train.drop(["PassengerId", "Survived"], axis=1)
Y_train = df_train["Survived"]

X_test = df_test.drop(["PassengerId"], axis=1)

#パイプラインに流し込んだときに不要な属性を削除する関数
class DataFrameSelector(BaseEstimator, TransformerMixin):
    def __init__(self, attribute_names):
        self.attribute_names = attribute_names
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        return X[self.attribute_names].values

#数値属性を処理するパイプライン。       
num_pipeline = Pipeline([
    ('selector', DataFrameSelector(X_train_num_attributes)),
    ('imputer', Imputer(strategy="median")), #欠損値を埋める
    ('std_scaler', StandardScaler()) #正規化する
])

#文字列属性を処理するパイプライン
cat_pipeline = Pipeline([
    ('selector', DataFrameSelector(X_train_cat_attributes)),
    ('cat_encoder', OneHotEncoder(sparse=False)), #数値に変換する
])

#複数のパイプラインに流し込んで結果を結合してくれる便利なもの
full_pipeline = FeatureUnion(transformer_list=[
    ("num_pipeline", num_pipeline),
    ("cat_pipeline", cat_pipeline),
])

#正規化などを行う
full_pipeline.fit(pd.concat([X_test, X_train], ignore_index=True))

#データの前処理
X_train_prepared = full_pipeline.transform(X_train)

#ランダムフォレストで学習
forest_reg = RandomForestRegressor()
forest_reg.fit(X_train_prepared, Y_train)

X_test_prepared = full_pipeline.transform(X_test)

#推測と結果の出力
Y_prediction = forest_reg.predict(X_test_prepared)
submission = pd.DataFrame({
'PassengerId': df_test['PassengerId'],
'Survived': Y_prediction.round().astype(int)
})
submission.to_csv('submission.csv', index=False)

結果

スコアが0.77511になった。最初に用意されているgender_submission.csvが0.76555なのでそれを上回ることができ、データ分析しないよりはましだったと言える結果がでた。

気になったこと

パイプラインのDataFrameSelectorあたりの実装が野暮ったく感じるけどこんなもんなんだろうか

感想と次にやること

これまでできるようになったのは「Kaggleのチュートリアルの通りやる方法」と「scikit-learnとTensorFlowによる実践機械学習の2章のやり方」の2つ。その二つの道具を使って、タイタニックの問題を処理した。
チュートリアルと本の写経から離れたことで、実は理解できていないという箇所が発見でき改めて復習できたし、単純な問題とはいえ自力で結果を出すことができて自信になった。

同じコードで決定木も試したら決定木の方がスコアがよかった。パラメータの調整などに進みたい。

scikit-learnとTensorFlowによる実践機械学習

scikit-learnとTensorFlowによる実践機械学習