機械学習 其の007 ~馬毎のデータ分析~
前回のエントリでは1200mレースの着順事のタイムレンジを分析することで、1着の馬のタイム期待値を求めようとしてみましたが、レンジ幅が大きすぎていまいちな結果となったので、今回は馬のデータについて分析してみようと思います。
データは以下のような感じです。 今回は、開催日毎のタイムで分析をしてみたいと思います。
データの元ネタは例によってnankankeiba.comから取得させて頂きました。
データを見ると開催日は第1カラム、距離は第5カラム、タイムは第10カラム目となっています。
馬の戦績データ
15/8/13 大井 3 C3(六)(七) 1200 曇/稍重 7 1 2/12 1:14.3 0.5 37.5 1-1 446 西啓太 54.0 橋本馬 240,000 15/7/28 大井 3 C3(八)(九)(十) 1200 晴/良 12 1 2/14 1:15.0 0.2 39.1 3-3 446 西啓太 54.0 橋本馬 240,000 15/6/26 大井 1 C2(十五)C3(一) 1200 曇/良 14 9 4/14 1:14.7 0.2 38.3 3-3 447 西啓太 55.0 橋本馬 120,000 15/6/4 大井 6 C2(十六)C3(一) 1200 晴/稍重 9 10 8/10 1:15.0 1.0 38.0 3-3 443 西啓太 55.0 橋本馬 0 15/1/23 大井 7 C2(十五)(十六)(十七) 1200 晴/不良 3 9 10/16 1:16.4 2.9 40.7 8-9 447 中村尚 56.0 橋本馬 0 14/12/28 大井 3 3歳190万 1200 晴/良 10 8 3/14 1:15.3 0.5 38.4 4-4 450 西啓太 53.0 橋本馬 180,000 14/11/26 大井☆ 4 3歳150万 1200 雨/不良 4 6 1/15 1:16.1 0.2 40.2 3-1 451 西啓太 53.0 橋本馬 1,000,000 14/9/29 大井 3 3歳115万 1200 晴/良 7 2 3/14 1:15.4 0.4 38.2 6-5 446 西啓太 53.0 橋本馬 198,000 14/8/25 大井 2 3歳95万 1200 曇/良 1 2 5/14 1:16.4 0.8 38.4 9-8 437 西啓太 53.0 橋本馬 110,000 14/8/12 大井 3 3歳70万 1200 雨/稍重 6 2 5/12 1:15.7 0.7 38.7 7-8 437 西啓太 53.0 橋本馬 110,000 14/7/27 大井 2 3歳55万 1200 曇/良 11 10 3/14 1:16.0 0.7 38.9 7-7 431 西啓太 53.0 橋本馬 198,000 14/2/25 大井 3 3歳35万 1200 晴/良 8 7 3/14 1:17.5 2.2 39.9 8-7 436 千田洋 56.0 橋本馬 240,000 14/2/3 大井 4 3歳25万 1500 晴/良 7 7 9/12 1:42.4 1.8 42.9 8-7-8 440 千田洋 56.0 橋本馬 0 14/1/20 大井 4 3歳25万 1200 晴/良 4 7 6/10 1:18.5 1.2 40.7 8-8 443 千田洋 56.0 橋本馬 0
分析につかったプログラム
# -*- coding: utf-8 -*- import scipy as sp import numpy as np import matplotlib.pyplot as plt import datetime from matplotlib.font_manager import FontProperties # 馬データの読み込み horsedata = sp.genfromtxt(r"toprising.tsv", delimiter="\t", dtype=[ ('日付','U10'), # 0:日付 ('開催地','U10'), # 1:開催地 ('レース','i2'), # 2:レース ('レース名','U50'), # 3:レース名 ('距離','i4'), # 4:距離 ('天候','U10'), # 5:天候 ('馬番','i2'), # 6:馬番 ('人気','i3'), # 7:人気 ('着順','U10'), # 8:着順 ('タイム','U10'), # 9:タイム ('差/事故', 'i4'), # 10:差/事故 ('上3F','i4'), # 11:上3F ('通過順','U10'), # 12:通過順 ('体重','i4'), # 13:体重 ('騎手','U20'), # 14:騎手 ('負担重量','i4'), # 15:負担重量 ('調教師','U20'), # 16:調教師 ('獲得賞金(円)','U10') # 17:獲得賞金 ], converters={ 1 : lambda s: s.decode('utf8'), # 開催地 3 : lambda s: s.decode('utf8'), # レース名 5 : lambda s: s.decode('utf8'), # 天候 14 : lambda s: s.decode('utf8'), # 騎手 16: lambda s: s.decode('utf8'), # 調教師 }) horsedata = np.array(horsedata.tolist(), dtype = object) x = horsedata[:,0] # 開催日の配列を生成 y = horsedata[:,9] # タイムの配列を作成 z = horsedata[:,4] # 距離の配列を生成 # 1200m以外のレースを除外 z = np.array([idx for idx, i in enumerate(z) if i == 1200 ]) x = x[z] y = y[z] # 日付を数値変換 for idx, d in enumerate(x): yyyy = "20" + d.split('/')[0] mm = d.split('/')[1] dd = d.split('/')[2] if len(mm) == 1: mm = "0" + mm if len(dd) == 1: dd = "0" + dd x[idx] = datetime.datetime.strptime(yyyy + mm + dd, '%Y%m%d') # タイムを数値変換 for idx, time in enumerate(y): y[idx] = np.float32(time.split(":")[0])*60+np.float32(time.split(":")[1]) y = y.astype('float') # 描画 xticks = [datetime.datetime(2010,1,1), datetime.datetime(2010,4,1), datetime.datetime(2010,7,1), datetime.datetime(2010,10,1), datetime.datetime(2011,1,1), datetime.datetime(2011,4,1), datetime.datetime(2011,7,1), datetime.datetime(2011,10,1), datetime.datetime(2012,1,1), datetime.datetime(2012,4,1), datetime.datetime(2012,7,1), datetime.datetime(2012,10,1), datetime.datetime(2013,1,1), datetime.datetime(2013,4,1), datetime.datetime(2013,7,1), datetime.datetime(2013,10,1), datetime.datetime(2014,1,1), datetime.datetime(2014,4,1), datetime.datetime(2014,7,1), datetime.datetime(2014,10,1), datetime.datetime(2015,1,1), datetime.datetime(2015,4,1), datetime.datetime(2015,7,1), datetime.datetime(2015,10,1) ] fp = FontProperties(fname=r'C:\WINDOWS\Fonts\msgothic.ttc', size=14) plt.scatter(x, y) plt.title(u"開催日別タイム", fontproperties=fp) plt.xlabel(u"開催日", fontproperties=fp) plt.ylabel(u"タイム", fontproperties=fp) plt.xticks(xticks, [str(d.year) + "/" + str(d.month) for d in xticks], fontproperties=fp) # 72ヵ月のレンジでx軸を作成 plt.yticks([i for i in range(70, 100)], [u"%i秒"%i for i in range(70, 100)], fontproperties=fp) # 70秒から100秒のレンジでy軸を作成 plt.autoscale(tight=True) plt.grid() plt.show()
プログラムの実行結果は以下のとおりです。レースを重ねるごとにタイムが伸びているのがわかります。1200mのレースであれば、前回のエントリからも分かるように73~74秒代のタイムを出せれば十分に1,2着を狙えると考えても良いと思います。
ちなみに、今回のデータは、今日(20150916の大井競馬場の第2レースに出走するトップライジングという馬です。
次回は分析に使ったプログラムの説明と、このレース結果についての分析を行おうと思います。