見出し画像

[競馬予想AI] 特徴量の選択と作成で精度向上を目指そう

今回は特徴量を選択、新規作成してモデルの性能向上を目指します。

前回はLightGBMによる予測を行いました。
また、同時にOptunaによるハイパーパラメータチューニングも行いました。

このモデルの性能は(ROC-AUC:0.7755)でしたのでこのあたりをベースラインとし、特徴量によってどの程度性能向上ができるか見ていこうと思います。

特徴量作成の作業

特徴量を作成するにあたってまず、特徴量はどのようにしてつくればよいかという疑問があるかもしれません。特徴量を作成するための作業としては次のようなものがあります。

変数を変換する

欠損値を適切な値に置き換えたり、標準化、非線形変換をします。
欠損値をどのような値に置き換えるかはその都度熟慮する必要があります。標準化は深層学習で効果を発揮することがあります。LightGBMのような木構造モデルではあまり効果が無いといわれています。

カテゴリ変数の変換

文字通りカテゴリ変数を変換します。特に深層学習ではカテゴリ変数が含まれているとうまく学習できない場合があります。LightGBMではカテゴリ変数を認識してよろしく処理してくれますが、認識してくれないモデルを使用する場合はカテゴリ変数を変換する必要があります。

変換方法には以下のようなものがあります。
・one-hot encoding
・label encoding
・target encoding

one-hot encodingは次元数が膨大になる(カテゴリ数の数だけ次元が増える)場合がありますし、target encordingはリーク(*1)になる可能性があるので注意が必要です。

*1「リーク」:通常では不明なはずのデータを使用してしまうこと。例えば未来のデータを使ってしまうなど。

時系列を考慮して特徴量を作成する

平均線や週別、月別など、時点を考慮した特徴量の作成があります。時系列データを扱う時はリークが起きないように十分注意して特徴量を作成する必要があります。

ドメイン知識をもとに特徴量を作成する

その分野の知識をもとに特徴量を作成します。例えば、トレーディングAIであれば金融に関する知識(金融特融の指標など)をもとに特徴量を作成します。よって、その業界についての深い知識が必要になります。担当者と綿密に打ち合わせをしたり、書籍などを購入して勉強することも必要です。

競馬の場合ではよく使われている「スピード指数」などを利用するのも良いかもしれません。また、その指数がどういう意図で生み出されたのか背景を探ることでオリジナルの指標を作成するヒントになるかもしれません。


特徴量選択の作業

特徴量選択ではその特徴量を採用するか否かの判断と、次元圧縮が主な作業になります。

特徴量の重要度を調べる

その特徴量がどれくらい重要かを調べなければ特徴量の採否の判断ができません。特徴量を1つずつ変更してモデルの性能指標にどれだけの変化があるかを見ることである程度の重要度は判断できますが、LightGBMではfeature_importanceメソッドを使うことで特徴量の重要度を調べることができます。

importance = pd.DataFrame(model.feature_importance(importance_type='gain'), index=X_train.columns, columns=['importance'])

引数のimportance_typeは何を使うべきかという議論はしばしばあるのですが、'gain'で良いかと思います。値の幅が大きすぎてよくわからない!という場合は正規化して見やすくしてみると良いと思います。

特徴量を選択する

feature_importanceが0の特徴量は削除してもいいと思います。このような特徴量はLightGBMでは残しておいても良いのですが、深層学習ではノイズとなってしまうことがあるようですので削除しておいたほうが良いでしょう。

また、統計量を計算して特徴量同士の関係や、特徴量と目的変数との関係を調べるなど慎重かつ丁寧に特徴量を取捨選択していくことが大切です。

次元削減

主成分分析を使って次元圧縮をすることで情報量はほぼそのままに次元数を減らすことができます。それにより予測の処理を早くすることができます。主成分分析の詳細はとても複雑なので省略します。(カーネルや分散、誤差、射影などのお話になります)

ほかの次元削減アルゴリズムではt-SNEなどがあります。主成分分析による次元圧縮は線形変換なのに対し、t-SNEは非線形変換が可能です。これも詳細は省略しますが非線形なので主成分分析より柔軟に次元を圧縮できるというイメージです。

以上のように、特徴量による性能向上については「選択」と「作成」のフェーズを繰り返して有効そうな特徴量を見つけていくのが基本的な作業になります。


その他の特徴量の作成方法

特徴量を機械学習で作成する方法があります。例えば、近傍法などのアルゴリズムを使って教師なし学習を行い、それによってクラスタリングされたデータを特徴量として利用するものです。解く問題によっては有効な場合もあるようですので当noteでも次かその次の更新で試してみようと思います。


今回作成した特徴量

新たに17種類の特徴量を作成してみました。

・変数変換、時系列に関する特徴量:13種類
・ドメイン知識による特徴量:4種類

どのような特徴量を追加したか少し具体的にいうと、現在使用している特徴量は過去の成績や同じレースの馬の情報がほとんど入っていません。レースという性質上、一緒に走る馬のデータなど、馬同士の比較ができるデータも必要と考えました。しかしながら時間の都合上、今回は馬同士で比較できる特徴量がほとんど作成できず、その馬の過去の成績などを中心に特徴量を作成しました。とっかかりとしては変数変換による特徴量作成がお手軽なのでここから始めてみるのが良いと思います。

特徴量作成においてはデータ操作ができないといけませんので、Pythonではpandasをゴリゴリ使います。データ操作が難しい、苦手な方はこのような書籍で練習してみるのがおすすめです。

データベースの操作をしたことがある方なら記法の違いによる問題だけでイメージはわきやすいと思います。
データの集計、加工などはどの業界でも必要なのでできるようになっておくと何かと便利だと思いますし、機械学習の分野では必須なので是非マスターしてみてください。


精度は上がったか?

特徴量を追加する前と後の比較は次のとおりです。

比較表

ROC-AUCは0.0074上昇し、log_lossは0.0021下がりました。わずかに精度が上がったようですがまだまだ変化幅は小さいです。ROC-AUC=0.8は欲しいところです。ちなみにですが、ドメイン知識による特徴量ではほとんど精度は上がりませんでした。


まとめ

特徴量の選択と作成について紹介しました。

特徴量はモデルの精度にかかわる重要な要素なので、統計学やドメイン知識をフルに活用して作成していくことになります。時には時系列分析の知識も必要になるかもしれません。また、特徴量を作成するためのデータ操作の技術も必要になります。

今回、多少の精度向上は見られましたがまだまだ特徴量を吟味していく必要があると思います。


あとがきと今後の予定

今まで当日のオッズ情報は使っておらずもし使ったらどうなるのかなという出来心から使ってみたのですが、ROC-AUC=0.8301と直近の目標0.8を軽々超えました。回収率を計算するとどの馬券でも2%ほど値が向上しました。この変化が大きいか小さいか判断が難しいですが、特徴量作成によって精度が向上しても回収率上昇が頭打ちになることも考えられます。

ということで、回収率向上を目指すのであれば馬券購入戦略についても本格的に考えないといけないのかなと思っている次第です。もうしばらくはモデルの精度向上を目指しますが、回収率向上のための記事も楽しみにしていただけたらと思います。

よろしければサポートをよろしくお願い致します。いただいたサポートは今後の技術向上のために書籍費用等に当てられ、このnoteで還元できればと思います。