[儲からない競馬予想AI] 閑話2 : 強化学習は競馬予測で使えない

閑話として強化学習が競馬予想に使えない話をしておきます

強化学習については知っている前提で話します。知らなければこの話は読まなくて構いません。
一応参考として、

Reinforcement Learning (DQN) Tutorial — PyTorch Tutorials 2.3.0+cu121 documentation
PyTorch 1.8 : 強化学習 : 強化学習 (DQN) チュートリアル – Dify, Transformers, Diffusers

を上げておきます。

なぜ使えないのか

競馬で儲けるというのもマネーゲームとして捉えれば、ゲームです。
そうすると、自然に強化学習を利用するアイディアが生まれてきます。
しかし、単純に競馬予想に強化学習を使うことはできません。

理由として次の2点をあげます

行動と環境の相互作用が無い

強化学習のモデルは基本的には行動と環境が相互作用し合うことを前提としています。

  1. ある状態で行動する
  2. 環境が変化する
  3. 報酬が得られる

の3ステップを繰り返す様な状況を想定して理論構築されています

これを競馬予想に当てはめてみると、2番目の「環境が変化する」という点が当てはまらなくなります。なぜなら、状態(任意のレースの状況)に対して、行動(馬券の購入等)を起こしても、次の状態(別のレース状況)が変化するわけではないからです。

さらに言えば、各レースは時系列を持ちますが、出馬している馬は独立しており、任意の日付のレースを入れ替えても対して問題はありません。

つまり、上の3ステップを繰り返すという過程が既に崩壊しているのです。

式変形するとオッズと着順予想をしている

強化学習で学習する関数とは、状態を入れたときに、各行動の行動価値を出力する関数でした。

まず、状態(ある馬のレースのデータ)\(s\)を入れたときに、2つの行動\(a_1\)、\(a_2\)をとるとします。
このとき、

  • \(a_1\) : 単勝にベットする。値はベットしたときの利益
  • \(a_2\) : ベットしない。値は0

としましょう。つまり\(s\)を入れて\(a_1\)、\(a_2\)を出力する関数を作ることが強化学習の目的なわけです。

ここで、\(a_1\)について式を作ってみます。\(a_1\)とは以下の式で与えられる値です。

$$
a_1 = \text{hit} \times \text{odds} – 1.0
$$

  • $\text{hit}$ : その馬が一番か否かの0, 1
  • $\text{odds}$ : その馬の単勝オッズ

つまり、その馬が勝てば、掛け金(1.0)を引いたoddsが利益として返ってくる。
その馬が負ければ、掛け金(1.0)が損益となるわけです。

単純な強化学習の目的関数では、

$$
\text{NN}(s) = a_1′, a_2′
$$

$$
a = \max{(a_1′, a_2′)}
$$

とした行動\(a\)に対して、実際の報酬(\(a_1\)もしくは\(a_2\))との誤差を計測し、Neural Network(NN)を学習します。

ここで、行動\(a_2\)は明らかに常に0ですから、学習せずとも\(a_2\)の値は定まってしまいます。

つまり、NNは\(a_1\)を学習すればよいということです。
ということは、上の式で(\(a_1\)が\(\text{hit}\)と\(\text{odds}\)で表現されることは既知ですから、\(\text{hit}\)と\(\text{odds}\)を予測できればよいということになります。

つまり、

$$
F_1(s) = \text{hit}
$$

$$
F_2(s) = \text{odds}
$$
の2つの関数を別々に作れればよいということであり、これはまさしく、Chapter2で行ったlightGBM実験で示してきたことであり、単純なClassification・Regression問題です。わざわざ強化学習の形式を取る必要がありません。

まとめ

何をこの話で伝えたかったかというと、無理やり強化学習を行ってもLightGBMで順位とオッズ予想する関数を作ることと同義であり、それならLightGBMのほうが性能が良い、ということでした。

※実際に試してみましたが、やはり強化学習はうまくいかず、時間の無駄でした。
状態と行動を別の形式を考えることができれば、もしかしたらうまくいくかもしれません。

タイトルとURLをコピーしました