見出し画像

[競馬予想AI] 深層学習で着順予想に挑戦

前回までは機械学習による着順予想を行ってきました。今回からは深層学習(Deep Learning)による予想モデル作成を試していきたいと思います。

深層学習 概略

深層学習は今まで紹介したboosting木などと同様、分類や回帰などを行うことができます。では深層学習を使うメリットはあるのかという話になってきます。深層学習を使うメリットとしては一見抽象的な情報でもデータの関連性を自動で抽出する点にあると思います。例えば画像分析の分野で深層学習は多く使われています。画像の1ピクセルごとであったりその周辺数ピクセルとの関係は人間から見ると理解や紐づけは不可能に近いでしょう(人間は無意識に同じような理解をしてるとかしていないとか)。

深層学習の中身は例えるならろ過装置のようなもので、情報を流すと不要な情報がろ過されて必要な特徴量のみがいくつも抽出され、その特徴を利用して分類や回帰を行うイメージです。深層学習モデルを作る際に人間が行う作業はこのろ過装置を何層用意して、どのような大きさや構造にするかです。しかし、何層用意してどのような大きさにすればいいかの指針は存在しません。(GoogleのAutoMLではこの辺りを解決しようとしています)

問題によってはわざわざ深層学習を使用する必要はありません、統計的な手法を用いた方がシンプルで早いモデルを作ることが可能です。

使用する深層学習モデルの構造

とりあえず、全結合層のみで構成された深層学習モデルを用意して構造を変更しつつ性能を観察してみました。複雑なモデルとなると分岐、結合などの構造を持ち、層の数も数百数千となることがありますが、今回はシンプルな構造を採用しています。

基本的な方針としては、過学習が発生するような大きな構造のモデルを作成してから、評価指標がイイ感じになるようにモデルをシンプルにしていきます。評価指標をイイ感じにしたいので勿論、機械学習同様に評価指標を定義する必要があります。

また、今回の目的は1着の馬を当てることを目的とします。よって、不均衡データの分類問題を扱うこととなります。よって「評価指標をどうするか」という問題が出てくるわけです。不均衡データの分類問題において評価指標をどうするかは以前の機械学習の時でも記事にしましたのでこちらの記事を参考にしてみてください。

開発環境

OS:Windows10
CPU:Corei7-9700K
メモリ:16GB
GPU:GeForce RTX2070SP
フレームワーク:Keras

今回はフレームワークにKerasを使用しています。GPUによる学習を行うにはGPU対応版のKerasをインストールする必要があります。ただし、NVIDIA製のGPUに限ります。
必要に応じてデータベースを構築する必要もあるかと思います。もしそれほど大きいデータではないのであればデータベースは必要ないですし、GPUも必要ありません。このnoteで使用するモデルはCPUでも現実的な時間で学習可能です。ただ、少なくともHDDではなくSSDの方いいかと思います。120GBであれば2000円台で買えるのでおすすめです。


作成したモデルの一例

作成したモデルのひとつを紹介します。

深層学習のモデル図

3層の全結合層からなるシンプルな構造です。各層では過学習防止のためにドロップアウトを設定し、L2正則化を行っています。活性化関数はReLUを採用しています。最適化アルゴリズムはRMSpropを使用し学習率は0.1%です。損失関数はbinary crossentropy、評価指標は正解率を使用しています。
正則化や活性化関数、最適化アルゴリズムについての詳細な説明は省略します。(希望があれば解説します)

結果の混同行列は以下の通りです。

深層学習の結果表

再現率および適合率は次の通りです。
・再現率(Recall):67.67%
・適合率(Precison):14.59%

実際に1着だったものを1着だと予想できた割合が67.67%です。ところが、1着だと予想したものが実際に1着だった割合は14.59%でした。つまり、1着ではないのもの過大に1着だと予想してしまっているモデルとなります。1着の馬を取りこぼさないようにしていることがわかりますが、それでも2,112件については取りこぼしてしまっています。もう少し具体的にいうと、1レースあたり平均約34%の馬を1着と予想してしまいます。10頭レースだと3.4頭、18頭レースだと6.1頭を1着と予想してしまいます。

学習データとバリデーションデータの学習率(上)とLoss(下)は次の通りです。

画像3

画像4

正解率のグラフを見るとまだまだ上昇しそうに見えますが、Lossのグラフを見ると下げ止まりになっています。これはこれ以上学習すると過学習に陥ることを示しています。アーリーストッピングを「20エポック以上Lossが改善されない場合」に設定しているため学習は43エポック目で終了しています。
この時点でのテストデータの正解率は68.14%です。

試しに、400エポック学習させてみるとこのようになります。

画像5

画像6

混同行列

・再現率(Recall):59.20%
・適合率(Precison):13.69%

