【DataRobot】AIに有馬記念を当ててもらおう【競馬】

#はじめに
この記事は[機械学習の自動化プラットフォームDataRobotを使って楽しむ冬のイベント予測チャレンジ 【PR】 DataRobot Advent Calendar 2020](https://qiita.com/advent-calendar/2020/datarobot)のものです。

もう今年もあと少しで終わってしまいますね。
ところで年末の大イベントとはなんでしょうか？
クリスマス？大晦日？  
いいえ。**第65回 有馬記念（G1）**です。  
ということで今回はDataRobotを使って学習モデルを製作し、今年の有馬記念と予想をしてみたいと思います。
正直、機械学習で競馬予想なんてありきたり過ぎますが、最後まで読んでいただけると幸いです。

## DataRobotとは？
DataRobotとはDataRobot社が提供しているAutoML(Automated Machine Learning)のことです。
前処理、モデル選択・設計や最適化など機械学習において~~めんどう~~必要なことを全て自動で行ってくれます。(凄すぎる)
つまりデータセットさえ用意すれば全くコードを書かずに、予測モデルの作成ができちゃいます。

今回は[DataRobotフリートライアル](https://www.datarobot.com/jp/trial/)を使って予測に挑戦してみます。

##有馬記念とは？
有馬記念とは毎年12月下旬に中山競馬場で行われる芝2500mのレースのことです。
またこのレースではファン投票によって一部出走馬が決められるなど、とても面白いものとなっています。

#方法
1. 過去データを集める。
2. DataRobotでモデルを作る。
3. 作成したモデルの評価

この流れでいきたいと思います。

##データ集め
今回は過去に中山競馬場で行われた芝2500mのレースの情報を集めます。いろいろと調べてみると、同競馬場で行われる全ての距離、条件(芝・ダート)についてのデータを集めて予測されている方が多かったのですが、目的のレースが今回は1つなのであえて条件を絞ってみました。
データを集める方法と特徴量の選定は、以下を参考にしました。

* [クローリング&スクレイピング 競馬情報抜き出してみた](https://qiita.com/penguinz222/items/6a30d026ede2e822e245)
* [機械学習で競馬の回収率100%超えを達成した話](https://qiita.com/Mshimia/items/6c54d82b3792925b8199)

この条件では1986~2020年の間におよそ400レース行われており、約4000頭分のデータが集まりました。
データ量としてはかなり物足りないですが、このまま進めます。
また集めた項目は以下の通りです。

| 特徴量 | 説明 | 特徴量 | 説明 |
|:-:|:-:|:-:|:-:|
| year  | 年  |  male_blood | 父  |
| kai  |  回 | male_blood_1  |  父の父 |
|  day |  日 |  male_blood_2 |  母の父 |
|  num |  レース番号 | female_blood  | 母  |
| weather  |  天気 | female_blood  |  父の母 |
| condition  | 馬場状態  |  female_blood | 母の母  |
|  sum_num | 出走頭数  | l_days  | 前走からの経過日数  |
|  horse_num | 馬番  |  p_place |  前走の場所 |
|  horse_name | 馬名  |  p_weather | 前走の天気  |
|  sex | 性別  |  p_num | 前走のレース番号  |
|  age | 年齢  |  p_sum_num | 前走の出走頭数  |
| carry_weight  |  斤量 | p_horse_num  | 前走の馬番  |
|  jockey | 騎手  | p_rank  |  前走の順位 |
| rank  |  着順 | p_field  | 前走の馬場状態  |
|  horse_weight |  馬体重 |  p_dist | 前走の距離  |
|  weight_change | 馬体重の変化量  | p_time  | 前走の走破タイム  |
|   | | p_last3F  | 前走の上り3ハロンのタイム  |
|   | | p_weight  | 前走の斤量  |
|   | | p_race_name  | 前走のレースグレード  |

前走は対象レースから過去3レース分集めました。
また競馬予測においてよく使用されるスピード指数も計算し、データ項目に追加しました。

##DataRobotでモデル作成
###ターゲット選択
今回は対象が複勝圏内(1~3着)かどうかの分類問題とします。

###実行
![実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/9daf53e9-0357-23e3-e7a6-0078beb424ff.png)
ターゲットをrankに設定し、開始ボタンを押します。ちなみに複勝圏内ならばTrue、違えばFalseです。
あとはオートパイロットで様々な手法で学習モデルを30分で作成してくれました。交差検証もちゃんとしてくれるのでめっちゃ便利ですね。

##作成したモデル
最もAUCが高かったKernel SVM Classifierを採用しました。
結果は以下に示していきます。
![指数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/a6ce3ace-6891-4355-423b-daf4d081b772.png)
まず一般的な評価指数の一覧です。
複勝圏内予測スコアは0~1で決められ、これは単純に複勝圏内に入るであろう確率と言えます。そしてどれくらいの確率以上あれば、複勝圏内に入るとしてもよいかの閾値は、F1スコアが最大化されるように決定されており、今回の場合は0.303でした。

そしてこれらの指数のなかで最も重要であるといえるのは陽性的中率です。陽性的中率とは陽性(=複勝圏内に入る)と予想された馬が本当に複勝圏内に入る確率です。競馬は外れる馬を当ててもしょうがないので、ここのスコアを重視します。
結果は44.3%となりました。ちなみに完全ランダムに予想した場合、出走頭数が16頭であるとすると陽性的中率は18.75%です。
![スクリーンショット 2020-12-18 002729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/fe7d4740-9a0c-6a86-53f2-3d825923b8f2.png)
次に混同行列です。上段が実際には複勝圏外だった馬の数、下段が実際に複勝圏内だった馬の数を表しています。また左列が複勝圏外であると予測した馬の数、右列が複勝圏内であると予測した馬の数を表しています。
![Nystroem Kernel SVM Classifier、(0.303 Threshold) (密度) 予測分布.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/1cc5f300-7537-9a10-c26d-7e744a129f5c.png)
予測分布も載せておきます。複勝圏外の馬(紫色)は割と綺麗に左側によっていますが、複勝圏内(緑色)の馬が幅広く分布してしまっているので予測精度についてはなんともいえない結果となりました。

![特徴量.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/de17fd40-9db9-48da-7357-694585a604b9.png)
最後に特徴量の重要度を示しておきます。前走の順位がかなり重要視されていることが分かります。また馬齢やジョッキー、前走からの経過日数もそこそこ重要みたいですね。強い馬はローテーションを考えられているので、そこで経過日数が重要となっているのかもしれません。

また個人的に興味深かったのは血統についてです。従来より競走馬の血統では父が重要視されていることが多い気がしているのですが、今回の検証でも斤量と同じくらい、父の血統が重視されていることが分かりました。ある研究では父系より母系の方が遺伝的な影響は大きいとされているようですが...どうなんですかね(参考：https://www.jairs.jp/contents/w_news/2015/8/5.html )

#2020年 有馬記念の予想
では一番重要な、モデルから導かれた今年の有馬記念の予想を載せます。
なお各馬の馬番などは現時点では不明なので

- 全馬4枠8番とする
- 天気は晴、馬場状態は良とする
- 馬体重は前走の体重を使う
- 馬体重の変化は0とする
- 出走頭数は16頭であるとする
- 今のところ出走可能性のある23頭について予測する
- まだ騎手が決まっていない馬に関しては、とりあえず藤岡佑介騎手に乗ってもらうこととする

の条件とさせていただきます。

###予想結果
![有馬記念2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/c49fac72-889a-5b7c-f2a6-4b0fb7f95c0c.png)
去年の有馬記念3着馬であるワールドプレミアが1番となりました。前走は約1年ぶりのレース(ジャパンC)で6着でしたが、巻き返してくれるのでしょうか？4歳牡馬はあまり活躍できていないので頑張ってほしいです。また閾値は0.303だったので該当馬はワールドプレミアだけということになります。(オーソリティも入れてもいい気はしますが)

馬番が発表されたら、そのデータを使って再度予測したいと思います！
### 2020/12/24　追記
枠順が確定したので、その結果を用いて予測しました。
また前回の段階では分かっていなかったジョッキーなどのデータについても決定していたので加えました。
![スクリーンショット 2020-12-24 190239.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/f17952c3-1294-6f96-f628-f49678e0084f.png)
結果としては大きくは変わりませんでしたが、全体的に数値が下がり、一部順番が入れ替わりました。

### 2020/12/25 追記
発走1時間前ですが、馬体重が発表されたのでもう一度予測しなおしました。
![スクリーンショット 2020-12-27 143122.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379446/15ed186e-2ca6-82b8-86cc-e311f0e5775b.png)
結果として、オーソリティがかなりスコアを伸ばしました。正直、馬体重の変化がここまで効いてくるとは思いませんでした。

#最後に
めちゃくちゃお手軽に学習モデルを作れたのでびっくりしました。結果の表示も視覚的にとてもわかりやすくDataRobotスゲェ...
機械学習について知識がほぼないので、検証や考察ができていませんがそこは大目に見てください🥺
とりあえず、ワールドプレミアとオーソリティの複勝は買っておきたいと思います。

**当たってくれ！！！**