ラベル 競馬 の投稿を表示しています。 すべての投稿を表示
ラベル 競馬 の投稿を表示しています。 すべての投稿を表示

2014年9月4日木曜日

タイム差の連鎖で比較する方法の検証(5)

タイム差の連鎖で比較する方法の検証(4)で書いたように、今のところ、18番人気を予想するときがある。さすがにおかしいだろう、と調べてみる。2013年までの間で18番人気を予想してしまうのは、6レース。その最も最近のレースは、2012年4回阪神9日11レース。勝ったのは、17番オリービン(4番人気)で、予想した結果は10番アンノルーチェ(18番人気)である。見てみたところ、おかしな数値が出ているところはない。以下がタイム差を計算したもの。数が大きいほど、相手の馬に対して速いことを示す。なお、時間差を走破タイムで割るという調整をしているので、時間差そのままではない。そして、アンノルーチェのオリービンに対するタイム差は、-0.022085369だが、逆は、0.02186513と微妙に違う値になる。これは、その調整による差である。この値から直接のタイム差としては、オリービンのほうが速いということになる。平均値にはほとんど差がない。計算不能だった3頭を除くと、アンノルーチェより速いのは、1番クラレントと17番オリービンしかない。なぜに、これで18番人気なのか。うーん、何が問題なのか、もっと詳細を調べる必要があるな。


10 アンノルーチェ17 オリービン
1 クラレント-0.0220853690.0041351984
2 エックスダンス
3 フレールジャック-0.0015884668
4 モンストール0.0012626622-6.1875914E-4
5 ゼロス0.009481094
6 ブレイブファイト0.021263170.006194453
7 ゴールスキー0.0113776970.00542193
8 オートドラゴン0.0199577230.013366331
9 マイネルクラリティ0.018794650.012109033
10 アンノルーチェ0.02186513
11 タガノエルシコ0.0123999220.0058213435
12 ダイシンプラン0.0256952120.00988129
13 ダローネガ0.013413218-0.0023949028
14 ミキノバンジョー0.0176212840.0063157864
15 タムロスカイ0.0191193350.013514917
16 ガンダーラ0.021165427
17 オリービン-0.022085369
18 レッドデイヴィス0.0127679750.0038332231
平均0.0071950.007139

2014年9月2日火曜日

タイム差の連鎖で比較する方法の検証(4)

タイム差の連鎖で比較する方法の検証(3)で書いたバグをとった結果は、以下のようになった。今回も予想の範囲は、2001年から2013年の範囲で、80%以上データがあるレースに限っている。
的中率 23.2% 回収率 86.0%
バグってた時より、的中率も回収率もあがっている。以前にも書いたように一番人気は、以下。
的中率  32.3% 回収率 76.1%
さて、予想結果は、何番人気の馬を予想しただろうか。結果は以下。
1番人気 14545レース
2番人気 7838レース
3番人気 4752レース
4番人気 3166レース
5番人気 2231レース
6番人気 1607レース
7番人気 1047レース
8番人気 796レース
9番人気 597レース
10番人気 357レース
11番人気 252レース
12番人気 179レース
13番人気 130レース
14番人気 92レース
15番人気 66レース
16番人気 43レース
17番人気 14レース
18番人気 6レース
うーん、減ったものの、18番人気を予想するのはおかしいよなー。また、調べてみよう。

2014年9月1日月曜日

タイム差の連鎖で比較する方法の検証(3)

18番人気を勝つと予想してしまったデータがあると、タイム差の連鎖で比較する方法の検証(2)で書いた。どういうレースでそのような予想をしてしまうのか。まず、データ中で最も最近のデータを調べてみることにした。そのレースは、2013年5回京都7日目8レース。このレースで18番人気である6番マナウスを予想している。実際の結果は、17着であり、ほぼ人気どおり。詳細を調べてみると、おかしいタイム差になっているレースがあった。

6番マナウスと12番やマニンプードレとの時間差の計算のために、
まず、2013年4回京都8日目6レースで7番マナウスと8番アウトシャイン間のタイム差を計算している。このレースでは、
14着7番マナウス1.13.3
15着8番アウトシャイン1.13.3
で時間差なしである。次に、2013年2回小倉9日目12レースで2番アウトシャインと11番ノーザンソングのタイム差を比較している。
2着2番アウトシャイン1.08.4
13着11番ノーザンソング1.09.5
で時間差は-1.1である。次に、2013年4回阪神5日目7レースで6番ノーザンソングと3番ヤマニンプードレのタイム差を比較している。
あっ、ヤマニンプードレは出走取り消しになってる。

