はじめに
Kaggle / Titanic のチュートリアルでは RandomForestClassifier()
で学習している. このパラメータを調整して, 学習精度が向上するか確認する.
データの準備
import numpy as np
import pandas as pd
import seaborn
import matplotlib.pyplot as plt
train_data = pd.read_csv("../train.csv")
from sklearn.model_selection import train_test_split
train_data_orig = train_data
train_data, cv_data = train_test_split(train_data_orig, test_size=0.3, random_state=1)
train_test_split
を使って, train : cv = 7 : 3 にデータを分割した (cv ; cross validation).
train_data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 623 entries, 114 to 37
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 623 non-null int64
1 Survived 623 non-null int64
2 Pclass 623 non-null int64
3 Name 623 non-null object
4 Sex 623 non-null object
5 Age 496 non-null float64
6 SibSp 623 non-null int64
7 Parch 623 non-null int64
8 Ticket 623 non-null object
9 Fare 623 non-null float64
10 Cabin 135 non-null object
11 Embarked 622 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 63.3+ KB
cv_data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 268 entries, 862 to 92
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 268 non-null int64
1 Survived 268 non-null int64
2 Pclass 268 non-null int64
3 Name 268 non-null object
4 Sex 268 non-null object
5 Age 218 non-null float64
6 SibSp 268 non-null int64
7 Parch 268 non-null int64
8 Ticket 268 non-null object
9 Fare 268 non-null float64
10 Cabin 69 non-null object
11 Embarked 267 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 27.2+ KB
train が 623 個, cv が 268 個, 合計が 891 個になっている.
チュートリアル通りに学習する
from sklearn.ensemble import RandomForestClassifier
features = ["Pclass", "Sex", "SibSp", "Parch"]
y = train_data["Survived"]
y_cv = cv_data["Survived"]
X = pd.get_dummies(train_data[features])
X_cv = pd.get_dummies(cv_data[features])
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1, max_features="auto")
model.fit(X, y)
predictions = model.predict(X_cv)
print('Train score: {}'.format(model.score(X, y)))
print('CV score: {}'.format(model.score(X_cv, y_cv)))
Train score: 0.8394863563402889
CV score: 0.753731343283582
train は 84% くらいの正解になっているが, CV では 75% の正解に留まる. 過学習? ってことでしょうか?
RandomForestClassifier のパラメータを手動で変更する
n_estimator
n_estimator
の値を変えてみる.
rfc_results = pd.DataFrame(columns=["train", "cv"])
for iter in [1, 10, 100]:
model = RandomForestClassifier(n_estimators=iter, max_depth=5, random_state=1, max_features="auto")
model.fit(X, y)
predictions = model.predict(X_cv)
rfc_results.loc[iter] = model.score(X, y), model.score(X_cv, y_cv)
rfc_results
train | cv | |
---|---|---|
1 | 0.826645 | 0.753731 |
10 | 0.833066 | 0.753731 |
100 | 0.839486 | 0.753731 |
決定木の数が増えるにつれて, train のスコアは微増するが, cv のスコアは変わらない. ムムッ.
max_depth
max_depth
の値を変えてみる.
max_depth = 2
for iter in [1, 10, 100]:
model = RandomForestClassifier(n_estimators=iter, max_depth=2, random_state=1, max_features="auto")
model.fit(X, y)
predictions = model.predict(X_cv)
rfc_results.loc[iter] = model.score(X, y), model.score(X_cv, y_cv)
rfc_results
train | cv | |
---|---|---|
1 | 0.813804 | 0.731343 |
10 | 0.81862 | 0.753731 |
100 | 0.817014 | 0.761194 |
cv のスコア 76% が出てきた.
max_depth = 3
for iter in [1, 10, 100]:
model = RandomForestClassifier(n_estimators=iter, max_depth=3, random_state=1, max_features="auto")
model.fit(X, y)
predictions = model.predict(X_cv)
rfc_results.loc[iter] = model.score(X, y), model.score(X_cv, y_cv)
rfc_results
train | cv | |
---|---|---|
1 | 0.81862 | 0.753731 |
10 | 0.82504 | 0.776119 |
100 | 0.82504 | 0.768657 |
cv のスコア 77.6% が出てきた.
max_depth = 4
for iter in [1, 10, 100]:
model = RandomForestClassifier(n_estimators=iter, max_depth=4, random_state=1, max_features="auto")
model.fit(X, y)
predictions = model.predict(X_cv)
rfc_results.loc[iter] = model.score(X, y), model.score(X_cv, y_cv)
rfc_results
train | cv | |
---|---|---|
1 | 0.823435 | 0.764925 |
10 | 0.82825 | 0.761194 |
100 | 0.826645 | 0.764925 |
cv のスコアは 76.5% 程度.
以上から, max_depth=3
として, n_estimators=10
が一番スコアが高かった.
RandomForestClassifier のパラメータを自動で変更する
グリッドサーチ (GridSearchCV
) という方法で, 一番良いパラメータを探す. これは, 列挙したパラメータの組み合わせをしらみつぶしで試してみて, 一番良いものを探すという方法.
from sklearn.model_selection import GridSearchCV
param_grid = {"max_depth": [2, 3, 4, 5, None],
"n_estimators":[1, 3, 10, 30, 100],
"max_features":["auto", None]}
model_grid = GridSearchCV(estimator=RandomForestClassifier(random_state=1),
param_grid = param_grid,
scoring="accuracy", # metrics
cv = 3, # cross-validation
n_jobs = 1) # number of core
model_grid.fit(X, y) #fit
model_grid_best = model_grid.best_estimator_ # best estimator
print("Best Model Parameter: ", model_grid.best_params_)
from
行に注意. ネットで調べると from sklearn.grid_search import GridSearchCV
という書き方もあったが, 私の場合ではこれでは NG でした.
Best Model Parameter: {'max_depth': 3, 'max_features': 'auto', 'n_estimators': 10}
手動で試した通り, max_depth = 3
, n_estimators = 10
が一番良かった. max_features
も 2 種類試したが, "auto"
が良かった.
print('Train score: {}'.format(model.score(X, y)))
print('CV score: {}'.format(model.score(X_cv, y_cv)))
Train score: 0.826645264847512
CV score: 0.7649253731343284
Kaggle / Titanic に submit
今回のパラメタを用いて結果を予測し, Kaggle に submit した. しかし精度は 0.77751 で, チュートリアルそのままのパラメタと変わらなかった. びえん.
おわりに
特徴量で改善を図る前に, 学習のハイパーパラメータを調整することで, ちょっとだけ向上させることができた. 次はいよいよ, 特徴量を検討していきたい.