Kaggleに登録してみたので備忘録を。
初心者ということもあり、まずは王道のタイタニックデータを使った分析をしてみた。
データの前処理
データはKaggle内にあり、TrainとTestにあらかじめ分けられている。
生存有無を予測する2値分類問題であり有名なデータ。
import numpy as np import pandas as pd from scipy import stats #-- import train = pd.read_csv("../input/titanic/train.csv") test = pd.read_csv("../input/titanic/test.csv")
このデータは欠損があるようなので、今回は諸先輩方のブログを参考に中央値と最頻値で補完する。
また、カテゴリ変数は数値化しておく。
###--- 欠損処理 train["Age"] = train["Age"].fillna(train["Age"].median()) #--中央値で補完 train["Embarked"] = train["Embarked"].fillna("S") #-- 最頻値で補完 train["Embarked"].mode() test["Age"] = test["Age"].fillna(test["Age"].median()) #--中央値で補完 test["Fare"] = test["Fare"].fillna(test["Fare"].median()) #--中央値で補完 ###--- カテゴリの数値化 train["Sex"] = train["Sex"].map({'male':0, 'female':1}) train["Embarked"] = train["Embarked"].map({'S':0, 'C':1, 'Q':2}) test["Sex"] = test["Sex"].map({'male':0, 'female':1}) test["Embarked"] = test["Embarked"].map({'S':0, 'C':1, 'Q':2})
※あとから気づいたが、Embarked
はダミー変数化した方が良かった。
pd.get_dummies(train, columns=['Embarked'])
バリデーションデータの準備
Kaggleでは、テストデータ(正解ラベルなし)があらかじめ準備されているため、次の手順で分析してみる。
* 訓練データを訓練&検証データに分割
* F1-スコアでモデル評価
* ベストモデルを用いてテストデータで予測
from sklearn import model_selection Xval = ["Pclass", "Sex", "Age", "Fare", "Embarked"] df_y = train["Survived"].values df_X = train[Xval].values train_X, valid_X, train_y, valid_y = model_selection.train_test_split(df_X, df_y, random_state=19) test_X = test[Xval].values
モデル作成
初めてなので色々なモデルを試してみた(グリッドサーチ、ランダムサーチなどはしていない)。
順番に決定木、ランダムフォレスト、ロジスティック回帰(L2正則化、L1正則化、両方0.5ずつ)、線形サポートベクターマシーン(L2正則化、L1正則化)、サポートベクターマシーン(カーネル:Linear、rbf、poly、sigmoid)。
from sklearn.tree import DecisionTreeClassifier from sklearn.linear_model import LogisticRegression from sklearn.svm import LinearSVC, SVC from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, confusion_matrix, f1_score modfnc = [DecisionTreeClassifier(random_state=19) ,RandomForestClassifier(random_state=19) ,LogisticRegression(random_state=19, penalty="l2") ,LogisticRegression(random_state=19, penalty="l1", solver='liblinear') ,LogisticRegression(random_state=19, penalty="elasticnet", solver='saga', l1_ratio=0.5) ,LinearSVC(random_state=19) ,LinearSVC(random_state=19, penalty='l1', loss='squared_hinge', dual=False) ,SVC(kernel='linear', random_state=19) ,SVC(kernel='rbf', random_state=19) ,SVC(kernel='poly', random_state=19) ,SVC(kernel='sigmoid', random_state=19) ] score=0 for modfnc1 in modfnc: model = modfnc1 model.fit(train_X, train_y) pred_y = model.predict(valid_X) print("----",modfnc1,"-----") #print(model.score(valid_X, valid_y)) print(f1_score(valid_y, pred_y, average="micro")) #print(confusion_matrix(valid_y, pred_y)) #print(classification_report(valid_y, pred_y)) #print() if score < f1_score(valid_y, pred_y, average="micro"): best_model = modfnc1 score = f1_score(valid_y, pred_y, average="micro") print("---- best model ----") print(best_model) print(score)
このうち、F1-スコアでの評価ではランダムフォレストが最も良好だった。
---- DecisionTreeClassifier(random_state=19) ----- 0.7713004484304933 ---- RandomForestClassifier(random_state=19) ----- 0.8430493273542601 ---- LogisticRegression(random_state=19) ----- 0.8071748878923767 ---- LogisticRegression(penalty='l1', random_state=19, solver='liblinear') ----- 0.8251121076233184 ---- LogisticRegression(l1_ratio=0.5, penalty='elasticnet', random_state=19, solver='saga') ----- 0.6905829596412556 ---- LinearSVC(random_state=19) ----- 0.7309417040358744 ---- LinearSVC(dual=False, penalty='l1', random_state=19) ----- 0.8251121076233184 ---- SVC(kernel='linear', random_state=19) ----- 0.8116591928251121 ---- SVC(random_state=19) ----- 0.6636771300448431 ---- SVC(kernel='poly', random_state=19) ----- 0.6278026905829597 ---- SVC(kernel='sigmoid', random_state=19) ----- 0.5919282511210763 ---- best model ---- RandomForestClassifier(random_state=19) 0.8430493273542601
テストデータで予測
ベストモデル(ランダムフォレスト)を使ってテストデータで予測を行う。
Kaggleのテストデータには正解ラベルが入っておらず、予測結果をKaggleの指定ページに提出してスコアを出す仕組みである(カンニングできない)。
best_model.fit(train_X, train_y) pred_y2 = best_model.predict(test_X) submission = pd.DataFrame({'PassengerId':test['PassengerId'], 'Survived':pred_y2}) submission.to_csv('submission.csv', index = False)
実際に結果を提出してみたところ、Score : 0.75119(44,476位)だった。
ハイパーパラメータを何もいじらずだったので、次はグリッドサーチやランダムサーチを使ってベストモデルを探してみたい。
もしくはポピュラーな LightGBM
や XGboost
の実装をしてみたい(こっちの興味の方が強い)。
参考
【Kaggle超初心者向け】Titanicにチャレンジしてみた - Qiita
Kaggleコンペの提出データをKernelから提出する - Qiita
機械学習初心者がKaggleのTitanic課題でモデルを作る | 4番は司令塔
当ブログの関連記事:
【統計】ロジスティック回帰分析 - こちにぃるの日記
【機械学習_Python】Ridge回帰、Lasso回帰、Elastic Net回帰 - こちにぃるの日記
【機械学習_Python】決定木とランダムフォレスト - こちにぃるの日記
【機械学習_Python】サポートベクターマシーン - こちにぃるの日記