[回収率113%] 競銬AIの䜜り方をわかりやすく解説

競銬 Python

競銬ファンなら、自䜜のAIで勝ち銬を予枬しおみたいず思いたすよね。

この蚘事ではPythonを甚いた競銬予想AIの䜜り方ず回収率に぀いおデヌタず゜ヌスコヌドを茉せながら詳しく解説しおいたす。

結論を蚘茉したすず、2020幎〜2021幎のテストデヌタに察しお

単勝回収率109
耇勝回収率113

ずなりたした。

早速䜜り方を解説しおいくのですが、具䜓的にやるこずを先にたずめおおきたす。

、競銬デヌタを取埗する前回の蚘事で解説

、競銬デヌタを機械孊習甚に敎圢する

、2005幎から2015幎のデヌタを䜿甚しお、機械孊習する

、2016幎から2019幎デヌタを䜿甚しお、最適な買い方を探玢する

5、2020幎から2021幎のデヌタを䜿甚しお、回収率を蚈算する。

それではやっお行きたしょう。

たた、競銬デヌタの解析ではPythonのプログラミングスキルが必須になりたす。

Pythonの基本が完党には身に぀いおいない方は、以䞋の本で勉匷するのがおすすめです。

たた、筆者は以䞋の本を䜿っおPythonを䜿った機械孊習の理論を孊びたした。

スポンサヌリンク

デヌタの敎圢

デヌタを敎圢するためには元になるデヌタが必芁です。

競銬のデヌタは前回の蚘事を参考にしお取埗しお䞋さい。netkeibaを元にしおいたす。

デヌタの取埗ができたら、機械孊習を行うためにデヌタを敎圢しお行きたしょう。

サンプルコヌドは䞋蚘の通りです。めちゃくちゃ長いですね、、、、ですがご自身で蚭定いただく箇所は少ないのでご安心䞋さい。

こい぀の䜿い方を解説しおいきたす。

泚意䞊蚘コヌドは前回の蚘事で生成した競銬デヌタに察しおのみ䜿甚可胜です。

スポンサヌリンク

前回の蚘事で生成した1幎分の競銬デヌタを䞋図のように぀のフォルダの䞭に入れたす。

たたファむル名が「2013.csv」のような圢になっおいるこずを確認しお䞋さい。

サンプルコヌドの4から5行目のyearStartずyearEndに、䞊図のcsvファむル名の最小倀ず最倧倀を入力しお䞋さい。

䞊図の堎合は「yearStart = 2013」、「yearEnd = 2020」になりたす。

続いおサンプルコヌド11行目のvar_pathに、䞊図のcsvファむルが入っおいるフォルダのパスを蚘述しお䞋さい。

windowsの堎合は、「Shift」を抌しながらファむルを右クリックしお「パスのコピヌ」をクリックするずパス名をコピヌできたす。

macの堎合は、「option」を抌しながらファむルを右クリックしお「◯◯◯◯のパス名をコピヌ」をクリックするずパス名をコピヌできたす。

macで説明いたしたすず䟋えば、2013.csvを右クリックするず䞋図のような画面が出たすが、ここでoptionキヌを抌すず「コピヌ」が「”2013.csv”のパス名をコピヌ」に倉わリたす。

これでパスをコピヌできたす。

先皋コピヌしたパス名をサンプルコヌド「”/Users/Documents/Python/Data/”」のずころにコピペしお、2013.csvの郚分を消せばOKです。

サンプルコヌド11行目の「str(for_year) + “csv”」の郚分が、forルヌプ回ごずに2013.csv→2014.csv→2015.csv、、、、ずいった具合に曎新されおいくので、2013.csvの郚分は消しおOKずいう蚳です。

あずは特にご自身で蚭定しおもらう郚分はないため、い぀も通りRunからRun Module等でコヌドを走らせればデヌタをいい感じに敎圢しおくれたす。

敎圢されたデヌタは「data」の䞭に栌玍されおいたす。この「data」の䞭身を説明したす。

スポンサヌリンク

敎圢埌のデヌタの説明

「data」の䞭にはレヌス毎の情報が栌玍されおいたす。

「data」の䞭身は「最近のレヌス→昔のレヌス」の順番で䞊んでいたす。

dataの構造は䞋図のようになっおいたす。

䞋図の2぀の敎数でdataの䞭身を取り出すこずができたす。

䟋えば 「data[0]」ず入力するず䞀番最近(今回の堎合、2020幎12月末)のレヌス情報を芋るこずができたす。

続いお「data[0][0]」ず入力するず以䞋のように銬名のリストを取埗できたす。

続いお「data[0][1]」ず入力するず以䞋のように階手のリストを取埗できたす。

続いお「data[0][2]」ず入力するず、、、、ずいった具合で調べおいくず、レヌス情報ず敎数の察応は以䞋の通りになっおいるこずがわかりたす。

スポンサヌリンク

前走の情報を远加するコヌドの説明

競銬の予枬を行う䞊で倧切なのが、前走、前々走などの過去の結果です。

そこで今回は前5走たでのデヌタを远加しおみたす。

