LoginSignup
8

More than 3 years have passed since last update.

posted at

updated at

KaggleのTitanicでモデルを選別する(kaggle④)

はじめに

初めてKaggle(カグル)のコンペに参加してみたお話です。
前回の「KaggleのTitanicで相関関係を確認する」では、相関関係を調べて、Pclass(チケットクラス)、Sex(性別)、Fare(運賃)の3つの入力データを採用することにしました。
今回はいくつかのモデルを試してみたいと思います。

目次

1.結果
2.利用するモデルについて
3.モデルの評価方法
4.モデルを試す
5.パラメータチューニング
6.Kaggleに提出する
7.まとめ

履歴

1.結果

結果から言うと、スコアが少しあがり「0.77511」になりました。
上位58%(2019/12/29現在)という結果です。
再提出までの流れを見ていきたいと思います。

2.利用するモデルについて

前回は、scikit-learnのアルゴリズムシートに従って「Linear SVC」を利用しました。
自分が機械学習を最初に学んだこの本では、クラス分類問題について、scikit-learnの以下のモデルを取り上げています。
・sklearn.svm.LinearSVC
・sklearn.svm.SVC
・sklearn.ensemble.RandomForestClassifier
・sklearn.linear_model.LogisticRegression
・sklearn.linear_model.SGDClassifier

今回は、上記のモデルを試してみたいと思います。

3.モデルの評価方法

モデルの評価は以下の手順になります。
1.トレーニングデータを使って学習する
2.テストデータを使って、予測する
3.予測した結果が正しいか確認する

KaggleのTitanicでは、トレーニングデータ [train.csv](結果が分かるデータ)とテストデータ [test.csv](結果が分からないデータ)があります。
2の「予測する」と、3の「確認する」をtest.csv を使うと毎回commitして提出しないと結果が分からないため非効率です。
結果が分かっているトレーニングデータ [train.csv]を、トレーニングデータ用データとテスト用データに分けることで効率的に評価することができます。
scikit-learnには、トレーニングデータとテストデータに分割する関数「train_test_split」が用意されています。

from sklearn.model_selection import train_test_split

######################################
# トレーニングデータとテストデータを分ける
# Split training data and test data
######################################
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=1, shuffle=True)

以下のようなイメージです。
test_size=0.3だと、トレーニングデータとテストデータを「7:3」で分割します。

〇分割前のデータ

y x
Survived Pclass Sex Fare
1 0 3 male 7.25
2 1 1 female 71.2833
3 1 3 female 7.925
4 1 1 female 53.1
5 0 3 male 8.05
6 0 3 male 8.4583
7 0 1 male 51.8625
8 0 3 male 21.075
9 1 3 female 11.1333
10 1 2 female 30.0708

〇分割後のトレーニングデータ

y_train x_train
Survived Pclass Sex Fare
1 0 3 male 7.25
2 1 1 female 71.2833
4 1 1 female 53.1
5 0 3 male 8.05
6 0 3 male 8.4583
8 0 3 male 21.075
10 1 2 female 30.0708

〇分割後のテストデータ

y_test x_test
Survived Pclass Sex Fare
3 1 3 female 7.925
7 0 1 male 51.8625
9 1 3 female 11.1333

続いて、学習と予測です。

scikit-learnのモデルには、学習するためのメソッド「fit」と、予測を評価するためのメソッド「score」が提供されています。
「fit」と「score」です。

from sklearn.svm import LinearSVC
model = LinearSVC(random_state=1)

######################################
# 学習する
# training
######################################
model.fit(x_train, y_train)

######################################
# 予測した結果を評価する
# Evaluate predicted results
######################################
score = model.score(x_test, y_test)

「fit」は学習です。
「score」は「x_test」で結果を予測し、その結果と「y_test」と突き合わせて正解率を返します。
上記の場合、score は「0.753731343283582」になります。
75%の正解率という結果です。

4.モデルを試す

いろいろなモデルを試し、scoreを比較することで、モデルの性能を評価できます。
「2.利用するモデルについて」のモデルを試してみます。

全体的なコードは以下です。

準備
import numpy 
import pandas

# train.csvを読み込む
# Load train.csv
df = pandas.read_csv('/kaggle/input/titanic/train.csv')

##############################
# データ前処理
# 必要な項目を抽出する
# Data preprocessing 
# Extract necessary items
##############################
# 'Survived', 'Pclass', 'Sex', 'Fare'を抽出する
# Extract 'Survived', 'Pclass', 'Age', 'Fare'
df = df[['Survived', 'Pclass', 'Sex', 'Fare']]

##############################
# データ前処理
# ラベル(名称)を数値化する
# Data preprocessing 
# Digitize labels
##############################
from sklearn.preprocessing import LabelEncoder
# 性別をLabelEncoderを利用して数値化する
# Digitize gender using LabelEncoder
encoder_sex = LabelEncoder()
df['Sex'] = encoder_sex.fit_transform(df['Sex'].values)

##############################
# データ前処理
# 数値を標準化する
# Data preprocessing
# Standardize numbers
##############################
from sklearn.preprocessing import StandardScaler

# 標準化
# Standardize numbers
standard = StandardScaler()
df_std = pandas.DataFrame(standard.fit_transform(df[['Pclass', 'Fare']]), columns=['Pclass', 'Fare'])

# Fare を標準化
# Standardize Fare
df['Pclass'] = df_std['Pclass']
df['Fare'] = df_std['Fare']

from sklearn.model_selection import train_test_split

