How many files(0-15)

競馬の予想システムで一儲を企むおっさんのヨコシマな横顔

機械学習 其の005 ~前処理とデータ表示2~

前回のエントリで、1レース分の着順事のタイムをプロットしてみました。今回はこのデータを更に増やしてみます。
例によってnankankeiba.com/から大井競馬場の8/24~8/28の1200mのレースに絞ってデータを集め表示してみました。

基本的には前回のエントリと同じプログラムでよいのですが、データの一部に落馬等で記録が残っていないデータがあります。このようなデータは着順やタイムに"-"が設定されているためデータ処理の前に除去しておく必要があります。具体的には以下のように配列生成と同時にループで特定条件の要素を除外しています。この辺はpythonだと、とても柔軟に記述できて素晴らしいと思います。


記録なしのデータ除去部分

x = racedata[:,0]     # 着順の配列を作成
y = racedata[:,10]    # タイムの配列を作成

# 落馬等の原因で着順、タイムの記録が存在しないデータを除去
x = np.array([i for i in x if i != -1 ])
y = np.array([i for i in y if i != "-" ])


実行結果
f:id:taka23kz:20150912193109p:plain


結果としては、いまいちですね。72秒から73秒前後だとほぼ1~3着に入れそうだということと、77秒代でも1着になるケースもあるということ程度しか分かりません。このままでは全然役に立ちそうにないので、もっと別の評価軸を設定する必要があるのだろうと想像できます。


まぁ、ダメ元で直線で近似(いわゆる最小二乗法)してみます。
前回のサンプルだとベクトルyが文字となっていたので、astypeでfloatのベクトルに変換し、polyfitでモデル関数のパラメータであるfp1を取得します。
次にfp1からpoly1d(1次元なので1d)を使ってモデル(近似)関数f1を作成します。


作成したfp1とf1は次のようになります。fp1が「[ 0.17563257 74.85191064]」でf1(モデル関数)が「0.1756 x + 74.85」です。 fp1からf1が作成されていることがわかると思います。


fp1とf1の内容

[  0.17563257  74.85191064]
 
0.1756 x + 74.85


次に作成したf1を描画します。サンプルでは、f1を描画するのにplot関数を使用しています。plot関数の引数は点を描画する座標をx,yでそれぞれ設定します。今回はfxとf1(fx)を与えています。fxは1~16の範囲を16分割した配列をlinspaceで作成したもので今回の場合であれば、着順のリストとなっています。実際fxの内容を表示すると以下のようになっています。


fxの内容

[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.  14.  15.  16.]


f1(fx)は1着から16着までのタイムを返却する関数となっており、これらで表現される座標にプロットしています。plotの第3引数はプロットする点(あるいは線)に関するプロパティです。サンプルでは「linewidth=4」としていますが、「"ro"」(赤い丸)等を指定すると表示が変わります。


近似関数の描画

# タイムを数値変換
for idx, time in enumerate(y):
    y[idx] = np.float32(time.split(":")[0])*60+np.float32(time.split(":")[1])

y = y.astype('float')


fp1 = sp.polyfit(x, y, 1)       # fp1:モデル関数についてのモデルパラメータを取得
f1 = sp.poly1d(fp1)             # モデルパラメータからモデル関数を作成
fx = sp.linspace(1, 16, 16)    # fxプロット用に1着から16着の範囲で配列を作成(第3パラメータの16はfxのベクトルの要素数)

fp = FontProperties(fname=r'C:\WINDOWS\Fonts\msgothic.ttc', size=14)
plt.scatter(x, y)
plt.plot(fx, f1(fx), linewidth=4)
plt.title(u"着順別タイム", fontproperties=fp)
plt.xlabel(u"着順", fontproperties=fp)
plt.ylabel(u"タイム", fontproperties=fp)
plt.xticks([i for i in range(1, 17)], [u"%i着"%i for i in range(1, 17)], fontproperties=fp)   # 1着から16着のレンジでx軸を作成
plt.yticks([i for i in range(70, 90)], [u"%i秒"%i for i in range(70, 90)], fontproperties=fp) # 70秒から90秒のレンジでy軸を作成
plt.autoscale(tight=True)
plt.grid()
plt.show()


実行結果
f:id:taka23kz:20150913000351p:plain


やはりというか、役に立ちそうにないので、次回は別の評価軸に関する検討をしてみたいと思います。