Rで競馬予測関数を作って実際に使用してみた【ウキゴリラの趣味】

スポンサーリンク

はじめに

最近競馬を始めてしまいました、、、。
(月1万ほどしか賭けないエンジョイ派ですが)

何回か賭けてみて、データって大事だなと強く思いました。
そこで「回帰線作ってタイム予測させたら当たるんじゃね」と考え、試しに作ってみました。

スポンサーリンク

コードと使い方

今回は楽天競馬で公開されているデータを利用させていただきました。

楽天競馬では出走する各馬のデビューから今日までの成績を以下の写真のような形で見ることができます。

このデータについて次のようなデータセットに編集しました。

楽天競馬のデータシートはエクセルなどの表計算ソフトにそのままペーストできます。
ただし、馬場の状態と天候はセル結合という扱いになるため、他の列には空白ができてしまいます。
「いらない列を削除→空白にすべて「NA」を入れる→na.omit()を使ってNAが含まれている行を消す」
上記の手順を踏むことで上の図のようなデータセットになります。

そして以下に公開しているコードを入力した後
Keibayosoku(data名,Time,Dis,予測したいレースの距離)と打ち込みます

・コードの例
Keibayosoku(KochiR10_0227,KochiR10_0227$Time,KochiR10_0227$Dis,1300)
#高知競馬場2月27日のR10を予測していたのでこのようなデータ名です(笑)

すると予測したタイムとそのプロットが出力されます。

スポンサーリンク

競馬予測関数を作成するコード

今回作ってみた関数は以下の通りです。
各距離のタイムを指数関数で近似し、その推定値を算出して、出力しています。
ややごり押し感はありますが、参考までにどうぞ

注. Timeは上記のデータセットのように「分:秒.小数点以下」と打たないとうまくいかないです。
注. 馬番の列名はIDと指定ください。
注. 地方競馬しかしていないため、ダートのレースのみ対応です。芝に変えるには二列目を”ダ”→”芝”に変えてください。

Keibayosoku<-function(data,time,dis,x){
  data$Dis<-sub("ダ", "", dis)
  data$Dis<-as.numeric(data$Dis)

  data$SecTime<-
    (as.numeric(as.POSIXlt(time, format="%M:%S", tz = "Japan")$min*60)
     +as.numeric(as.POSIXlt(time, format="%M:%S", tz = "Japan")$sec)
     +as.numeric(substr(time, 7, 7))/10)
  
  No1<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==1),start=c(a=10,b=0))
  No2<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==2),start=c(a=10,b=0))
  No3<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==3),start=c(a=10,b=0))
  No4<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==4),start=c(a=10,b=0))
  No5<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==5),start=c(a=10,b=0))
  No6<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==6),start=c(a=10,b=0))
  No7<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==7),start=c(a=10,b=0))
  No8<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==8),start=c(a=10,b=0))
  No9<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==9),start=c(a=10,b=0))
  No10<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==10),start=c(a=10,b=0))
  No11<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==11),start=c(a=10,b=0))
  No12<-nls(SecTime~a*(as.numeric(Dis))^b,data=subset(na.omit(data),ID==12),start=c(a=10,b=0))
  
  distance=x
  KochiR10_0227predict<-
    data.frame(No=c(1:12),
               Predicter=c(
                 summary(No1)$parameters[1,1]*(distance)^summary(No1)$parameters[2,1],
                 summary(No2)$parameters[1,1]*(distance)^summary(No2)$parameters[2,1],
                 summary(No3)$parameters[1,1]*(distance)^summary(No3)$parameters[2,1],
                 summary(No4)$parameters[1,1]*(distance)^summary(No4)$parameters[2,1],
                 summary(No5)$parameters[1,1]*(distance)^summary(No5)$parameters[2,1],
                 summary(No6)$parameters[1,1]*(distance)^summary(No6)$parameters[2,1],
                 summary(No7)$parameters[1,1]*(distance)^summary(No7)$parameters[2,1],
                 summary(No8)$parameters[1,1]*(distance)^summary(No8)$parameters[2,1],
                 summary(No9)$parameters[1,1]*(distance)^summary(No9)$parameters[2,1],
                 summary(No10)$parameters[1,1]*(distance)^summary(No10)$parameters[2,1],
                 summary(No11)$parameters[1,1]*(distance)^summary(No11)$parameters[2,1],
                 summary(No12)$parameters[1,1]*(distance)^summary(No12)$parameters[2,1])
    )
  print(KochiR10_0227predict)
  plot(KochiR10_0227predict$No,KochiR10_0227predict$Predicter)
  plot(data$Dis,data$SecTime,type="n")
  lines(subset(na.omit(data),ID==1)$Dis,fitted(No1),col="Black")
  lines(subset(na.omit(data),ID==2)$Dis,fitted(No2),col="gray")
  lines(subset(na.omit(data),ID==3)$Dis,fitted(No3),col="red")
  lines(subset(na.omit(data),ID==4)$Dis,fitted(No4),col="blue")
  lines(subset(na.omit(data),ID==5)$Dis,fitted(No5),col="yellow")
  lines(subset(na.omit(data),ID==6)$Dis,fitted(No6),col="lightyellow")
  lines(subset(na.omit(data),ID==7)$Dis,fitted(No7),col="green")
  lines(subset(na.omit(data),ID==8)$Dis,fitted(No8),col="lightgreen")
  lines(subset(na.omit(data),ID==9)$Dis,fitted(No9),col="orange")
  lines(subset(na.omit(data),ID==10)$Dis,fitted(No10),col="Moccasin")
  lines(subset(na.omit(data),ID==11)$Dis,fitted(No11),col="pink")
  lines(subset(na.omit(data),ID==12)$Dis,fitted(No12),col="Coral")
}
スポンサーリンク

試しに使ってみた

2月27日の高知競馬場最終ラウンドで使ってみました。

出走馬のここ一年間の高知競馬場におけるレースの結果を抽出して用いました。
ただし、一か月以上欠場している場合はその欠場後の成績のみを用いました。

上の条件で作成したデータセットを上記の関数で予測した結果は「6→12→9→1→11」という結果でした。

そして実際の結果は、、、

「12→1→6→2→5」という結果で、掲示板5頭のうち3頭当たりました!!

実は6は12番人気で三連複で16860円の払い戻しでした!
(私は信じきれなかったので1-12-9の馬複BOXを買って一応的中しました、、、)

もしかして、使える、、、!?
でも、5番は最下位の予測だったし、9番は9着だったし、まだまだ改良の余地はありそうです。

今後、バージョンアップや、何レースか試して的中率の算出を行い、公開したいと思います。

注. 上記の関数を使っても必ず当たるとは限りません(多分外れます)。使用する場合は自己責任でお願いします。

コメント

タイトルとURLをコピーしました