Selection)についてまとめました。aotamasaki.hatenablog.com今回は実際に実装してみます。目的を見失うのを防ぐために、何が目的でどんなことをするのか実験設定を明記します。目的いくつかの変数選択手法によって変数を選択し、モデルの改善を確かめる。用いるデータirisとかもう見すぎて飽きてるのでKaggleから取ってきました。Kaggleこのデータは、クレジットカードのデータから不正使用されたかどうか当てるタスクに用いることができます。オリジナルデータは機密情報で会社としては公開できないので、このデータはオリジナルのデータをPCAしたものになります。説明変数の実態がなんなのかわからないのでハンドクラフトに特徴をピックアップすることができず、今回の変数選択手法を試すのにはぴったりなデータセットだと思います。Classが1であるサンプルが著しく少ないインバランスなデータです。中身を見てみるとこんな感じです。メインディッシュです。Method2つで、後で述べる評価指標で比較したいと思います。用いる判別器ロジスティック回帰を用いて行います。理由としては、計算が軽量であることや線形分離で判別できそうということが挙げられます。(あとで可視化します。)評価指標10CVでRP-AUC(PR曲線の下側の面積)の標本平均を用います。PR曲線はROC曲線の親戚のようなもので、インバランスデータを評価するのに適しています。詳しくは過去の記事を見てください。aotamasaki.hatenablog.com行わないことインバランスへの対応(用いるデータはClass==1が著しく少ないデータになっています。)パラメーターサーチこのデータに対してどの判別器が適しているのかクラス分類をするための閾値の設定この判別に対して最終的なモデルを示すつまり、変数選択の結果、判定器が改善されたかだけを見ます。データを少し見てみるdatasetのV1~V3を可視化してみます。これだけでもなんとなく線形分離可能なんじゃないかと予想できます。変数選択が有用ということを示すには、比較対象が必要です。すべての特徴を用いてロジスティック回帰を行った場合に、どれぐらいのスコアが出るのか確認してから変数選択した場合と比較しましょう。0.76342498463すべての何も考えず特徴を用いたとき、0.763となりました。Methodによる変数選択を行ってみます。今回、特徴(説明変数)が連続値で、目的変数がカテゴリーなので、前回の記事の表に従うとLDAを用いて、目的変数に対して特徴が効いてるのか見ることになります。sklearnで楽にやりたかったこともあり今回はANOVAのF値を指標にしました。これは、sklearn.feature_selection.SelectKBestでf_classif(判別分析用)を指定したときのスコアになります。ANOVAのF値については、いろいろ検索してみましたがこちらが私的にわかりやすいと感じました。分散分析とは何か?(データの変動からいかにして誤差と処理による変動に分けるか?)(このF値とF分布を用いると検定の枠組みに持っていくことができて、その特徴がどの程度の確率で有意なのかも定量的に判断することができますが今回は考えないことにします。)さて、では実際に変数選択してみましょう。各クラスごとに各特徴の確率分布を描くことによって、効いてそうな特徴を目視で選択してみることにします。目視により選択すべての説明変数の確率分布を表示してみました。図が多いのでここではわかりやすい図だけ示します。これを使ってロジスティック回帰を評価して見ようと思います。0.782114705419目視で変数選択したときのスコアは0.782となりました。目視ではなくもっと機械的に決めます。前述したようにANOVAのF値を用いています。その上位K個を返すといった関数です。いくつ変数が選ばれたらモデルとして良いのかわからないため、選ぶ変数の数を探索します。特徴が選ばれていく様子を示します。用いる説明変数の数とそのときのスコアは以下のようになりました。0.759085348642モデルに使う特徴の数とスコアの関係を図示します。scores)show(p)21番目の説明変数を加えた途端スコアが大きく伸びました。21番目に追加された説明変数'Time'の確率分布を見てみましょう。5)plt.show()分けられるか微妙ですが、もしかしたら他の変数に対するマルチコが少なく他の変数と組み合わせると有効に働くのかも知れません。上位5つの特徴だけを用いたときと、上位5つ+'Time'を用いたときを比較しましょう。0.811386618241Timeも特徴に含めたほうが、結果として一番良いスコアが出ました。SelectKBestでは選ぶことができなかったので、FilterMethodを用いた結果としては、0.782の方を採用します。Timeは有用な変数だったにもかかわらず、SelectKBestで見逃されたようです。多重共線性を考慮できないのがFilterMethodの問題点です。eliminationを用いた選択です。fontsize=15)plt.show()選ばれた特徴でスコアを算出します。0.788190162305先程と同じように'Time'が選ばれていません。問題となったTimeも加えて評価してみました。0.809050680037少しだけスコアが上がりました。これもRFECVが自動的に選んではくれなかったものなので、ここでのスコアは0.788とします。Borutaによる変数選択これはrandomForestを用いた変数選択手法の一つで、詳しいアルゴリズムはこちらの3ページに書いてあります。0.7962962687520.796というスコアになりました。適当にパラメーターを決めたり、ロジスティック回帰でいいのかという疑問はありますが、ひとまずこれを採用したいと思います。計算時間に関しては、2.5GHzCorei5で4時間程度かかりました。計算中はメモリも2GBぐらい持っていかれたと思います。0.796まとめ4つの変数選択を試してみて、共通してすべての特徴を用いたときよりもスコアが改善した。スコアが良かったのはborutaを用いた場合だった。borutaは計算時間が著しくかかった。sklearnを用いた場合も結構かかった。用いる判別器によってはborutaと同じぐらいかかるかも知れない。Methodを用いるのがよいかもしれない。お問い合わせはてなブログをはじめよう!aotamasakiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。