正解率は74%付近で頭打ちになり、Lossは50エポック手前から上昇しています。エポック数を増やしたところで性能は向上しないことがわかります。このモデルの場合、20エポックほどの学習で十分そうです。

class weightの設定と評価指標

このモデルでは実はclass weightを設定していました。class weightの設定は過去の機械学習のモデルでも使用したもので、クラスの割合に応じてクラスの重要度を設定するものです。具体的には、クラス1の重みはクラス0の重みより約12倍大きく設定しています。

class weightを設定しなかったらどうなるでしょうか。答えは「すべて0(1着ではない)と予想する」です。その理由も前回同様、損失関数の計算式上、すべて0とした方がよいからです。

class weightの値を変えると再現率や適合率はある程度調整できそうです。少数派(クラス1)の重みを大きくするとクラス1の取りこぼしが少なくなることが予想できます。少数派のクラスの重みを多数派の100倍にしてみます。

クラス1(1着)の重みをクラス0の100倍にした結果

画像7

画像8

混同行列

・再現率(Recall):95.35%
・適合率(Precison):9.40%

再現率は95.35%と非常に高くなりました。想定通り、クラス1の取りこぼしが少なくなりました。当然ですが反面、適合率はかなり小さくなっています。不均衡データなので特に適合率の低下は顕著です。
全頭中74.42%を1着だと予想し再現率95.35%ですので、16頭レースだと平均約4頭は1着にはならないと高確率で予想できます。重みを100倍にする例は極端ですが、class weightを大きくして再現率を上げたモデルは消去法として使えるかもしれません。

逆に、競馬の予想においては再現率が低く、適合率が高い、つまり消去法とは逆に「1着だと予想したものが実際に1着だった割合」が高い方が有用な時だってあるはずです。むしろこちらの方が有用なはずです。
では、クラス1の重みをある程度低くすればモデルの適合率は高くなるでしょうか。

class weightに対する各種指標の遷移

class weightの値の変更による再現率と適合率のトレードオフはどのくらいになるのでしょうか。class weightを少しずつ変えた時の再現率と適合率を調べてみましょう。これが分かれば再現率重視、適合率重視、バランス重視と、モデルの使い分けが可能になりそうです。

classweightによる指標の関係

※class weight(横軸)は0.5刻みですが、加えてclass weight=2.9, 6.3の時の値を挿入しています。

class weightを大きく設定すると再現率が大きくなることがわかりますが、class weightを小さくすると適合率が大きくなるかというとそこまで大きな変化はありませでした。クラス1と0を同程度に検出できれば再現率と適合率は綺麗にトレードオフになりますが、クラス1のデータの割合が少なく、また、モデルの精度がそこまで高いわけではないのでclass weightを小さくすると損失関数の計算上、class weight=2.9を境に途端すべてクラス0と判断するようになってしまいました。

F1値は再現率と適合率との調和平均です。再現率の変化量は大きくても適合率の変化量が小さいためそちらにひっぱられてF1値も下げ止まりしています。不均衡データにおいてF1値だけを見て性能を判断するのは危険であることがわかります。

正解率を見ると92%あたりから下降の一方です。先述しましたが、これも不均衡データに起因するものです。すべてクラス0としたほうが最も正解率が高くなるからです。この競馬着順予想問題(今回は1着だけ予想)におけるベースラインはこの92%ラインです。正解率92%を超えるようなモデルが出来た時、競馬着順予想AIの完成といえます。

回収率

1着を当てるモデルの場合、混同行列からおおよその回収率を計算できます。1レースに1着の馬が1頭だけいて、単勝の配当が405円(過去馬券の調和平均)と仮定すると、真陽性数×4.05÷(偽陽性数+真陽性数)×100(%)で求まります。
残念ながら今回は回収率100%を超えるようなモデルを作ることができませんでした。

精度向上のためには?

今回は単純な全結合層によるモデルを作成しました。深層学習には色んな形態が存在しますので、競馬着順予想に適したモデルの形を研究する必要があります。また、モデルに適したデータを準備し、データ形式を整える必要もあります。統計的な手法や以前扱った機械学習モデルよりも複雑なモデルが作れる一方、下準備の手間も増えてきます。
また、そもそものデータ(特徴量)を見直す必要もあるかもしれません。

アプローチを変更するのも手

今までは「着順を予想する」ことを目的に様々なモデルを作成してきましたが、例えばお金を稼ぐことが目的であるならば思い切って「回収率130%以上を目指す」とした方がよいかもしれません。
そうなるとまた異なる手法が使えるかもしれません。完全に着順を予想できずとも、例えば統計的手法であったり強化学習でカバーすることができるかもしれません。またそれらを組み合わせることもできます。

やるべきこと勉強するべきことがたくさんありますが、当noteではこれからも少しずつ色んな手法を試していきますので応援いただければ幸いです。


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