AI競馬で回収率100%越えを目指して

はなむけ競馬場

python 競馬

【失敗談】モデル構築に失敗していた話+修正

投稿日:

【テスト開始】回収率170%超えのAI開発に成功【解説】などで書いた通り、機械学習で競馬予想モデルを作成しました。

個人レベルで開発しているものであり、出来たと思ってもあとで失敗していたというのがここ一か月続いています。

今回失敗していた箇所を説明し、次に生かしたいと思います。

レースの順番をうまくソートできていなかった

過去のレースの結果をたくさん使っているため、1戦前、2戦前という順番は正確にしないと意味がありません。

1走前のデータを2走前のデータとして扱うことは意味がないどころか、未来の情報を教えていることになり、データのリークにつながります。

未知のデータに対して正答を導き出す機械学習において、正解を見せた状態で予測しろと言っても、カンニングしているじょうたいなので、高い精度が出ても意味はありません。

今回、レース順番に対する理解が甘く、適切なデータ処理が出来ていませんでした。

騎手は一日に何回かレースに出走しています。

データを見たところ、連続するレースに出走しており、その間隔は1時間に満たないこともあります。

私がもともと集めていたデータには分単位のデータは無く、時間単位でしか集めていませんでした。

よって、おなじ10時台で出走する場合、データ的にはどっちが先に走っているのかわからなくなっていました。

前走データがごちゃごちゃになっており、2走前のデータが1走前、1走前のデータが2走前になるなど、ところどころ間違っていました。

特に、1位率、3位率などのデータに関しては致命的に狂っていまいした。

競馬データを扱う際には、分単位(出走時間)で集めたほうが良いでしょう。

出走時間の取得

前述の出走データを取得し、関連するデータを修正するために、netkeiba.comからデータを集めるコードは以下の通りです。

import MySQLdb
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
import datetime
# 接続する
conn = MySQLdb.connect(
user='root',
passwd='',
host='localhost',
db='keiba',
charset='utf8')
# カーソルを取得する
cur = conn.cursor()
# カーソルを取得する
cur = conn.cursor(MySQLdb.cursors.DictCursor)

#SQLをすべてDataFrameに変換する
df = pd.read_sql_query(sql='SELECT * FROM `race_result` WHERE 1', con="mysql+mysqlconnector://root:@localhost:3306/keiba")
#各レースのID
race_link = df["レースID"].unique()
options = webdriver.ChromeOptions()
options.add_argument('--user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1')

driver = webdriver.Chrome(options=options)

for i in race_link:

    driver.get("https://db.netkeiba.com/race/" + str(i))

    WebDriverWait(driver, 120).until(EC.presence_of_element_located((By.ID, "PageTOP")))

    #発走時間
    run_time_4date = driver.find_element_by_css_selector("body > div.Wrap.wide_table.fc > div > div.RaceHeader_Value > div.RaceData > span:nth-child(1)").text
    run_time_4date = re.findall(r"\d{2}",run_time_4date)

    #日付
    date_4date = driver.find_element_by_css_selector(".Race_Date").text[0:-3].split("/")
    date_4date = list(map(int,date_4date))

    nitizi = datetime.datetime(date_4date[0],date_4date[1],date_4date[2],int(run_time_4date[0].lstrip("0")),int(run_time_4date[1]))
    
    sql = "UPDATE race_result SET `日時`='" + str(nitizi) +"' WHERE `レースID`='" + str(i) + "'"
    
    
    time.sleep(0.5)
    cur.execute(sql)
    conn.commit()

netkeiba.comの各レース情報にある発送時間を取得しています。

正しいモデル作成のために正しいデータを

今回凡ミスしたのは、「面倒だからいいや」という気持ちで最初にプログラムを組んでいたことに起因します。

分単位では要らないだろうという希望的観測を持ち込んで、結果的により面倒な状況になってしまいました。

要るか要らないか分からなくても、データなんてあって困るなんてことは少ないでしょうから、今後はどんどん取っていければと思います。

ちなみに、500%あった回収率は200%行かないくらいになってしまいました。

これでも高いので、まだどこかでミスっているのではと恐れているところです。

-python, 競馬

Copyright© はなむけ競馬場 , 2021 All Rights Reserved Powered by AFFINGER5.