俺人〜OREGIN〜俺、バカだから人工知能に代わりに頑張ってもらうまでのお話

俺って、おバカさんなので、とっても優秀な人工知能を作って代わりに頑張ってもらうことにしました。世界の端っこでおバカな俺が夢の達成に向けてチマチマ頑張る、そんな小さなお話です。現在はG検定、E資格に合格し、KaggleやProbSpaceのコンペに参画しながら、Pythonや機械学習、統計学、Dockerなどの勉強中です。学習したことをブログにアウトプットすることで、自分の身に着けていきたいと思います。まだまだ道半ばですが、お時間がありましたら見て行ってください。

エピソード3-10: 大幅手戻り、Leakageにはまる。(KaggleでKickstarter Projectsに挑戦する。)

「Kaggle」のデータセットKickstarter Projects」に取り組んで、順調に精度を向上させているかに見えたのですが、ここにきて、知人に「それ、Leakageじゃない?」と指摘され、今回は、Leakageの回避に取り組みました。

これまでの流れは以下にまとめてあるのでご参照ください。

oregin-ai.hatenablog.com

 

Leakageとは、学習時の説明変数に、目的変数と同等の変数を使ってしまうことで、予測精度や分類精度が、大幅に向上してしまうことです。

今回のデータセットで言えば、結果として集まった金額や、後援者の数などをつかってしまうことになります。

 

1.Leakageに該当すると思われる説明変数を除外してみる。

これまでの検証で「backers」を使ってしまったのですが、これは、クラウドファンディングの結果、集まった後援者を表しているので、目的変数の’state'と同様、結果として得られる数値なので、予測や分類につかってしまうと、Leakageに該当します。

また、訓練データの’state’の成功、失敗をもとに自分で作った、'country_rate'や'main_category_rate'や'category_rate'も数値を作るときに、目的変数の'state'を使ってしまっているので、Leakageになってしまいます。

これらは、説明変数からのぞかないとLeakageになってしまい、訓練時は精度が良くても実際には精度がでないという結果になってしまします。

どうりで、80%だ90%だのAccuracyがバンバン出せたわけだ・・・。

 

2.代わりに、country,main_category,categoryをOne-Hotに変換してみる。

 上記で、変数を減らしたので、代わりにcountry,main_category,categoryをOne-Hotベクトルに変換する。

One-Hotベクトルとは、Countryのようなカテゴリーデータを、各カテゴリの列(country_US,country_UKなどの列)に変換し、その列のカテゴリに該当する行は「1」、該当しない行は「0」に変換することで出来上がる表現です。

#####################################
#country,main_category,categoryをOne-Hotに変換する。
#####################################
df_train = pd.get_dummies(df_train, columns=['country', 'category', 'main_category'])
 

pandasのget_dummies()に、変換したいデータフレームと、変換したいカラムをcolumns=[変換したいカラムリスト]とすることで、変換したデータフレームが取得できます。

結果としては、以下のような感じになります。

f:id:kanriyou_h004:20190602163834j:plain

 

3.Leakageにあたる変数を除外して、One-Hotを採用したデータフレームで改めてロジスティック回帰で分類してみる。

今回、変数を除外してOne-Hotを採用したデータフレームでロジスティック回帰で分類してみました。

One-Hotは、全部採用すると時間がかかりそうだったので、いったんいくつかに絞り込んで分類を実施。

#********************************************************************
#.ロジスティック回帰で分類してみる。
#********************************************************************

#目的変数'state'を正解としてyに格納
y = df_train['state'].values
#説明変数'goal','days','country'のOne-Hotをいくつか,'main_category'のOne-Hotをいくつか,'category'のOne-Hotをいくつか、を入力としてXに格納
X = df_train[['goal','days','country_GB','country_HK','country_SG','country_US','main_category_Art','main_category_Comics','main_category_Dance','main_category_Design','main_category_Film & Video','main_category_Games','main_category_Music','main_category_Theater','category_Anthologies','category_Chiptune','category_Classical Music','category_Comic Books','category_Country & Folk','category_Dance','category_Indie Rock','category_Jazz','category_Letterpress','category_Performances','category_Plays','category_Residencies','category_Tabletop Games','category_Theater','category_Typography']].values

#ロジスティック回帰で学習
clf = SGDClassifier(loss='log', penalty='none', max_iter=10000, fit_intercept=True, random_state=1234)
clf.fit(X, y)

#********************************************************************
#.予測精度または識別精度を確認する
# 混同行列を作成し、Accuracy、Recall、Precisionを求める
#********************************************************************
# 学習した結果を使って説明変数を入力して予測
y_est = clf.predict(X)

#混同行列を作成
tn, fp, fn, tp = confusion_matrix(y, y_est).ravel()
print(fn, fp)
print(tn, tp)

#'Accuracy、Recall、Precisionを求めて表示
print('Accuracy  = {:.3f}%'.format(100 * (tn+tp)/(tn+fp+fn+tp)))
print('Recall    = {:.3f}%'.format(100 * (tp)/(fn+tp)))
print('Precision = {:.3f}%'.format(100 * (tp)/(fp+tp)))
 

Accuracy = 62.700%
Recall = 43.186%
Precision = 54.991%

 

結果としては、 Accuracyが、大幅に下がって、62.7%になりました。

Leakageに気づかず、精度が向上して喜んでいましたが、Leakageにならないように考慮した結果62.7%になりました。

成功と失敗で絞り込んだデータのうち、失敗の割合が約60%なので、全部失敗と予測するモデルとあまり変わらない精度に落ちてしまいました・・・。

改めて、検討しなおしです。

 

 2019年3月9日(土)にG検定を受験し、見事合格できました!

受験の体験記や勉強法などを別のブログにまとめました。

これから受験される方がいらっしゃいましたらご参考まで。

g-kentei.hatenablog.com