LoginSignup
5
6

More than 5 years have passed since last update.

【Kaggle】タイタニック生存予想をとりあえずsubmit

Posted at

機械学習勉強中の文系Webディレクターです。
文系のくせにずっと機械学習に興味があり、本格的に手を出し始めました。
近いうちにゴリゴリとモデル構築とかを行える人になりたい。

なにはともあれとりあえずKaggleという流れがあるらしいのでやってみました。
Submitまでは正直簡単です。問題はこの後の精度向上。

大枠の流れは下記のようになります。

  • IDデータ、正解ラベル、特徴データに分類する
  • カテゴリ変数(データが文字のもの)をOneHotEncodingで数値データとして扱えるようにする
  • 欠損値(NaN)はそのままでは支障が出るため、欠損値は補完する
  • 色々なモデル・パラメーターでベストなモデルを探す
  • 訓練データと同じ前処理をテストデータにも行う
  • テストデータに対して予測を実行

訓練データを使ったモデル構築

train.py
# 関連ライブラリのインポート
import numpy as np
import pandas as pd
from pprint import pprint

#未知データ対策のため、データ型を指定して読み込み
df = pd.read_csv('train.csv', header=0,
                dtype={'Name':object,
                        'Sex':object,
                        'Ticket':object,
                        'Fare':object,
                        'Cabin':object,
                        'Embarked':object})

# set variable roles
ID = df.loc[:, ['PassengerId']]
X  = df.drop(['PassengerId', 'Ticket', 'Cabin','Name' ,'Survived'], axis=1) #学習に不要そうなものは削除
y  = df.loc[:, ['Survived']]

## 前処理
from sklearn.preprocessing import Imputer # 欠損処理
# one-hotエンコーディングでカテゴリ変数を数値に変換
OHE_COLS = ['Sex', 'Embarked']
X_ohe = pd.get_dummies(X, dummy_na=True, columns=OHE_COLS)
# Imputer(欠損値補完※今回は中央値を使用)
imp = Imputer(missing_values='NaN',strategy='mean',axis=0)
imp.fit(X_ohe)

X_ohe_columns = X_ohe.columns.values
X_ohe = pd.DataFrame(imp.transform(X_ohe), columns=X_ohe_columns)
X_fin = X_ohe #特徴量が膨大ならRFEなどで絞り込むが、今回はなし

#グリッドサーチでの最適解らしきものを探す
from sklearn.preprocessing import StandardScaler # 標準化
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC, LinearSVC #サポートベクタマシン
from sklearn.linear_model import LogisticRegression,RidgeClassifier # リッジ回帰
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier #アンサンブル
from sklearn.pipeline import Pipeline # パイプライン
from sklearn.metrics import r2_score,f1_score #R2スコア

# パイプラインの設定
pipe_RidgeClassifier = Pipeline([('scl',StandardScaler()),('est',RidgeClassifier(random_state=0))])
pipe_RandomForestClassifier = Pipeline([('scl',StandardScaler()),('est',RandomForestClassifier(random_state=0))])
pipe_GradientBoostingClassifier = Pipeline([('scl',StandardScaler()),('est',GradientBoostingClassifier(random_state=0))])
pipe_SVC = Pipeline([('scl', StandardScaler()),('est',SVC(random_state=0))])
pipe_LinearSVC = Pipeline([('scl', StandardScaler()),('est',LinearSVC(random_state=0))])

# パラメータグリッドの設定
param_grid_RidgeClassifier = {'est__solver':['auto', 'svd', 'cholesky', 'lsqr', 'sparse_cg', 'sag', 'saga']}
param_grid_RandomForestClassifier = {'est__n_estimators':[10,25,50,100],'est__max_depth' : [5, 20, 50, 100]}
param_grid_GradientBoostingClassifier = {'est__n_estimators':[50,100],'est__subsample':[0.8, 1.0]}
param_grid_SVC = {'est__C':[0.1,1.0,10.0,100.0], 'est__degree':[1,3,5]}
param_grid_LinearSVC = {'est__C':[0.1,1.0,10.0,100.0], 'est__loss':['hinge','squared_hinge']}

# # 学習
algs = [
    {
        'name' : 'RidgeClassifier',
        'pipe' : pipe_RidgeClassifier,
        'param': param_grid_RidgeClassifier
    },
    {
        'name': 'RandomForestClassifier',
        'pipe' : pipe_RandomForestClassifier,
        'param': param_grid_RandomForestClassifier
    },
    {
        'name': 'GradientBoostingClassifier',
        'pipe' : pipe_GradientBoostingClassifier,
        'param' : param_grid_GradientBoostingClassifier
    },
    {
        'name': 'SVC',
        'pipe' : pipe_SVC,
        'param' : param_grid_SVC
    },
    {
        'name': 'LinearSVC',
        'pipe' : pipe_LinearSVC,
        'param' : param_grid_LinearSVC
    }
]

best_estimator = []

for alg in algs:
    print('----------------------------------------------------------------------------------------------')
    name, pipe, param = alg['name'], alg['pipe'], alg['param']
    print('アルゴリズム:%s' % name)
#     print('探索空間:%s' % param)
    gs = GridSearchCV(estimator=pipe, param_grid=param, scoring='f1', cv=3)
    gs = gs.fit(X_fin, y.as_matrix().ravel())
    best_estimator.append([gs.best_estimator_, gs.best_score_])   # gs.best_estimator_でベストモデルを呼び出せる
    print('Best Score %.6f\n' % gs.best_score_) # gs.best_score_で上記ベストモデルのCV評価値(ここではf1スコア)を呼び出せる

テストデータを使って検証

test.py
#テストデータ前処理
df_s = pd.read_csv('/Users/kamitaku/Desktop/Kaggke_Titanic/test.csv', header=0,
                dtype={'Name':object,
                        'Sex':object,
                        'Ticket':object,
                        'Fare':object,
                        'Cabin':object,
                        'Embarked':object})

ID_s = df_s.loc[:, ['PassengerId']]
X_s  = df_s.drop(['PassengerId', 'Ticket', 'Cabin','Name'], axis=1) # Loan_IDはKey情報なので特徴量ベクトルから削除

X_ohe_s = pd.get_dummies(X_s, dummy_na=True, columns=OHE_COLS)
X_fin_s = pd.DataFrame(imp.transform(X_ohe_s), columns=X_ohe_columns)

#予測
from datetime import datetime
best_model = best_estimator[0][0] #ベストなモデルを選択
predictions = best_model.predict(X_fin_s)

submission = pd.DataFrame({
        "PassengerId": ID_s['PassengerId'],
        "Survived": predictions
    })
now = '{0:%Y%m%d%H%M%S}'.format(datetime.now())
submission.to_csv('submission' + now + '.csv', index=False)

結果としては、75.8%の正解率で4260/10606 でした。
精進せねば。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6