「Kaggle」のデータセット「Kickstarter Projects」に取り組んで、前回、LassoCVを使った特徴量選択を実施したので、その特徴量を使ってNNモデルを作り学習率をグリッドサーチします。
前回の記事は、以下にありますので、ご参照ください。
では、さっそく取り組んでまいります。
1.まずは、選択された特徴量だけに絞り込んで、学習用の訓練データと、性能検証用のテストデータに分割します。
# ラベルデータとして’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)
# Lassoで削除するべき特徴量に選ばれたカラムをドロップする train_data = train_data.drop(train_data.columns[removed_idx], axis=1) #目的変数'state'を正解としてyに格納 y = train_label.values
#カラムをドロップした説明変数を、Xに格納 X = train_data.values # 全データのうち、30%をテストデータにする test_size = 0.3 # ホールドアウト法を実行(テストデータはランダム選択) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size,shuffle=True, random_state=1234) #X_train : 学習用の訓練データの説明変数
#X_test : 検証用のテストデータの説明変数
#y_train : 学習用の訓練データの目的変数
#y_test : 検証用のテストデータの目的変数
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)(144879, 172) (62091, 172) (144879,) (62091,)
144,879個の訓練データと、62,091個のテストデータに分かれて、説明変数は172個になりました。
2.1,2層目tanh 3,4層目ReLU、5層目Sigmoid の2値分類ニューラルネットワークモデルを採用, それぞれの層でバッチ正規化の処理を入れる。
モデルを一から作るのは大変なので、Kerasでくみ上げることにしました。
import keras from keras.models import Sequential from keras.layers import Dense, Dropout, Activation from keras.layers.normalization import BatchNormalization from keras.optimizers import Adam model = Sequential() #Lassoで削除された説明変数を削除する場合 model.add(Dense(256, activation='tanh', input_dim=172)) model.add(BatchNormalization()) model.add(Dense(256, activation='tanh')) model.add(BatchNormalization()) model.add(Dense(128, activation='relu')) model.add(BatchNormalization()) model.add(Dense(64, activation='relu')) model.add(BatchNormalization()) model.add(Dense(1, activation='sigmoid')
3.最適化手法にAdamを採用し学習率を交差検証法で探索する。
最適化手法にはAdamを採用し学習率を変化させて、テストデータAccuracyが最大になる値を探索することにしました。
探索にあたっては、交差検証法(クロスバリデーション)を利用しました。#学習率毎のAccuracy格納用データフレームを初期化 df_lr_Acc = pd.DataFrame(index=[], columns=['lr','step','loss', 'val_loss','acc', 'val_acc']) for lr in np.arange(0.001,0.01,0.001): #クロスバリデーションの検証毎のAccuracy格納用データフレームを初期化 df_val_Acc = pd.DataFrame(index=[], columns=['step','loss', 'val_loss','acc', 'val_acc']) #クロスバリデーションでの検証ステップを初期化 step = 1 #クロスバリデーションで検証(訓練データを三分割して、2つを学習用、1つを検証用に使うを三回実施) for train_index, test_index in KFold(n_splits=3,shuffle=True, random_state=1234).split(X_train, y_train): X_val_train, X_val_test = X[train_index], X[test_index] y_val_train, y_val_test = y[train_index], y[test_index] print(X_val_train.shape, X_val_test.shape,y_val_train.shape, y_val_test.shape) # ------ 最適化手法 ------ adam = Adam(lr=lr) # ----------------------------- model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy']) # 計算の実行 fit = model.fit(X_val_train, y_val_train,epochs=5,batch_size=256,validation_data=(X_val_test, y_val_test)) # 各epochにおける損失と精度をdfに入れる df = pd.DataFrame(fit.history) val_df = pd.DataFrame(index=[],columns=['step','loss', 'val_loss','acc', 'val_acc']) val_df = val_df.append(df,ignore_index = True,sort=False) val_df[['step']] = step df_val_Acc = df_val_Acc.append(val_df, ignore_index = True,sort=False) step = step + 1 lr_df = pd.DataFrame(index=[],columns=['lr','step','loss', 'val_loss','acc', 'val_acc']) lr_df = lr_df.append(df_val_Acc.mean(),ignore_index = True,sort=False) lr_df['lr'] = lr df_lr_Acc = df_lr_Acc.append(lr_df, ignore_index = True,sort=False)計算にはすごく時間がかかりましたが、何とか以下の結果が得られました。
display(df_lr_Acc)df_lr_Acc[['acc', 'val_acc']].plot() plt.show()
三番目のVal_Accが最大になっているので、0.004を学習率として採用する。
4.訓練データをすべて投入し、epoch数を増やしてみて学習後、テストデータでの精度を確認する。
エポック数は100にしてみます。
# ------ 最適化手法 ------ adam = Adam(lr=0.004) # ----------------------------- model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy']) # 計算の実行 fit = model.fit(X_train, y_train,epochs=100,batch_size=256,validation_data=(X_test, y_test)) # 各epochにおける損失と精度をdfに入れる df = pd.DataFrame(fit.history) # グラフ化 df[['loss', 'val_loss']].plot() plt.ylabel('loss') plt.xlabel('epoch') plt.show() df[['acc', 'val_acc']].plot() plt.ylabel('acc') plt.xlabel('epoch') plt.show()
前回のLeakageの気づきで大きく手戻りしましたが、ロジスティック回帰で分類した62%から、66%まで改善することができました。
次回は、別のモデルを採用してさらなる改善を目指します。
2019年3月9日(土)にG検定を受験し、見事合格できました!
受験の体験記や勉強法などを別のブログにまとめました。
これから受験される方がいらっしゃいましたらご参考まで。