よくoptunaをつかってRandomForestの調整をするのですが、コードをなくすことが多いため備忘録も兼ねて投稿します。コピペ用に作ったので、ぜひ試してみてください。
コードのみ
ライブラリのインポート
使うライブラリのインポートを行う。
import matplotlib.pyplot as plt
%matplotlib inline
import japanize_matplotlib
import pandas as pd
import seaborn as sns
import numpy as np
from sklearn.metrics import (
confusion_matrix,
accuracy_score,
precision_score,
recall_score,
f1_score
)
import lightgbm as lgb
import optuna
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import fbeta_score
from sklearn.model_selection import train_test_split
混合行列の可視化と特徴量重要度の可視化
def heat_map(cm):
cm_matrix = pd.DataFrame(data=cm,columns=['Actual Positive:1','Actual Negative:0'],
index=['Predict Positive:1','Predict Negative:0'])
# ヒートマップで描画
plt.figure(figsize=(3, 3))
heatmap = sns.heatmap(cm_matrix, annot=True, fmt='d',cmap='coolwarm')
# heatmap.set_title('混同行列',fontsize=20)
heatmap.set_xticks([0.5,1.5])
heatmap.set_xlabel('予測',fontsize=15)
heatmap.set_xticklabels(['Negative:0','Positive:1'],fontsize=12)
heatmap.set_ylabel('真値',fontsize=15)
heatmap.set_yticks([0.5,1.5])
heatmap.set_yticklabels(['Negative:0','Positive:1'],fontsize=12)
def feature_importances_sort(fti):
feat_df=pd.DataFrame()
# print('Feature Importances:')
for i, feat in enumerate(x_train.columns):
# print('\t{0:20s} : {1:>.6f}'.format(feat, fti[i]))
AAA=pd.DataFrame([fti[i]],index=[feat],columns=['importance'])
feat_df=pd.concat([feat_df,AAA],axis=0)
feat_df_sort=feat_df.sort_values(["importance"],ascending=False)
return feat_df_sort
データのロード
以下のようにデータを準備する。
TRAIN_df=学習データ
VALID_df=検証データ
x_train=TRAIN_df[利用するカラム]
x_valid=VALID_df[利用するカラム]
target_columns=目的変数のカラム
y_train=TRAIN_df[target_columns]
y_valid=VALID_df[target_columns]
# train_test_split
X_tr, X_te, y_tr, y_te = train_test_split(x_train,y_train,random_state=42,stratify = y_train)
optunaの準備
def objective(trial):
bootstrap = trial.suggest_categorical('bootstrap',[True,False])
max_depth = trial.suggest_int('max_depth', 1, 100)
# max_features = trial.suggest_categorical('max_features', ['sqrt','log2',"None"])
max_features = trial.suggest_float('max_features', 0,1.0)
max_leaf_nodes = trial.suggest_int('max_leaf_nodes', 1,1000)
n_estimators = trial.suggest_int('n_estimators', 1, 1000)
min_samples_split = trial.suggest_int('min_samples_split',2,5)
min_samples_leaf = trial.suggest_int('min_samples_leaf',1,10)
model = RandomForestClassifier(bootstrap = bootstrap,
max_depth = max_depth,
max_features = max_features,
max_leaf_nodes = max_leaf_nodes,
n_estimators = n_estimators,
min_samples_split = min_samples_split,
min_samples_leaf = min_samples_leaf,
criterion="gini",random_state=0, n_jobs=-1)
model.fit(X_tr , y_tr)
# 推論
y_pred = model.predict(X_te)
# 評価
#===========利用したい評価指標に変更===============
score = fbeta_score(y_te, y_pred, average='binary', beta=0.5)
return score
optunaの実行
study = optuna.create_study(direction='maximize',sampler=optuna.samplers.TPESampler(seed=42))
study.optimize(objective, n_trials=50)
print("=======ベストパラメータ========")
print(study.best_params)
調整したパラメータで学習
# チューニングしたハイパーパラメーターをフィット
optimised_RF = RandomForestClassifier(bootstrap = study.best_params['bootstrap'],
max_depth = study.best_params['max_depth'],
max_features = study.best_params['max_features'],
max_leaf_nodes = study.best_params['max_leaf_nodes'],
n_estimators = study.best_params['n_estimators'],
min_samples_split = study.best_params['min_samples_split'],
min_samples_leaf = study.best_params['min_samples_leaf'],
criterion="gini",random_state=0, n_jobs=-1)
optimised_RF.fit(x_train ,y_train)
評価
検証用データを用いて予測結果を出し、評価をする。混合行列と重要度も算出する。
y_pred_RF=optimised_RF.predict(x_valid)
valid_precision=precision_score(y_valid,y_pred_RF)
valid_recall=recall_score(y_valid,y_pred_RF)
valid_f1=f1_score(y_valid,y_pred_RF)
print(valid_precision,valid_recall,valid_f1)
混合行列の可視化。
cm = confusion_matrix(y_valid,y_pred_RF)
heat_map(cm)
特徴量重要度の可視化。
fti = optimised_rf.feature_importances_
feature_importances_sort(fti).style.bar(axis=0)
まとめ
完全に自分用の備忘録的にまとめたので詳細な説明は省いていますが、必要になったらぜひ使ってみてください。
コメント