競艇や競馬の買い目最適化(ケリー基準の一般化)
問題設定
特定のレースの特定の券種で、確定オッズ(以下オッズ)と的中確率は所与とします。
そのうち、期待値がを超える券が枚あるとします。
枚の券のうち、番目の券の、オッズを、的中確率をとします。
それぞれの券の期待値がを超えるので、です。
さて、このときそれぞれの券にいくらずつかけるのが最適ですか?という問題です。
ただし、何レースでも購入でき、オッズは低下せず、少数金額も購入できるとします。
(他にも条件あるかもしれませんが、このくらいで。)
最適化
番目の券を所持金の倍購入するとします。
いま、枚の券はすべて同じ券種であるため、互いに排反な事象となります。なので、的中してもどれか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