これまでの話とこれからの話
前回回収率100%超えて喜んでたけど、的中率を求めると酷いことが分かってしまった。
なんと単勝的中率1%!
つまり、手堅いのを外し続けて、まぐれ大当たりで結果的にプラスになってただけだった。
そこで、的中率も重視してより良いAIを作りたいのが今回の話。
要約
ランキング学習を取り入れることで、単勝的中率80%を達成した。
回収率は据え置きなので問題なし。
ただ、どうせなら三連単/複の的中率もせめて50%は超えたいので今後も調整していく。
今回のアプローチ
今までは分類問題として解いていた。(今回も分類問題ではある)
しかし分類問題の中にも色々あるようで、一般的に行われる分類問題は「ポイントワイズ法」と呼ばれる。
これはワンホットベクトルのように一つだけ立ってるものを当てるような話。
点を予測する。
対して、ランキング学習は順序を予測する。
ざっくり概要としては、1, 2, 3の並びを予測するために、考えられる並び順から一つ選ぶようなもの。
組み合わせは以下の6通りあり、この中から正解の一つを選ぶ。
- 1 2 3
- 1 3 2
- 2 1 3
- 2 3 1
- 3 1 2
- 3 2 1
仮に正解が2 1 3
だとすると、ワンホット的に書くと[0 0 1 0 0 0]
を与えるような話。
厳密には全然違うので専門家から怒られそうだが、イメージはそんな話。
本記事では、そういったランキング学習を取り入れて予測を行う。
実装と結果
lightGBMを使用して実装した。
使用するデータは前回の記事と同様で、中央レース2008~2022年を学習データ、2023年以降をテストデータとする。
説明変数は以下の25変数。
- 馬番
- 人気
- 単勝
- 馬場(札幌、函館、……、小倉)
- 距離
- 性別(牝、牡)
- 年齢
- 馬体重
- (馬体重の)増減
- 前走からの日数
- 前走順位~5走順位
また、着順を以下のようにラベルを振る。
- 1着→3
- 2,3着→2
- 4,5着→1
- 6着以降→0
学習プログラムは以下。
model = lgb.LGBMRanker(n_estimators=1000,
random_state=0,
learning_rate=1 * 1e-1,
)
model.fit(
train,
target,
group=groups,
eval_set=[(test, ans)],
eval_group=[tgroups],
early_stopping_rounds=10,
verbose=1,
eval_at=[1, 3, 5],
eval_names=["test"],
)
これで学習させた結果が以下になる。
単勝的中率は81%となり、良い感じ。
三連の的中率が35%というのが残念だが、今後の工夫次第では上昇が期待できるだろう。
[単勝] 回収率: 82609.19% (馬券: 2,785,500, 払戻: 2,301,079,000.0)
[三連単] 回収率: 2515949204.56% (馬券:33,426,000, 払戻: 70,081,765,093,000.0)
[三連複] 回収率: 20000845.02% (馬券: 5,571,000, 払戻: 1,114,247,076,000.0)
[単勝] 平均回収率: 14.83%
[三連単] 平均回収率: 451615.37%
[三連複] 平均回収率: 3590.17%
[単勝] 的中率: 81.65%
[三連] 的中率: 34.84%
[馬単] 的中率: 58.25%
今後の予定
実際に運用してみて、本当に8割も当たるのか確認する。
また、別の手法を試したり、説明変数を見直してより高い精度を目指す。