これはイレギュラーなので無視しないと駄目だ。バグであり、修正しないと行けない。

2014年8月31日日曜日

タイム差の連鎖で比較する方法の検証(2)

タイム差の連鎖で比較する方法の検証で書いたつづき。
予想がどれぐらいいいのかは、的中率と回収率で評価するしかない。しかし、オッズというのが非常によく出来ているというか、「みんなの意見」は案外正しい (角川文庫) というか、的中率が上がると回収率が下がり、的中率が下がると回収率が上がるみたいな結果になりがちだ。で、両方あげようとすると、フィルタリングをかけるのか、何らかの手段を講じないといけないだろう。

とりあえずは、この予想方法で、最も速いと予想された馬が何番人気だったのか、という結果を調べてみた。

1番人気 11856レース
2番人気  6681レース
3番人気  4298レース
4番人気  3082レース
5番人気  2290レース
6番人気  1813レース
7番人気  1384レース
8番人気  1255レース
9番人気  1032レース
10番人気  873レース
11番人気  735レース
12番人気  668レース
13番人気  561レース
14番人気  439レース
15番人気  358レース
16番人気  282レース
17番人気  67レース
18番人気  47レース

もっと、人気馬が選出されていると思っていた。いくらなんでも、この予想方法で18番人気の馬が選出されることがあるのは、少ないとはいえ、理解しがたい。もちろん、18番人気の馬が勝つ確率はある。上記のデータと同じ(2001年から2013年のレースでデータが80%以上そろっていたもの)レースで18番人気の馬は2回勝っているようだ。しかし、予想については、タイム差を使っているのだから、基本的にタイムが速い馬が選出されているはずである。人が予想する場合もタイムを見ているはずで、ある程度上位に来ないとおかしいのではないか。詳細を調べてみたい。

2014年8月30日土曜日

タイム差の連鎖で比較する方法の検証

タイム差の連鎖で比較するの考え方で書いた方法で計算をしてみた。馬の連鎖は3連鎖までとした。単純に言えば、AとBの馬の差を計算するときに、AとB直接対決した場合か、A-C(AとCが出たレースの差)-B(CとBが出たレースの差)のように、間に別の馬を1頭のみ挟んだ場合、同様にして2頭挟んだ場合を計算する。Aの強さは、A-Bのタイム差(複数ある場合は平均)、A-Cのタイム差、...、と計算したタイム差を平均したものとする。データがそろわないものは予想から外さないと行けないので、80%以上出走馬のタイム差が出た場合のみにした。予想は2001年から2013年の13年分。で、結果は、以下。

的中率 19.7% 回収率 83.1%

うーむ、なんと悪いことよ。ところで、同じレースの1番人気の的中率と回収率は、以下。

的中率 32.3% 回収率 76.1%

回収率は1番人気よりましだが、的中率はかなり悪い。だいたい予想アプリを作るとこういう傾向になる。

2014年8月24日日曜日

タイム差の連鎖で比較するの考え方

