「Kaggle」のデータセット「Kickstarter Projects」に取り組んでいます。
今回は、一度NNモデルから離れて、木モデルのAdaBoostに挑戦します。
NNモデルの記事は、以下にありますので、ご参照ください。
では、さっそく取り組んでまいります。
1.まずは、Leakageになりそうなカラム、相関が強いカラムをドロップする。
# ラベルデータとして’state’を採用する。 train_label = df_train['state'] # Leakageになりそうなカラム、相関が強いカラムをドロップする train_data = df_train.drop(['state','name','currency','deadline','goal','launched','pledged','backers','usd pledged','usd_pledged_real','period'], axis=1)
2.標準化する。
# 標準化
train_data = (train_data - train_data.mean()) / train_data.std()
train_data = train_data.astype('float32')平均との差分を、標準偏差で割って、値を標準化します。
3.ホールドアウト法で、最終的に性能を見るためのテストデータを別にする。
テストデータは30%にします。
#ホールドアウト法に関する関数をインポートする。 from sklearn.model_selection import train_test_split # 交差検証法に関する関数をインポートする。 from sklearn.model_selection import KFold#目的変数'state'を正解としてyに格納 adB_y = adB_train_label.values #カラムをドロップした説明変数を、Xに格納 adB_X = adB_train_data.values # 全データのうち、30%をテストデータにする test_size = 0.3 # ホールドアウト法を実行(テストデータはランダム選択) #X_train : 学習用データの説明変数 #X_test : テスト用データの説明変数 #y_train : 学習用データの目的変数 #y_test : テスト用データの目的変数 adB_X_train, adB_X_test, adB_y_train, adB_y_test = train_test_split(adB_X, adB_y, test_size=test_size,shuffle=True, random_state=1234) print(adB_X_train.shape, adB_X_test.shape, adB_y_train.shape, adB_y_test.shape)(144879, 199) (62091, 199) (144879,) (62091,)
学習用のデータが144879個、テスト用のデータが62091個に分離できました。
4.max_depth(木の深さ)を変化させて、Accuracyが最大になる値を探す。
AdaBoostを使って、木の深さを変化させて、検証データのAccuracyが最大になる値を探索することにしました。
探索にあたっては、交差検証法(クロスバリデーション)を利用しました。#木の深さ毎のAccuracy格納用データフレームを初期化 df_md_Acc = pd.DataFrame(index=[], columns=['max_depth','val_acc'])
#木の深さ毎に検証する。 for max_depth in np.arange(1,10,1): #クロスバリデーションの検証毎のAccuracy格納用データフレームを初期化 df_val_Acc = pd.DataFrame(index=[], columns=['val_acc']) #クロスバリデーションでの検証ステップを初期化 #クロスバリデーションで検証 for train_index, test_index in KFold(n_splits=2,shuffle=True,random_state=1234).split(adB_X_train, adB_y_train): adB_X_val_train, adB_X_val_test = adB_X[train_index], adB_X[test_index] adB_y_val_train, adB_y_val_test = adB_y[train_index], adB_y[test_index] clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=max_depth,min_samples_split=2,random_state=1234,criterion="gini"),n_estimators=10, random_state=1234) clf.fit(adB_X_val_train, adB_y_val_train) score = clf.score(adB_X_val_test, adB_y_val_test) print("max_depth=",max_depth) print("score=", score) val_se = pd.Series( [score], index=df_val_Acc.columns ) df_val_Acc = df_val_Acc.append(val_se, ignore_index = True,sort=False) md_df = pd.DataFrame(index=[],columns=['max_depth','val_acc']) md_df = md_df.append(df_val_Acc.mean(),ignore_index = True,sort=False) md_df['max_depth'] = max_depth df_md_Acc = df_md_Acc.append(md_df, ignore_index = True,sort=False)以下の結果が得られました。
display(df_md_Acc)
display(df_md_Acc.max())
max_depth val_acc 0 1 0.723286 1 2 0.758233 2 3 0.764852 3 4 0.765508 4 5 0.765784 5 6 0.763789 6 7 0.763658 7 8 0.761898 8 9 0.759385 val_acc 0.765784 dtype: float64
df_md_Acc[['val_acc']].plot() plt.show()グラフ上の横軸とmax_depthの値が1ずれているのでわかりにくいですが、四番目(max_depth=5)のVal_Accが最大になっているので、5をmax_depthとして採用する。
5.訓練データをすべて投入し、テストデータでの精度を確認する。
AdaBoostに訓練データをすべて投入し、max_depth=5で学習させます。clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=5,min_samples_split=2,random_state=1234,criterion="gini"),n_estimators=10, random_state=1234)
clf.fit(adB_X_train, adB_y_train)
print("score=", clf.score(adB_X_test, adB_y_test))score= 0.6750253659950718クロスバリデーション時から、精度が下がりましたが、なんとか精度が67.5%まで改善し、NNモデルより精度が向上しました。
6.木モデルでつかわれている説明変数を確認する。
AdaBoostのfeature_importance_を利用して、このモデルでつかわれている説明変数を確認します。# 説明変数の重要度を出力する
# 棒グラフで出力する。 pd.DataFrame(clf.feature_importances_, index=adB_train_data.columns).plot.barh(figsize=(12,50)) plt.ylabel("Importance") plt.xlabel("Features") plt.show()LassoCVで選択した特徴量よりも大幅に少なくなっています。また、usd_goalも利用されていて、直感的な特徴量が採用されている気がします。
今回は、視点を変えて、木モデル(AdaBoost)を試したのですが、これまでより、少ない特徴量で効率的な分類モデルができたと思われます。でも、まだまだ、全く役に立たないレベルの精度なので、いったん初心に戻って、テキスト等を参考に、理論を学びなおしたいと思います。
2019年3月9日(土)にG検定を受験し、見事合格できました!
受験の体験記や勉強法などを別のブログにまとめました。
これから受験される方がいらっしゃいましたらご参考まで。