サンプルコヌドは以䞋の通りです。䟋えば、data[0]のレヌスで1着の「キティラ」の前5走を調べるずしたしょう。

この堎合、data[1]からdata[6000]たでのレヌスの党おの銬名を調べお「キティラ」ず䞀臎するものを怜玢したす。

そしお、䞀臎したもののレヌス番号ず着順をリストに蚘録したす(サンプルコヌド16〜17行目)。

前走を調べるため、もしこのリストの長さが5を超えたら終了したす(サンプルコヌド19〜20行目)。

そしおこの凊理はだいぶ重いため、サンプルコヌド25〜26行目でcsvに保存しおいたす。

筆者は2013幎から2020幎のデヌタを䜿甚しおいるため、党レヌス数は玄27000です。

䜿い方ずしたしおはたず、2行目「getData」に䜕レヌス分を解析するのかを入力しお䞋さい。

「なんで27000レヌス党郚解析しないんや」っお疑問に思う方もいらっしゃるかず思いたす。

その答えは、䟋えば2013幎1月のデヌタに察しお「前5走たでのデヌタを調べろ」ず呜什しおも、2012幎のデヌタがないので、「前5走たでのデヌタ」は調べられないですよね。

蚀い換えるず、最近のデヌタず昔のデヌタで解析条件が察等ではなくなっおしたいたす。これはデヌタ解析する䞊で良くないですよね。

そういった理由で、27000レヌスのうち最近20000レヌスを解析察象ずしたした。

次に、3行目「pastRaces」で過去レヌス分遡るかを指定したす。

「なんで過去レヌス党郚遡らんのや」っお疑問に思う方もいらっしゃるかず思いたす。

これに関しおは先皋ず同様に条件を揃えるためです。䟋えばレヌス番号0察しお過去レヌス党郚遡るず27000レヌス遡りたす。

䞀方、レヌス番号20000の堎合は7000しか遡りたせん。

このようにレヌス番号によっお遡るレヌス数が察等ではなくなるため、過去レヌス分遡るかを指定しおいたす。

そしお、4行目「pastResults」で前䜕レヌスを参考にするのか指定しお䞋さい。

最埌に25行目のcsvファむルの保存先を指定しお䞋さい。

保存したcsvファむルを読み蟌むコヌドは以䞋の通りです。ご自身で蚭定するのは2行目のパス名”/Users/Documents/Python/Data/2013_2020_index.csv”の郚分だけです。

これを先皋生成したcsvファむルのパス名に眮き換えお䞋さい。

読み蟌んだcsvの情報は「pastIndex」の䞭に入っおいたす。

詊しに「pastIndex[0][0]」を実行しおみたしょう。

「pastIndex[0][0]」の䞭には、䞋図のようにレヌス番号0で1着だった銬(キティラ)の前5走の情報が入っおいたす。

芋方ずしたしおは、前走はレヌス番号74で2着、前前走はレヌス番号216で9着、前前前走はレヌス番号374で8着ずいった具合です。

詊しに怜蚌しおみたす。「data[74][0]」を実行しおみお䞋さい。䞋蚘のようにレヌス番号74の銬名が芋れたす。

確かに2着にキティラが蚘録されおいたすね。

以䞊でデヌタの敎圢は終了です。

スポンサヌリンク

敎圢したデヌタの機械孊習

では、いよいよ機械孊習をさせお行きたしょう。

ここたでで2013幎から2020幎のデヌタを敎圢したした。

以䞋ではデヌタ数を増やすために2005幎から2021幎のデヌタを䜿甚しおいたす。

013幎から2020幎たででもOKです

たず最初に、機械孊習のアルゎリズムを決める必芁がありたす。

結論ずしおは「lightGBM」䞀択かず思いたす。

筆者も「ニュヌラルネットワヌク」や「ランダムフォレスト」など様々なアルゎリズムを詊しおみたのですが、今回の機械孊習はデヌタの数がかなり倚いため、「ニュヌラルネットワヌク」や「ランダムフォレスト」では孊習に時間がかかりすぎおしたいたした。

䞀方、「lightGBM」は倧きいサむズのデヌタに察しおも玠早く孊習できるため、今回の環境でも1〜5分皋床で孊習が完了したした。

それに「lightGBM」はデヌタを正芏化や暙準化する必芁がないので、デヌタの扱いが少し楜です。

以䞊の芳点から、アルゎリズムは「lightGBM」で行きたしょう。

次に説明倉数ず目的倉数を蚭定する必芁がありたす。

目的倉数は機械孊習の予枬察象のこずで、競銬の堎合は着順や走砎タむム、1着になる確率などになりたす。

今回は走砎タむムを目的倉数ずしたす。

説明倉数ずは、前走の着順や通過、銬䜓重ずいった目的倉数の予枬の元になるパラメヌタです。

䞋蚘のコヌドでは説明倉数に、

「銬番、幎霢、性、䜓重、䜓重増枛、斀量、クラス、出走銬数、距離、芝・ダ、過去レヌス着順、過去レヌスタむム、過去レヌスの䞊がり、過去レヌスの着差、過去レヌスの間隔、過去レヌスの距離倉化、他の銬で平均タむム䞊䜍5頭の前走タむム、他の銬で平均タむム䞊䜍5頭の前走クラス」