タイム差の連鎖で比較するで、書いたようにタイム差を使った予想アプリを作成する。
考え方は単純だ。たとえば、2014年の宝塚記念を考えてみる。1着 ジャスタウェイはゴールドシップだが、メイショウマンボを除いて、他の馬とは過去に一緒のレースに出たことがある。なので、それから、タイム差が求められる。たとえば、2着 カレンミロティックとのタイム差は、
有馬記念(2013年)
3着 ゴールドシップ 2.33.8
6着 カレンミロティック2.34.3
をもとに、0.5秒差と算出できる。しかし、直接対決をしていない場合であっても、他の馬経由で算出できる。
ヴィクトリアマイル(2014年)
1着 ヴィルシーナ 1.32.3
2着 メイショウマンボ 1.32.4
ジャパンカップ(2013年)
7着 ヴィルシーナ 2.26.3
15着 ゴールドシップ 2.27.5
つまり、ゴールドシップとヴィルシーナのタイム差は-1.2秒差、ヴィルシーナとメイショウマンボのタイム差は0.1秒差、で合わせて、-1.1秒差というのが他の馬経由でのタイム差である。このタイム差は宝塚記念で実際には勝ったゴールドシップのほうが遅いということだが、たまたま大負けしたジャパンカップが算出用のレースになったのだからしかたない。このようにある馬経由で算出できるタイム差はたくさんあるはずで、それらを平均すれば、それなりに正しいタイム差が出せるのはないかというのが、考え方。
いくつも馬を連鎖すれば、誤差が蓄積されているだろうし、その組み合わせを算出するために計算量が大きくなる時間がかかるだろうから、ある程度連鎖の数はしぼるのがいいのだろう。そして、タイム差は距離によって重みが違うだろうから、単純に-1.2+0.1=-1.1ではなく、-1.2/(2.27.5秒) + 0.1/(1.32.3秒)ように走破タイムで重みを変えることにする。

2014年8月11日月曜日

タイム差の連鎖で比較する

スピード指数は前の記事で書いたように難しい。そこで違う方法を考えてみる。

競馬新聞から競馬を予想するとき、過去のレース結果からその馬の強さを予想する。過去のレースの格や順位、タイムなどいろいろな情報を使う。スピード指数はその中でもタイムに注目して、そのタイムがレースごとの馬場の状態や展開によって差が出ることから、その調整を入れる。でも、その調整という部分が技術の必要な部分であり、予想ソフトなりの特徴になってくる。

しかし、調整というのは結局のところ、馬の強さに合わせることであり、遅いはずの馬のタイムは遅くして、速いはずの馬のタイムは速くするということになる。それにより、そのレースに出る馬の過去のタイムを比較しやすくする。しかし、そもそも過去のタイムを比較しやすくするためであれば、調整したタイムではなく、直接的に比較すればいいのではないか。

たとえば、Aという馬とBという馬があって、前走でも、AとBが直接対決していれば、そのままのタイム差(T(A)-T(B))を使えばいいし、直接対決していなくても、AとC、BとCが対決しているレースがあれば、AとBのタイム差は(T(A)-T(C))+(T(C)-T(B))を使えばいいのではないか。おそらくこのように他の馬を介して計算するタイム差はいくつもあるだろうが、それらを平均すればいい。このタイム差の計算方法は、いくつの馬を介せば、あるレースの全頭の時間差を出せるのかが気になるところではある。しかし、同じクラスの馬は、他の馬を1頭か2頭介せばつながるのではないか。一方で、クラスが上がったばかりの馬については、つながりにくくなる可能性はある。しかし、他にもよく似た時期に同じようにクラスを上がった馬もあるはずで、それほど気にする必要はないかもしれない。それに、クラスの壁と言われるタイムだけではわからない差をこの方法だと見ることができるかもしれない。また、芝もしくはダートが初挑戦のような馬もつながりにくいだろう。これは、そもそも予想が難しい部分でこの方法に限らない問題であり、それほど気にする必要はないだろう。

2014年8月10日日曜日

スピード指数の難しさ

スピード指数を出すには、場所と距離ごとの標準タイムが必要だ。しかし、距離による時間差、距離による時間差(2)などで書いてきたが、500万以下、1000万以下クラスで同じ距離のレースが何度も行われているわけではないし、雨が降ると一気に走破タイムが変わる。それに、この記事に書いたようにオープンしかないようなレースもある。スピード指数系の予想ソフトを作る人は、ここをどのように適切にするのか、それがポイントになるだろう。逆に言えば、ここに恣意的な操作を施すことによって、それなりの結果を得られるようにすることもできると考えられる。また、開催日ごとの馬場の差を計算に入れるための馬場指数についても同じようなことが言える。馬場指数は、その日に行われたレースのタムから決めることになるだろうが、結局のところ、馬場の状態だけでなく、ペースなどいろいろな要因から変わってくるため、調整するしかない。ここも恣意的な操作が入る部分である。ここの目利きが、その予想ソフトの強さに影響する。

