競艇や競馬の買い目最適化(ケリー基準の一般化)
問題設定
特定のレースの特定の券種で、確定オッズ(以下オッズ)と的中確率は所与とします。
そのうち、期待値がを超える券が
枚あるとします。
枚の券のうち、
番目の券の、オッズを
、的中確率を
とします。
それぞれの券の期待値がを超えるので、
です。
さて、このときそれぞれの券にいくらずつかけるのが最適ですか?という問題です。
ただし、何レースでも購入でき、オッズは低下せず、少数金額も購入できるとします。
(他にも条件あるかもしれませんが、このくらいで。)
最適化
番目の券を所持金の
倍購入するとします。
いま、枚の券はすべて同じ券種であるため、互いに排反な事象となります。なので、的中してもどれか1枚です。
(※券種は複勝や拡連複ではないとして、さらに同着や返還等も考えません。)
なので、レースが終わったときの結果の事象としては、
枚の券のうちどれか1枚が的中するか、全部外れるかです。
したがって、ケリー基準を導出する際と同様に考えて、
この関数を最大化します。
ただし、です。
また、の
は、あらゆる
の組み合わせ的な感じです。
なぜこの関数を最大化するのかは、上記参考サイトに任せますが、
イメージとしては、
枚全部外れる確率は
で、そのとき所持金は
倍になる。
番目の券が的中する確率は
で、そのとき所持金は
倍になる。
それらの期待値のような感じです。
掛け算や指数があれなので、最適化の常套手段である対数変換をします。
ベクトルで偏微分とか苦手なので、地道にいきます。
上式を、番目の券の購入割合
で偏微分してイコール
とおくことで、
となります。
ここで、第1項と第2項はによらず一定です。
なので、別の番目の券の購入割合
で偏微分した場合は、
第3項だけが変わるので、
が成り立ちます。
変形して、
となります。
この式により、偏微分した式の第2項の総和の中身のインデックスを
オッズの比をかけることで、変換できるようになります。
第2項の総和の中身のインデックスを
に変換します。
とおいて、さらに変形をつづけます。
上式はすべてのについて成り立ちます。
ここまでくるともう少しですね。
いま求めたいのは、ですけど、
線形になっているので、解けますね。
具体的には、
次元縦ベクトル
、
の行列
、
次元縦ベクトル
とすると、
が成り立ちますので、最適なは、
と求まりました。
の場合について考えて、ケリー基準と一致するか確認してみます。
のとき、
なので、
となります。
ここで、
なので、
となり、普通のケリー基準の式と一致します。
(参考サイトや一般的に紹介されているケリー基準と違うのはオッズの置き方によるもの。本質的には全く同じ。)
数値シミュレーション
求めた解が正しいか、数値シミュレーションで確認します。
現実ではありえないかもしれませんがで、
という状況を考えます。
期待値はそれぞれ順にとなります。
番目の券が一番期待値高いです。
番目と
番目の券は期待値同じです。
最適なを求めると、
となりました。
番目と
番目の券を比較すると期待値は同じですが、
確率は番目の券の方が高いため、購入金額の割合は大きいです。
番目の券が一番期待値高いですが、一番購入金額は低くなりました。
的中確率が小さいためですね。
では、この設定で5000レースシミュレーションしてみます。
また、最適なに、
定数を掛けた場合も同時に示します。


横軸はレース数、縦軸は所持金で対数グラフです。初期所持金はとしました。
どうやら、求めたものは正しかったようですね。
最適なより小さいと、資産の増え方は下がりばらつきが抑えられます。
一方最適なより大きいと、資産の増え方は下がりばらつきが増えます。
レース数が少ないとき、一時的に資産が最適なのときの資産を上回る可能性はありますが、長期的にみるといいことないですね。
なので、ハーフケリーとかの方法があるんですかね。
おわりに
今回は、的中確率とオッズが所与のときの買い目を最適化しました。
今後の課題としては、
- 複数種類の券種がある場合どうなるか
- 的中確率やオッズが確立変数として与えられたときどうなるか
です。気になります。
のちのち考えていきます。
Rコード
library(ggplot2) p=c(0.1,0.2,0.3) o=c(15,6,4) N=length(p) p0=1-sum(p) o0=1-sum(1/o) f=solve(matrix(p0-p*o*o0,ncol=N,nrow=N)-diag(N)*p0*o)%*%(p0-p*o*o0) p*o f R=5000 flg=sample(1:(N+1),R,prob=c(p,p0),replace=TRUE) ff=f data=data.frame(R=1:R,w=cumprod(c(1+ff*o-sum(ff),1-sum(ff))[flg])) g=ggplot()+geom_line(data=data,aes(x=R,y=w),color=2)+scale_y_log10() for(i in seq(0.2,0.8,by=0.2)){ ff=f*i data=data.frame(R=1:R,w=cumprod(c(1+ff*o-sum(ff),1-sum(ff))[flg])) g=g+geom_line(data=data,aes(x=R,y=w)) } g ff=f data=data.frame(R=1:R,w=cumprod(c(1+ff*o-sum(ff),1-sum(ff))[flg])) g=ggplot()+geom_line(data=data,aes(x=R,y=w),color=2)+scale_y_log10() for(i in seq(1.2,1.8,by=0.2)){ ff=f*i data=data.frame(R=1:R,w=cumprod(c(1+ff*o-sum(ff),1-sum(ff))[flg])) g=g+geom_line(data=data,aes(x=R,y=w)) } g