x = df.drop(columns='Survived')
y = df[['Survived']]
トレーニングデータ、テストデータ作成
#######################################
# トレーニングデータとテストデータを分ける
# Split training data and test data
#######################################
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=1, shuffle=True)
y_train = numpy.ravel(y_train)
y_test = numpy.ravel(y_test)
モデル評価
#######################################
# モデルを評価する
# Evaluate the model
#######################################
from sklearn.svm import LinearSVC
model = LinearSVC(random_state=1)
model.fit(x_train, y_train)
score = model.score(x_test, y_test)
score

「モデル評価」のモデルの定義部分を差し替えれば、いろいろなモデルで評価できます。
「2.利用するモデルについて」に記述したモデルを試してみます。
結果は以下になりました。

モデル score
sklearn.svm.LinearSVC 0.753
sklearn.svm.SVC 0.783
sklearn.ensemble.RandomForestClassifier 0.805
sklearn.linear_model.LogisticRegression 0.753
sklearn.linear_model.SGDClassifier 0.753

ランダムフォレストが一番良いという結果になりました。
次は、ランダムフォレストモデルのパラメータを調整してみます。

5.パラメータチューニング

パラメータの調整は scikit-learn にある グリッドサーチ(GridSearchCV)を利用します。
グリッドサーチは、指定されたパラメータを全パターンで評価し、最適なパラメータの組み合わせを突き止めてくれます。
ただし、全パターンを評価するため、パラメータを増やすほど処理に時間がかかります。
ランダムフォレストのドキュメントを確認し、以下のパラメータを調整することににします。

パラメータ パターン
criterion gini / entropy
n_estimators 25 / 100 / 500 / 1000 / 2000
min_samples_split 0.5 / 2 / 4 / 10
min_samples_leaf 1 / 2 / 4 / 10
bootstrap Ture / False

「モデル評価」を以下の「グリッドサーチ」に入れ替えることで、グリッドサーチを実行できます。

グリッドサーチ
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
###############################################
# グリッドサーチで LogisticRegression のパラメータを試す
# Tuning LogisticRegression parameters with grid search
###############################################
pipe_svc = RandomForestClassifier(random_state=1)

param_grid = {'criterion':['gini','entropy'],
              'n_estimators':[25, 100, 500, 1000, 2000],
              'min_samples_split':[0.5, 2,4,10],
              'min_samples_leaf':[1,2,4,10],
              'bootstrap':[True, False]
              }

grid = GridSearchCV(estimator=RandomForestClassifier(random_state=1), param_grid=param_grid)
grid = grid.fit(x_train, y_train)

print(grid.best_score_)
print(grid.best_params_)

以下の結果になりました。
自分の環境では、グリッドサーチの実行に10分程度かかりました。

グリッドサーチ結果
0.8105939004815409
{'bootstrap': False, 'criterion': 'entropy', 'min_samples_leaf': 10, 'min_samples_split': 2, 'n_estimators': 100}

6.Kaggleに提出する

グリッドサーチでチューニングしたパラメータを指定し、学習、予測してみましょう。
「トレーニングデータ、テストデータ作成」「グリッドサーチ」のコードを以下に書き換え、学習と予想を行います。

学習、予想
##############################
# モデルの構築
# Model building
##############################
from sklearn.ensemble import RandomForestClassifier

# モデルを生成する
# Generate a model
model = RandomForestClassifier(n_estimators=100, \
                               criterion='entropy', \
                               min_samples_split=2, \
                               min_samples_leaf=10, \
                               bootstrap=False, \
                               random_state=1)

##############################
# 学習
# Trainig
##############################
y = numpy.ravel(y)
model.fit(x, y)

# test.csv を変換する
# convert test.csv
##############################
# test.csvを読み込む
# Load test.csv
df_test = pandas.read_csv('/kaggle/input/titanic/test.csv')

# Fare のNanを変換
# Convert Fare Nan to 0 
df_test = df_test.fillna({'Fare':0})

# 'PassengerId'を抽出する(結果と結合するため)
# Extract 'PassengerId'(To combine with the result)
df_test_index = df_test[['PassengerId']]

# 'Pclass', 'Sex', 'Fare'を抽出する
# Extract 'Pclass', 'Sex', 'Fare'
df_test = df_test[['Pclass', 'Sex', 'Fare']]

# 標準化
# Standardize
df_test_std = pandas.DataFrame(standard.transform(df_test[['Pclass', 'Fare']]), columns=['Pclass', 'Fare'])
df_test['Pclass'] = df_test_std['Pclass']
df_test['Fare'] = df_test_std['Fare']

# ラベル エンコーディング
# Label Encoding
df_test ['Sex'] = encoder_sex.transform(df_test ['Sex'].values)

##############################
# 結果を予想する
# Predict results
##############################
x_test = df_test.values
y_test = model.predict(x_test)

# PassengerId のDataFrameと結果を結合する
# Combine the data frame of PassengerId and the result
df_output = pandas.concat([df_test_index, pandas.DataFrame(y_test, columns=['Survived'])], axis=1)

# result.csvをカレントディレクトリに書き込む
# Write result.csv to the current directory
df_output.to_csv('result.csv', index=False)

上記をKaggleの環境で記述します。
「Run All」を実行し、result.csvが作成されることを確認します。

「Commit」⇒「Open Version」⇒「Submit to Competition」で提出します。
20191229_01.png

スコアが「0.77511」になりました。

7.まとめ

今回は5種類のモデルを比較し、パラメータチューニングすることでスコアを少し上げることができました。
次回は scikit-learn のいろいろなモデルから、より適したモデルを調べてみたいと思います。

履歴

2019/12/29 初版公開
2020/01/01 次回のリンク追加
2020/01/03 ソースのコメント修正

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
What you can do with signing up
8