機械学習勉強中の文系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 でした。
精進せねば。