つまり、標準タイムと馬場指数は過去のレースからの計算のみで算出することはできない。過去のレース結果を参考にして、そこから経験等をもとに調整することが必要だ。だからこそ、この部分が売り物になるのだろう。西田式スピード指数のサイトでは、標準タイムと馬場指数が有料で手に入れられる。もう少し、自動的な計算のみで指数を出せないものか。

2014年8月9日土曜日

データベースを使う(4)

データを取り出すのは簡単だ。SQLのselectを使えばいいだけ。下のような形で、馬名で指定する馬の一定期間内のデータを取得することが出来る。

public List<HorseData> select(String horsename, Date mindate, Date maxdate) {
try {
PreparedStatement ps = conn.prepareStatement("select * from Horse where name = ? and date < ? and date >= ? order by date DESC");
ps.setString(1, horsename);
ps.setDate(2, new java.sql.Date(maxdate.getTime()));
ps.setDate(3, new java.sql.Date(mindate.getTime()));
ResultSet rs = ps.executeQuery();
return readResultSet(rs);
} catch (SQLException se) {
for (SQLException e = se; e != null; e = e.getNextException()) {
TLog.e("%s: %s%n", e.getSQLState(), e.getMessage());
}
}
return null;

}
private List<HorseData> readResultSet(ResultSet rs) {
List<HorseData> list = new ArrayList<HorseData>();
try {
while (rs.next()) {
HorseData hd = new HorseData();
hd.name = rs.getString("name");
hd.term = rs.getInt("term");
hd.place = rs.getInt("place");
hd.day = rs.getInt("day");
hd.rnum = rs.getInt("rnum");
hd.date = new Date(rs.getDate("date").getTime());
hd.frame = rs.getInt("frame");
hd.number = rs.getInt("number");
hd.order = rs.getInt("ordernumber");
hd.time = rs.getInt("time");
hd.popularity = rs.getInt("popularity");
hd.weight = rs.getInt("weight");
hd.loadweight = rs.getFloat("loadweight");
hd.threefurlong = rs.getFloat("threefurlong");
hd.odds = rs.getFloat("odds");
hd.setPassorder(rs.getString("passorder"));
list.add(hd);
}
} catch (SQLException se) {
for (SQLException e = se; e != null; e = e.getNextException()) {
TLog.e("%s: %s%n", e.getSQLState(), e.getMessage());
}
}
return list;
}

2014年8月6日水曜日

データベースを使う(3)

データベースを使う(1)で作ったテーブルに、馬のデータを差し込んで行く。普通にSQLのinsertを使えばいいだけ。executeUpdate()を使えば、Primary Keyが同じ場合はエラーでなく、上書きされる。これをYahoo競馬から取得したデータをすべてデータベースに登録し直し。これで、使いやすくなったはず。

public boolean insert(Horse horse, int term, int place, int day, int rnum, Date date) {
try {
final String sql = "insert into Horse values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
final PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, horse.name);
ps.setInt(2, term);
ps.setInt(3, place);
ps.setInt(4, day);
ps.setInt(5, rnum);
ps.setDate(6, new java.sql.Date(date.getTime()));
ps.setInt(7, horse.frame);
ps.setInt(8, horse.number);
ps.setInt(9, horse.order);
ps.setInt(10, horse.time);
ps.setInt(11, horse.popularity);
ps.setInt(12, horse.weight);
ps.setFloat(13, horse.loadweight);
ps.setFloat(14, horse.threefurlong);
ps.setFloat(15, horse.odds);
ps.setString(16, horse.getPassorder());
ps.executeUpdate();
} catch (SQLException se) {
for (SQLException e = se; e != null; e = e.getNextException()) {
TLog.e("%s: %s%n", e.getSQLState(), e.getMessage());
}
}
return true;

}

2014年8月4日月曜日

データベースを使う(2)

テーブルを作るかどうかを判定するには、データを取ってみたらいいようだ。
ResultSet rs = null;
try {
final Statement s = conn.createStatement();
rs = s.executeQuery("select count(1) from Horse");
} catch (SQLException se) {
final String state = se.getSQLState();
if (state.equals("42X05")) {
makeTable(conn);
} else {
for (SQLException e = se; e != null; e = e.getNextException()) {
TLog.e("%s: %s%n", e.getSQLState(), e.getMessage());
}
}
} finally {
if (rs != null) try {rs.close();} catch (Exception e) {};

}

