見出し画像

文系事務職がゼロから競馬予想プログラムを作る話~初学者が勉強1ヵ月で日本ダービーを自作AIで予想した編~

前回までのあらすじ

 プログラミング未経験・文系事務職である私はオンライン教材と本による独学で競馬予想プログラムの作成に挑んでいた。ひたすらに勉強に励み、いよいよ目標の日本ダービー当日の予想に挑もうとしていた。
 (詳細は↓のリンクより)

予想の仕方

 さて、「機械学習で予想する」と一言でいってもどういうことなのかわからない方もいらっしゃると思われます。今回の記事を読みやすくするためにも、機械学習について簡単に触れておきます。

 機械学習とは、人工知能のプログラム自身が学習する仕組みである。
 そもそも学習とは何か。どうなれば学習したといえるのか。学習の根幹をなすのは「分ける」という処理である。ある事象について判断する。それが何かを認識する。うまく「分ける」ことができれば、ものごとを理解することもできるし、判断して行動することもできる。「分ける」作業は、すなわち「イエスかノーで答える問題」である。
 (中略)
 人間にとっての「認識」や「判断」は、基本的に「イエス・ノー問題」としてとらえることができる。この「イエス・ノー問題」の精度、正解率を上げることが、学習することである。
 機械学習は、コンピュータが大量のデータを処理しながら、この「分け方」を自動的に習得する。いったん「分け方」を習得すれば、それを使って未知のデータを分けることができる。
        松尾 豊『人工知能は人間を超えるか』P116-117より引用
                        (太字は自分で追加)

 少し追記します。機械学習には更に「教師あり学習」と「教師なし学習」に分けられます。私が作成したプログラムは「教師あり学習」に分類されます。「教師あり学習」はまず「入力」と「正しい出力」がセットになった訓練データをあらかじめプログラムに学習させておきます。そして別に用意した「入力」と「正しい出力」のセットでどれだけ正しく学習しているかをテストするものです。
 競馬予想プログラムでは、過去のレースデータを訓練データ及びテストデータとして使用します。そしてその学習の結果を用いて実際に結果が判明していないレースの結果を予想します。
 詳細については先程触れた松尾先生の本や前回紹介したオライリーの本を参照願います。

実際の予想①~データ読み込み・加工~

 では、実際に予想した過程を見ていきましょう。

 まずは過去のレース結果を読み込みます。
 今回の予想で使ったのは、10年分の東京2400mのレース結果です。
 これをエクセルで関数を使って加工し、csv変換して取り込んでいました。

 使っていた特徴量(機械学習の入力に使う変数のことで、この値が学習の結果を表すものです。)は例えば次のようなものでした。

 ・単勝オッズ
 ・レース間隔
 ・脚質
 ・前走着順
 ・前走オッズ
 ・キャリア
  ...etc

   多くの加工はエクセルで行っていましたが、次のようにダミー変数化や欠損値の補完はpythonのプログラムで行っていました。

#データ読み込み
data = pd.read_csv("plate_dabie.csv",encoding='cp932')

#ダミー変数化
data2=pd.get_dummies(data,columns=["脚質","枠番","性別"])
data= pd.DataFrame(data2)

#欠損値補完
data.isnull().sum()

from sklearn.preprocessing import Imputer 
imr = Imputer(missing_values=np.nan, strategy='median')
imr = imr.fit(data.values)
imputed_data = imr.transform(data.values)

data2 = pd.DataFrame(imputed_data)

実際の予想②~学習とその結果~

 次にこのデータを訓練データとテストデータに分けます。

from sklearn.model_selection import train_test_split

X, y = data2.iloc[:, 1:].values, data2.iloc[:, 0].values

X_train, X_test, y_train, y_test =\
   train_test_split(X, y, 
                    test_size=0.3, 
                    random_state=10, 
                    stratify=y)

 そして、パラメータを設定して、ランダムフォレストという分類方法を使って機械学習を行います。


forest = RandomForestClassifier(n_estimators=100,min_samples_leaf=4,random_state=10)
forest.fit(X_train, y_train) 

 学習したプログラムにダービーのデータを入れれば、予想完了です。
 (本当はもっと長いのですがキリがないのでこのくらいにしておきます。)
 予想結果は次のようになりました。

画像1

 分かりづらいですが、0から始まっているため、一番左の番号に1を足した数が馬番、1と書かれている列が3着以内に入る確率となります。
 とりあえず半分(0.5)を超えている番号を購入対象とすると、
 5番のコントレイルと12番のサリオスが対象となります。

レース結果

 1着 ⑤コントレイル
 2着 ⑫サリオス
 3着 ⑥ヴェルトライゼンデ

 購入対象とした馬2頭が3着以内に入りました。
 的中です!

課題

 ただし、喜べない部分があります。
 次の画像を見てください。

画像2

 これは予想に使われた特徴量を表示しているのですが、単勝オッズが大部分を占めております。
 困りました。これでは単勝オッズの高い順に買えば勝てるという当たり前の結論を述べているにすぎません。
 競馬予想で勝つためには、単勝オッズが高くても上位に入ってくる馬を見つけ出す必要があります。
 そのためにはまず単勝オッズを特徴量から外したプログラムを作成する必要があります。

 実はこの他にも課題を抱えていました。

 ・データ取集に時間がかかる
 ・データ加工に時間がかかる
 ・東京2400mしか予想できない

 この課題を解決するためにまだまだ勉強を進めるわけですが…
 次回「悪戦苦闘編」へ!







この記事が気に入ったらサポートをしてみませんか?