はじめに
データサイエンティスト養成講座の第二回を受けてきました。
扱った内容は、
- 決定木
- クロスバリデーション
- グリッドサーチ
講座では、Rを使うのだけれども、Pythonにもなれておきたいので、
講座の内容をPythonで復習しました。
ついでに、kaggleのタイタニック問題を決定木で解きました。
今回のコードは、githubにあげています。以下は、コードの抜粋です。
Pythonで決定木
Pythonで決定木を使うには、scikit-learnライブラリを使う。
from sklearn import tree
clf = tree.DecisionTreeClassifier(random_state=17)
clf.fit(X, y)
簡単!
クロスバリデーション with KFold
決定木は、max_depthパラメータを大きくすればするほど精度が上がっていくが、汎化性能が下がっていく。なので、クロスバリデーションという方法を使って、過学習が起こっていないかチェックすることが重要になる。
from sklearn.model_selection import KFold
from sklearn import metrics
from sklearn.metrics import accuracy_score
K = 5
kf = KFold(n_splits=K, shuffle=True, random_state=17)
score_train_tmp = 0
score_test_tmp = 0
for train_index, test_index in kf.split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
# 構築データでモデル構築
clf.fit(X_train, y_train)
# 構築データの予測値
pred_train = clf.predict(X_train)
# 構築データのaccuracy
auccuracy = accuracy_score(pred_train, y_train)
#構築データのaccuracyを足していく
score_train_tmp+=auccuracy
#検証データの予測値
pred_test = clf.predict(X_test)
#検証データのaccuracy
auccuracy = accuracy_score(pred_test, y_test)
#検証データのaccuracyを足していく
score_test_tmp+=auccuracy
score_train_tmp/K
0.82463676190176005
score_test_tmp/K
0.80247944259619608
構築データと検証データのスコアが近ければ、過学習が起こっていないと判断できる。これが乖離していると過学習が起こっているので、パラメータチューニングが必要。
グリッドサーチ
最適なパラメータをしらみつぶしにパラメータを組み合わせて探索していく方法をグリッドサーチという。普通はfor文を回してパラメータを変えてスコアを見ることで調整していく。しかし、scikit-learnには、GridSearchCVというグリッドサーチをするための専用のクラスが用意されている。
これをつかえば、煩わしいfor文のネストを書かずとも、複数パラメータに対して探索をすくことができる。
調べたいパラメータをまずは辞書で定義する。
from sklearn.model_selection import GridSearchCV
# use a full grid over all parameters
param_grid = {"max_depth": [2,4,6,8,10],
"max_features": [log2, sqrt,auto],
"min_samples_split": [2, 3, 5],
"min_samples_leaf": [1,5,8],
"criterion": ["gini", "entropy"]}
次に、GridSearchCVを読んで、グリッドサーチを実行する。
tree_grid = GridSearchCV(estimator=clf,
param_grid = param_grid,
scoring="accuracy", #metrics
cv = K, #cross-validation
n_jobs =-1) #number of core
tree_grid.fit(X,y) #fit
tree_grid_best = tree_grid.best_estimator_ #best estimator
print("Best Model Parameter: ",tree_grid.best_params_)
print("Best Model Score : ",tree_grid.best_score_)
Best Model Parameter: {criterion: gini, max_depth: 6, max_features: log2, min_samples_leaf: 8, min_samples_split: 2}
Best Model Score : 0.812570145903
便利だ。素晴らしい。
しかし、このパラメータチューニングした結果をサイトにて提出しても、大したスコアは出ない。これは、特徴量エンジニアリングがそもそもしょぼいという問題がある。