タイムと着差がスクレイピング出来てない。。。
前回、競馬AIを作りたくてnetkeiba.com様からスクレイピングさせてもらいました。その時のデータがこんな感じです。
タイムがない。。。!!!
順位であるrankを予測したいので一応これでも予測出来るのですが、やはり競馬において走破タイムは大事になってきます。有名なものだと走破タイムから計算した西田式スピード指数というものがあります。これは以下の式で表されます。
西田式スピード指数=( 基準タイム - 走破タイム ) × 距離指数 + 馬場指数 + (斤量-55) × 2 + 80
詳しい解説は[こちら]が参考になりました。
[こちら]:https://team-d.club/about-speed-index/
計算は置いておいて、とにかく走破タイムをスクレイピングしないと始まらない。
環境
Google Colab
走破タイムをスクレイピング
netkeiba.com様からスクレイピングします。
こちらのタイムと着差の列をスクレイピングしていきます。
スクレイピングの流れは
1 requestsでhtmlを取得
2 BeautifulSoupでほしい要素を(タイムと着差)取得
これをレースIDごとにfor文を回して取得するだけです。レースIDは前回スクレイピングしてきたcsvファイルのUnnamed:0の下2桁を除いた番号です。
requestsを使って、URLにアクセスするのですが上記のような結果ページのURLは
https://race.netkeiba.com/race/result.html?race_id=レースID&rf=race_list
となっています。レースIDの部分をfor文で回しながらタイムと着差を取得していきます。
ほしい要素は右クリック→検証で見ることが出来ます。
するとspanタグのRaceTimeクラスに格納されていることが分かります。
全体のコードは以下のとおりです。
import requests
from bs4 import BeautifulSoup
import time
df_time_tyakusa = pd.DataFrame()
id=keiba_data["race_num"].unique().astype("str")
for h in id:
time.sleep(1)
url = "https://race.netkeiba.com/race/result.html?race_id=" + h + "&rf=race_list"
urls = requests.get(url) #URLを取得
soup = BeautifulSoup(urls.content, "html.parser") #htmlを解析する
racetime = soup.find_all("span",class_="RaceTime") #spanタグのRaceTimeクラスにタイムと着差がある。
for i in racetime:
texts = i.text #テキストにする。
s = pd.Series(texts)#Seriesにする。
df_time_tyakusa=df_time_tyakusa.append(s,ignore_index=True) #DataFrameに追加する。
結果は以下のとおりです。(コードが非効率なせいか2015~2018年のデータだけでも3時間くらいかかりました。)
偶数行にタイム、奇数行に着差が入ったSeriesが取得できるので、それらを分けてもともとのkeiba_dataに結合します。
df_time_tyakusa.columns=["time","tyakusa"] #カラム名を命名
tyakusa=df_time_tyakusa[1::2].reset_index(drop=True) #奇数行を取得
time=df_time_tyakusa[::2].reset_index(drop=True) #偶数行を取得
time_tyakusa=pd.concat([time,tyakusa],axis=1) #タイムと着差を結合
keiba_data = pd.concat([keiba_data,time_tyakusa],axis=1)#もとのデータに結合
結合後はこんな感じです。
ちゃんと結合できてますね。
着差についてはクビとか鼻を何秒とかに直したほうが良さそうですね。クビの着差ってコンマ何秒とかだと思いますが、秒に直してタイムと足すことで本当の走破タイムを計算できます。
タイムについてもそのまま使うとリークを起こすので、時系列でソートして過去のデータを使うなどの工夫が必要です。
これらを使って、競馬AIをグレードアップしてみます。
最後までご覧いただきありがとうございました。