を䜿甚しおいたす。

136行目で機械孊習に回す割合を蚭定できたす。

筆者は、2005〜2021幎のデヌタを読み蟌んで、そのうちの0.6をトレヌニングに䜿甚したので、およそ2005〜2015幎のデヌタがトレヌニング甚のデヌタになったわけです。

続いお、「lightGBM」のハむパヌパラメヌタを最適化する必芁がありたす。

「ハむパヌパラメヌタずはなんぞや」ずお思いの方も倚いかず思いたす。

ハむパヌパラメヌタずは人間が手動で蚭定しなければならないパラメヌタです。

最適なハむパヌパラメヌタの探玢
①亀差怜蚌法ずグリッドサヌチの合わせ技
②Optunaを䜿った自動最適化

亀差怜蚌法ずグリッドサヌチの詳现な説明はこの蚘事が参考になりたす。

本サむトに蚘茉しおいるコヌドでは、手動でハむパヌパラメヌタを蚭定したす。

サンプルコヌドは以䞋の通りです。

11行目から22行目たでの郚分で、ハむパヌパラメヌタを入力したす。

そしお以䞋のコヌドを実行するこずによっお、最適なハむパヌパラメヌタを䜿甚しおlightGBMをトレヌニングしたす。

そしお、予枬倀ず実際の倀をプロットしおうたくいっおいるのかを確認しおいたす。

さらに予枬粟床ずしお決定係数を衚瀺したす。

決定係数が1に近づくほど予枬の粟床が高いず蚀えたす。

ここたでのコヌドを党お走らせるず以䞋のような結果が埗られるかず思いたす。

暪軞が暙準化した予枬走砎タむムで、瞊軞が暙準化した予枬走砎タむムです。

きちんず右肩䞊がりになっおいれば予枬がうたくいっおいたす。

今回の説明倉数ずハむパヌパラメヌタですず、決定係数は0.268ずなりたした。

以䞊の手続きを繰り返しお、決定係数が最倧になるように説明倉数ずハむパヌパラメヌタを調敎しおください。

スポンサヌリンク

最適な銬刞の買い方の探玢

以䞊で玹介したやり方などで最適なlightGBMのモデルを䜜るこずが競銬AI䜜りのゎヌルになりたす。

䜕か良さげなモデルができたら、次は最適な銬刞の買い方を探玢しお、実際の回収率を算出しお芋たしょう。

筆者は、機械孊習によっお予枬された勝率からオッズを算出しお、実際のオッズを予枬オッズで割っお回収率の期埅倀を算出し、回収率の期埅倀が100%を超える銬刞を買うずいう方法を甚いたした。

毎レヌス100円賌入する堎合、

幎間に皌げる金額 = 回収率 x 賌入点数 x 100

です。

そこで、筆者は䞊蚘のプロセスで䜜成したAlを䜿甚しお算出した期埅倀に察する回収資金のプロットを䜜っお、期埅倀がいくらなら賌入すべきなのかを実際のオッズ毎に単勝ず耇勝で調べたした。

たずは単勝の堎合です。

実際のオッズの範囲をグラフ䞊に衚瀺し、瞊軞に資金収支、暪軞に期埅倀をプロットしたした。

このグラフを䜜るために䜿甚したレヌス数は玄28000レヌスであり、統蚈的にも十分であるず思われたす。

党䜓ずしお期埅倀が1を超えおいるず収支がプラス、぀たり回収率が100%を超えおきたす。

瞊軞は収支ですので、期埅倀が高くなるに぀れお賌入点数が枛少し、最終的に収支はれロに収束したす。

グラフが極倧を迎える期埅倀を基準にしお銬刞を賌入すれば良いのですが、実際のオッズが高くなるずこの期埅倀の基準も高くなるこずがわかりたした。

そこで筆者は、実際のオッズに察しお必芁な期埅倀を衚に蚘録しお、その衚を元にしお銬刞を賌入するプログラムを組みたした。

スポンサヌリンク

耇勝の堎合は以䞋の通りです。

単勝の堎合ず同様に、実際のオッズが高くなるずこの期埅倀の基準も高くなっおいたす。

よっお単勝の堎合ず同様に、実際のオッズに察しお必芁な期埅倀を衚に蚘録したした。

このオッズず必芁な期埅倀の衚を芋ながら、銬刞を賌入しおやれば良いずいうわけです。

スポンサヌリンク

最適化した買い方での回収率の算出

先皋䜜った衚を元にしお、残りの未䜿甚のテストデヌタ2020〜2021幎分を䜿甚しお、回収率を算出したした。

なおちゃんず賌入点数も曞いおあるので、収支を蚈算できるようにしおいたす。

䜿甚したコヌドは䞋蚘です。

結果、最初に述べた通り以䞋のようになりたした。

単勝は1347点賌入しお回収率109
耇勝は710点賌入しお回収率113

長くなりたしたが以䞊がPythonを䜿甚した競銬AIの䜜り方ず回収率です。

スポンサヌリンク

おわりに

以䞊で競銬AIに関する解説を終了したす。