械学習の前処理、EDA、モデル構築手順(分類問題)

自分用のメモです。 機械学習の手法について知っているが、実装方法をすぐに忘れてしまう人向けのメモです。 教師あり学習の分類問題を対象とします。ニューラルネットワークは対象としません。

分類問題

importするライブラリ

# データ解析のライブラリ
import pandas as pd
import numpy as np 
import pandas_profiling as pdp

# データ可視化のライブラリ
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import seaborn as sns
%matplotlib inline 

# Scikit-learn
# common
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV 
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import MinMaxScaler
from sklearn.cross_validation import cross_val_score
from sklearn.pipeline import Pipeline
# 評価指標
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score
from sklearn.metrics import f1_score, roc_curve
# 推定器
from sklearn.linear_model import LogisticRegression # ロジスティック回帰
from sklearn.ensembles import RandomForestClassifier # ランダムフォレスト
from sklearn.svm import SVC # SVM
from sklearn.naive_bayse import MultinominalNB, GaussianNB, BernoulliNB # ナイーブベイズ

# scipy
from scipy import stats

# XGBoost
import xgboost as xgb
from xgboost import XGBClassifier

# その他
from math import sqrt

EDA

とりあえず回帰問題と同じ

前処理

とりあえず回帰問題と同じ

ベースモデル

比較対象とする最初のモデル。とりあえずXGBoostで。

xgboost = XGBClassifier(random_state=1)
history = xgboost_base.fit(X_train, y_train)
y_pred_base = xgboos.predict(X_train)

モデル性能評価

# ロジスティック回帰
LR = LogisticRegression(random_state=1)
LR.fit(X_train,y_train)

# ランダムフォレスト
RF = RandomForestClassifier(random_state=1)
param_grid = [{
    'n_estimators':[5, 10, 50, 100],
    'min_samples_split': [2,5,10],
    'bootstrap':['Auto','sqrt'],
    'min_samples_leaf': [1,5,10],
    'max_depth':[10,50,90],
    'max_features':['auto','sqrt'],
    'random_state':[1]
}]
RF_CV = GridSearchCV(estimator = RF,param_grid = param_grid, cv = 5)
RF_CV.fit(X_train,y_train)

# サポートベクターマシン
SV = SVC(random_state=42)
param_grid = [{
    'C': [0.1, 1, 10],
    'gamma': [.01,0.1,1],
    'kernel':['rbf', 'poly', 'linear', 'sigmoid'],
}]
SV_CV = GridSearchCV(estimator = SV,param_grid = param_grid, cv = 5)
SV_CV.fit(X_train,y_train)

# ナイーブベイズ
NB = GaussianNB()
NB.fit(X_train, y_train)
NB_pred_test = NB.predict(X_test)

##  XGBoost 
xgboost = XGBClassifier(random_state=42)
param_grid = [{
    'n_estimators':[100,300,500],
    'max_depth':[6,10],
}]
xgboost_CV = GridSearchCV(estimator = xgboost,param_grid = param_grid, cv = 5)
xgboost_CV.fit(X_train,y_train)

アンサンブル学習

多数決

各分類器の予測を集め、多数決で決まったクラスを全体の予測とする

from sklearn.ensemble import VotingClassifier

log_clf = LogisticRegression()
rnd_clf = RandomForestClassifier()
svm_clf = SVC()

voting_clf = VotingClassifier(
estimators=[(’lr’, log_clf), (’rf’, rnd_clf), (’svc’, svm_clf)],
voting=’hard’)
voting_clf.fit(X_train, y_train)

バギング

すべての分類器で同じ訓練アルゴリズムを使いつつ、訓練セットから無作為に別々のサブセットをサンプリングして訓練する

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bag_clf = BaggingClassifier(
    DecisionTreeClassifier(), 
    n_estimators=500,
    max_samples=100, 
    bootstrap=True, 
    n_jobs=-1,
    oob_score=True,
)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_test)

ブースティング

ベースの分類器を訓練し、訓練セットを対象として予測のために使う。 そして、分類に失敗した訓練インスタンスの相対的な重みを上げる。 次に、更新された重みを使って第2 の分類器を訓練し、予測に使って、重みを更新す る。これを繰り返していく

from sklearn.ensemble import GradientBoostingRegressor

gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=120)
gbrt.fit(X_train, y_train)
errors = [mean_squared_error(y_val, y_pred)
for y_pred in gbrt.staged_predict(X_val)]
bst_n_estimators = np.argmin(errors)
gbrt_best = GradientBoostingRegressor(max_depth=2,n_estimators=bst_n_estimators)
gbrt_best.fit(X_train, y_train)

スタッキング

1段階目は5つの手法(Random Forest, Extra Tree, AdaBoost, Gradient Boost, SVM)で評価 → それぞれの手法で特徴量の重要度が異なることが望ましい 2段階目は1段階目の手法の予測結果を入力として評価(XGBoost) www.kaggle.com

評価指標

from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score, roc_curve

# 混同行列
confusion_matrix(y_test, y_pred_test)
# 正解率(accuracy = (TP+TN) / (TP + TN + FP + FN)
accuracy_score(y_test, y_pred_test)
# 適合率(precision = TP / (TP + FP)
precision_score(y_test, y_pred_test)
# 再現率(recall = TP / (TP + FN)
recall_score(y_test, y_pred_test)
# F値 =2 * (適合率 * 再現率) / (適合率 + 再現率)
f1_score(y_test, y_pred_test)

# ROC曲線、AUC(Area Under Curve: ROC曲線の下側の面積。0以上1以下で1に近づくほど精度がよい)
# 横軸にFP(偽陽性率: 0を誤って1と予測してしまう確率)、縦軸にTP(真陽性率)をとる。予測確率に対してどこから陽性にするかという閾値を1から下げていった時の変化
roc_curve()
probas = model.predict_proba(X_train)
fp, tp, th = roc_curve(y_train, probas[:, 1])
auc_score = roc_auc_score(y, probas[:, 1])

fig, ax = plg.subplot()
ax.step(fp, tp)
plt.show()
 ```