makeTableの先は、データベースを使うで書いたcreate tableを呼び出している。

2014年8月3日日曜日

データベースを使う

すべてオンメモリで動かせば、データベースを使う必要はないだろう。と、思ったが、結構でかい。全部読み込んだらエラーが出る。ヒープ領域を大きくすればいいのかもしれないが、すべてをメモリに読み込むのは止めることにした。それにあたり、Json形式でファイルを保存することにしていたが、読み込み時にデータをしぼることを考えれば、やはりデータベースを使うほうがいいだろう。なお、PCではなく、Google Appを使うことを考えたら、BigTableに置き換えることを想定したほうがいいのだが、普通にSQLを使う。JavaではDerbyを使うのがいいようだ。で、ライブラリに、ダウンロードしたderby.jarを追加した。
String CREATEHORSETABLE = 
"create table Horse " + 
"(name varchar(20) NOT NULL, term smallint NOT NULL, " + 
"place smallint NOT NULL, day smallint NOT NULL, " + 
"rnum smallint NOT NULL, date date NOT NULL, frame smallint, " + 
"number smallint, ordernumber smallint, time smallint, " + 
"popularity smallint, weight smallint, loadweight real, " + 
"threefurlong real, odds real, passorder char(20), " + 
"PRIMARY KEY(name, date))";
Connection conn = DriverManager.getConnection("jdbc:derby:/Users/tkydevelop/Documents/workspace/HorseRaceAnalyzer/db;create=true");
Statement s = conn.createStatement();
s.execute(CREATEHORSETABLE);
のようにしてテーブルを作成した。

2014年8月2日土曜日

Jsonで書き込みと読み出し

