AlphaImpact 会社概要 事業内容 開発情報 お問い合わせ

第6回 データの前処理だけで競馬は強くなる

2017/02/16更新

NUKUI

第6回目の理論記事では機械学習におけるデータの前処理の重要性を'16 フェブラリーSの予測を交えて説明します。

入力データの大きさを整える

前回の理論記事で特徴量には数値データとカテゴリデータがあることをお話しました。 カテゴリデータはダミー変数に変換してしまえば0か1のいずれかの値となりますが、数値データはコース距離や本賞金といった大きなスケールの値を取る場合があります。 そのようなデータの範囲が大きく異なる特徴量が特徴ベクトルに含まれると、パラメータの更新がうまくいかなかったり、値の大きな特徴量だけが結果に寄与するような予測器ができてしまいます。 中には決定木などスケールに影響されないアルゴリズムもありますが、多くの機械学習のアルゴリズムではスケールを適切に調整した方が良い結果となります。

よく使われるスケーリング手法は*正規化(normalization)標準化(standarization)*です。 正規化は文脈によって意味が異なりますが、多くの場面においては特徴量のとる範囲を[0, 1]に変換することを指します。 正規化はあらかじめ特徴量のとりうる値の範囲が決められているときに有効です。 以下の線形変換により正規化がされます。

normalization

一方標準化では特徴量の分布を平均0、分散1になるように変換します。 標準化は正規化のように上下限を設定していないため、外れ値が存在する場合でもうまくはたらき、実用性が高いスケーリング手法です。 変換式は以下のように書けます。

standarization

k近傍法で勝ち馬予測をする

機械学習アルゴリズムで最もシンプルな手法の1つk近傍法(k-nearest neighbors algorithm, k-NN)1による勝ち馬予測を例にスケーリングの有効性を示す実験を行います。 ここでは勝ち馬を馬券内に絡んだ馬と定義します。

k-NNはクラスラベル(勝ち馬 or 負け馬)がわかっている学習サンプルと勝ち馬予測をしたいサンプルとの特徴ベクトルの距離を測り、k番目までの近くにあるサンプルで多数決をとり、サンプル数が多い方のクラスラベルを割り当てる単純なアルゴリズムです。 以下の図における真ん中のサンプルが勝ち馬(赤)か負け馬(青)かを予測する例を考えます。k=5とした場合、真ん中のサンプルの近傍5つのうち勝ち馬3頭>負け馬2頭となるので、真ん中の馬は勝ち馬だと予測できます。 勝ち馬になる確率を計算するときは、以下の例では3/5=0.6となります。 今回はk=100で実験しました2

knn

入力データ

今回予測する対象の条件は、今週末に行われるフェブラリーSに合わせて東京ダート1600mの古馬戦に設定します。 2015/1/1〜2015/12/31に行われた該当レース(48レース)を学習データ、2016/1/1〜2016/12/31(48レース)を評価用データとしました。 また正例(勝ち馬)と負例の偏りが大きいと上手く予測ができないため学習データの負例を間引いて正例:負例=1:1になるように調整しました3

特徴量は以下の8種類を使いました。

特徴量名 カラム名 備考
馬齢 age
斤量 burden kg
脚質 run_style 逃げ=1, 先行=2, 差し=3, 追込=4
連対率 win2_ratio 馬の通算連対率
前走距離 prev_length メートル
前走タイム差 prev_time_diff 1着との秒差
前走後3Fタイム prev_last3f
前走本賞金 prev_prize
単勝オッズ win_odds 確定オッズ
馬体重 horse_weight kg

実際の入力データの中身は以下のように大小様々なスケールのデータが含まれています。

index   age  burden  run_style  win2_ratio  prev_length  prev_time_diff  prev_last3f  prev_prize    win_odds  horse_weight
0         4    57.0          4    0.100000         1800             0.1         39.3     1900000         2.7         484.0
1         4    57.0          3    0.100000         1600             0.7         35.6           0        26.2         558.0
2         5    57.0          2    0.066667         1600             0.5         36.5           0        17.2         494.0
3         4    55.0          2    0.153846         1800             1.4         40.9      750000        92.1         462.0
4         4    57.0          2    0.071429         1800             1.3         40.2           0        46.2         498.0

この入力データに対して標準化を適用すると以下のように特徴量ごとのスケールの異なりが解消されます。

index        age    burden  run_style  win2_ratio  prev_length  prev_time_diff  prev_last3f  prev_prize  win_odds  horse_weight
0      -0.350651  0.887719   1.344970   -1.069946     0.680274       -0.904699     0.346090   -0.013186 -0.707175     -0.010956
1      -0.350651  0.887719   0.248618   -1.069946    -0.189830       -0.345607    -0.204037   -0.370253 -0.435019      2.733302
2       0.510744  0.887719  -0.847734   -1.273420    -0.189830       -0.531971    -0.070222   -0.370253 -0.539249      0.359890
3      -0.350651 -0.398158  -0.847734   -0.741257     0.680274        0.306667     0.583982   -0.229306  0.328178     -0.826816
4      -0.350651  0.887719  -0.847734   -1.244352     0.680274        0.213485     0.479904   -0.370253 -0.203396      0.508228

評価

2016/1/1~2016/12/31(48レース)の各レースにおける勝利確率Top-1の単複的中率と回収率を示します。

  単勝的中率 単勝回収率 複勝的中率 複勝回収率
k-NN(標準化なし) 6.25% 13.5% 29.1% 46.0%
k-NN(標準化あり) 8.33% 33.1% 39.5% 90.8 %

標準化をすることで的中率と回収率が向上しました。 回収率は100%超えていませんが、複勝回収率90.8%という数字は控除率が85%であることを考えると有益な予測が出力されていると思われます。 単勝の成績があまり良くないのは、解いている問題が複勝圏内に来たか否かの2値分類であるためで、「1着になりやすい馬」と「3着までに入りやすい馬」の特徴が異なることを示唆しています。

続いて'16 フェブラリーSのレース結果とk-NNによる予測結果を示します。

▼ 着順と人気

着順 馬番 馬名 人気
1 14 モーニン 2
2 7 ノンコノユメ 1
3 4 アスカノロマン 7
4 5 ベストウォーリア 3
5 6 ロワジャルダン 6
6 13 タガノトネール 9
7 3 コパノリッキー 4
8 9 モンドクラッセ 10
9 16 ローマンレジェンド 13
10 2 ホワイトフーガ 5
11 10 グレープブランデー 11
12 11 スーサンジョイ 8
13 15 サノイチ 15
14 12 マルカフリート 16
15 8 コーリンベリー 12
16 1 パッションダンス 14

▼ 標準化なしk-NN

順位 馬番 馬名 予測確率
1 10 グレープブランデー 0.67
2 13 タガノトネール 0.67
3 7 ノンコノユメ 0.64
4 11 スーサンジョイ 0.64
5 14 モーニン 0.64
6 15 サノイチ 0.64
7 4 アスカノロマン 0.63
8 6 ロワジャルダン 0.63
9 9 モンドクラッセ 0.63
10 3 コパノリッキー 0.43
11 1 パッションダンス 0.41
12 2 ホワイトフーガ 0.4
13 8 コーリンベリー 0.4
14 16 ローマンレジェンド 0.39
15 5 ベストウォーリア 0.31
16 12 マルカフリート 0.2

▼ 標準化ありk-NN

順位 馬番 馬名 予測確率
1 4 アスカノロマン 0.71
2 14 モーニン 0.7
3 11 スーサンジョイ 0.67
4 7 ノンコノユメ 0.63
5 2 ホワイトフーガ 0.62
6 9 モンドクラッセ 0.62
7 5 ベストウォーリア 0.6
8 6 ロワジャルダン 0.57
9 3 コパノリッキー 0.55
10 13 タガノトネール 0.54
11 8 コーリンベリー 0.49
12 10 グレープブランデー 0.45
13 15 サノイチ 0.34
14 16 ローマンレジェンド 0.34
15 12 マルカフリート 0.28
16 1 パッションダンス 0.24

標準化なしの予測では上位が⑬タガノトネールや⑩グレープブランデーなど的外れな予測をしていましたが、入力データを標準化するだけで馬券内の3頭が上位4位までに入るという驚くべき結果に。 ④アスカノロマンは7人気ですから、単勝オッズだけを見ているというわけではなく、学習データの中にアスカノロマンと近い特徴ベクトルを持った勝ち馬が存在したのでしょう。 ちなみにモーニンとアスカノロマンのワイドは1690円の配当でした。

おわりに

k-NNのようなシンプルなアルゴリズムでも、適切にデータの前処理を行えば十分に使えるレベルの予測器が作れます。 逆に適切なデータ処理をしなければ、高性能GPUを積んでディープラーニングをぶん回したとしてもk-NNにすら勝てないショボい予測器ができるだけで、時間とお金の無駄となってしまうでしょう。 発展的な機械学習アルゴリズムを試すのは、データを完璧に整えてからでも遅くはありません。

次回は予測モデルの種類とその評価方法ついて書いていく予定です。


  1. k-nearest neighbors algorithm - Wikipedia ↩︎

  2. 本来であれば最適なkの値を探索しますが、今回はk=100で決め打ちして実験しました。 ↩︎

  3. サンプリング方法は負例をランダムにサンプリング ↩︎