Yahoo競馬から取得したデータをjson形式でファイルに保存することにした。jsonのライブラリとして、jacksonを使った。Annotations, Streaming API, DataBindのライブラリを追加した。
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
.setVisibility(PropertyAccessor.CREATOR, Visibility.NONE)
.setVisibility(PropertyAccessor.SETTER, Visibility.NONE)
.setVisibility(PropertyAccessor.GETTER, Visibility.NONE)
.setVisibility(PropertyAccessor.IS_GETTER, Visibility.NONE);
om.writeValue(file, list);
writeValueを使うとオブジェクトの属性値がそのまま書き出される。加えて、たとえば、getXXXX的な名前の関数の値も書き出されてしまう。そのため、setVisibilityを使って、それらを書き出さないように変更した。
一方で読み込みをしようとしても、うまくオブジェクトに読み込むことができなかった。仕方ないので、
JsonNode rootNode;
rootNode = om.readTree(new File(filename));
for (JsonNode node: rootNode) {
Race race = new Race();
race.date = new Date(node.get("date").longValue());
のような形で、リストを繰り返しながら読み込んだ。

2014年7月31日木曜日

距離による時間差(2)

距離による時間差の記事で、2013年の京都の芝1200mと2400mの上位3頭平均タイムを示したが、クラスが上なのに遅いタイムの部分があった。これは、馬場が不良のときのデータも含んでいたのが理由のように思われるので、良馬場だけのデータにする。

2013年の京都の芝1200mの上位3頭の平均タイムは、以下である。
新馬(1レース) 1:10:1
未勝利(5レース) 1:09:4
500万下(4レース) 1:08:7
1000万下(7レース) 1:08:5
1600万下(2レース) 1:08:7
オープン(4レース) 1:07:8
GIII (2レース) 1:08:0
で、2400mは以下である。
未勝利(1レース) 2:26:2
500万下(4レース) 2:27:4
1000万下(4レース) 2:27:2
1600万下(3レース) 2:25:1
GII(2レース) 2:24:0

未勝利と500万下の差は、0.7秒と-1.2秒、
500万下と1000万下の差は、0.2秒と0.2秒、
1000万下と1600万下の差は、-0.2秒と2.1秒
である。少しはましになったが、やっぱり、きれいな差にはなっていない。スピード指数で比較するのは、難しいのではないか。

2014年7月30日水曜日

距離による時間差

同じ秒差でも、距離によって異なる価値がある。ということで、スピード指数では、以下のように距離指数というのを使って、距離による時間差を吸収している。
この指数は 1秒÷基準タイム×1000 の計算式から求められたものです。
実際のところ、どれぐらい差があるのだろうか。2013年の京都の芝1200mの上位3頭の平均タイムは、以下である。
新馬(2レース) 1:10:2
未勝利(5レース) 1:09:4
500万下(5レース) 1:08:9
1000万下(7レース) 1:08:5
1600万下(4レース) 1:09:1
オープン(5レース) 1:08:3
GIII (2レース) 1:08:0
で、2400mは以下である。
未勝利(1レース) 2:26:2
500万下(4レース) 2:27:4
1000万下(5レース) 2:27:6
1600万下(3レース) 2:25:1
GII(2レース) 2:24:0

未勝利と500万下の差は、0.5秒と-1.2秒、
500万下と1000万下の差は、0.4秒と-0.2秒、
1000万下と1600万下の差は、-0.6秒と2.5秒
である。きれいな差にはなっていない。2400mは未勝利のほうが500万下、1000万下より速いやんか。結局、データ数がそれほどないため、ほとんど誤差と言えるのだろう。

2014年7月29日火曜日

オープンにしかない距離

基準タイムを計算しようとしたとき、500万下、1000万下にない距離はどうすればいいのか。とりあえず、オープン以上しかないレースというのがどれだけあるのだろうか。2013年で見てみると(障害はのぞく)、

京都 芝3000m オープン平場と、GIのみ
京都 芝3200m GIのみ
阪神 芝3000m GIIのみ
中山 芝3600m GIIのみ
東京 芝2500m GIIのみ
東京 芝3400m GIIIのみ

これだけあるようだ。これらの距離は、オープンのタイムをもとに基準タイムを作るしかない。逆に言えば、これらのレースタイムは誤差が大きくなるだろうな。

2014年7月28日月曜日

例外的なデータ(2)

どんな距離のレースがあるんだろうとデータを見ていて気付いた。23600になっているデータがある。何じゃこりゃと思うと、これはダイヤモンドステークス(3600m)から取得したデータのよう。Yahooのページで確認してみると、

芝・右・内2周 3600m [コースガイド] 

うーん、やられた。距離の部分を抜き出すために、このデータを、


Integer.parseInt(course.replaceAll("[^0-9]", ""));

として、数字の部分以外を削除していた。その結果、内2周の2も抜き出されてしまった。さて、どうやって切り出そうかな。[スペース]とmの間で抜き出すか。

String[] distances = course.split(" ");
for (String distance: distances) {
if (distance.endsWith("m")) {
return Integer.parseInt(distance.replaceAll("[^0-9]", ""));
}

}

上記のように、抜き出す部分を限定してみる。

2014年7月27日日曜日

基準タイムに何を使えばいいのか(2)

基準タイムに500万下、1000万下の平均タイムを使うとしても、そのクラスにはない距離というのがある。長距離、たとえば3200mなんてオープンにしかないし。ということは、その基準タイムは、オープンをもとに決めるしかない。したがって、オープンのタイムがこれぐらいだから、500万下もしくは1000万下だとこれぐらいと出すことになるのだろう。ということで、クラスごとにどれぐらいの差があるのかを調査中。たとえば、2013年の阪神競馬場芝1600mの平均(上位3頭)は以下。

新馬(8レース) 1:37:5
未勝利(13レース) 1:35:7
500万下(8レース) 1:34:8
1000万下(7レース) 1:34:5
1600万下(2レース) 1:33:8
オープン(4レース) 1:33:5
GIII(2レース) 1:35:1
GI(2レース) 1:34:5

これを見ると、何となく妥当なタイムが出ているように思うが、GIなどはレース数が少ない分、馬場の状態などで大きな違いが出る気がする。

2014年7月26日土曜日

基準タイムに何を使えばいいのか

500万下と1000万下の距離ごとの平均をとり、基準タイムとすることを書いた。しかし、実際に平均を取ってみると、不思議なデータもある。

2013年函館の芝2000mのデータ
500万下 8レース上位3頭の平均 2:03:8
1000万下 4レース上位3頭の平均 2:05:8

500万下のほうが2秒も速い。本来は、1000万下のほうがクラスが上なのだから速いはずである。しかし、たった4レースの平均だとすると、これぐらい差が出てもしかたないのかもしれない。もう少し調べてみよう。で、上記の対象になっているレースは、以下。
1回函館1日12レース 500万下 (混合)(特指) 定量 馬場:良 タイム: 2.00.6

1回函館3日8レース 500万下 [指定] 定量 馬場:良 タイム: 2.01.1
1回函館5日12レース 1000万下 (混合)(特指) 定量 馬場:良 タイム: 2.03.4
2回函館2日10レース 500万下 (混合)(特指) 定量 馬場:良 タイム: 2.02.1
2回函館3日10レース 500万下 (混合)(特指) 定量 馬場:良 タイム: 2.01.6
2回函館6日10レース 1000万下 (混合)(特指) 定量 馬場:良 タイム: 2.01.7
3回函館1日10レース 500万下 (混合)(特指) 定量 馬場:良 タイム: 2.02.0
3回函館3日10レース 500万下 (混合)(特指) 定量 馬場:良 タイム: 2.01.8
3回函館6日10レース 1000万下 (混合) 定量 馬場:良 タイム: 2.02.5
4回函館2日9レース 500万下 (混合)(特指) 定量 馬場:重 タイム: 2.06.9
4回函館5日12レース 1000万下 (混合)[指定] ハンデ  馬場:不良 タイム: 2.15.2
4回函館6日8レース 500万下 (混合)(特指) 定量 馬場:重 タイム: 2.12.5
これを見ると、500万下は、開催の最初のほうで行われていて、1000万下は後半だ。芝が荒れていたせいかもしれない。また、馬場不良で行われた4回函館5日12レースの非常に遅いタイムが効いているとも言える。

過去のデータはというと、
2012年
500万下 3レース上位3頭の平均 2:02:3
1000万下 2レース上位3頭の平均 2:02:4
2011年
500万下 3レース上位3頭の平均 2:02:4
1000万下 2レース上位3頭の平均 2:01:7

で安定しているように見える。馬場が悪いときのデータは外すべきか。

2014年7月25日金曜日

基準タイム

競馬でどの馬が勝つかはいろんな要因があるものの、速く走ったほうが勝ち、ということから考えると、やはり走破タイムが重要と言える。そして、競馬場によって走りやすさに差があることから、異なる競馬場での走破タイムをそのまま比較することは出来ないだろう。で、競馬場ごとの距離ごとに基準タイムを作って、比較しやすいようにするのが、第一ステップである。西田式スピード指数では、


各競馬場ごとに500万条件と1000万条件で行われたレースの1~3着に入着した馬のタイムの平均を求めてさらに平均したものです。
つまり各競馬場の各距離ごとに500万条件と1000万条件の中間に位置するモデル馬を想定して、これらが出すであろうタイムが基準タイムなのです。

になっている。同条件のレースは多くあることや、実力の拮抗ぐらいから考えて、この値を使うぐらいしかいい手はないかな、やっぱり。各距離と書かれているが、内回りと外回りは分けるべきかもしれない。分けようと思った場合、Yahoo競馬のページでは、
芝・右・外 1600m
のように外の場合のみ記述されているようだ。なので、このコース情報に"外"が含まれているかどうかを判定すればいいのだろう。また、500万、1000万条件を抜き出すには、
1000万下 (混合)[指定] 定量
のように書かれている条件に1000万下と書かれているかどうかで抜き出す。なお、2001年に900万下だったのが1000万下に変更になっている。Yahoo競馬のデータから見ると、変更になったのは、1回函館1日(2001/6/9)が最初のように見えるが、同時開催の東京・中京は900万のままだ。よくわからないな。とりあえず、900万下も1000万下も同じとしてマッチングすれば抜き出せるだろう。また、2歳の500万下と3歳以上の500万下には差がありそうな気がするが、平均だし、まずは気にせず同じものと取り扱うことにする。

この基準タイムは、予想するレースより、過去のレースのデータから求めないといけない。予想ソフトを作るのだから、当たり前だが、予想するレースが実施される前に手に入れられるデータのみを使うように制限する必要がある。ということで、基準タイムは、予想するレースの前年度のデータを使うことにするか。つまり、今(2014年)なら、2013年のデータを使うことになる。しかし、競馬場の改装工事があった場合、前年度データがないことも考えられるので、2年分の平均をとることにする。これで、データがないことを防げるだろう。