4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

競馬AI〜タイムと着差をスクレイピング〜

Last updated at Posted at 2021-02-10

タイムと着差がスクレイピング出来てない。。。

前回、競馬AIを作りたくてnetkeiba.com様からスクレイピングさせてもらいました。その時のデータがこんな感じです。
スクリーンショット 2021-02-10 11.03.07.png

タイムがない。。。!!!
順位であるrankを予測したいので一応これでも予測出来るのですが、やはり競馬において走破タイムは大事になってきます。有名なものだと走破タイムから計算した西田式スピード指数というものがあります。これは以下の式で表されます。

西田式スピード指数=( 基準タイム - 走破タイム ) × 距離指数 + 馬場指数 + (斤量-55) × 2 + 80

詳しい解説は[こちら]が参考になりました。
[こちら]:https://team-d.club/about-speed-index/
計算は置いておいて、とにかく走破タイムをスクレイピングしないと始まらない。

環境

Google Colab

走破タイムをスクレイピング

netkeiba.com様からスクレイピングします。
スクリーンショット 2021-02-10 11.24.00.png
こちらのタイム着差の列をスクレイピングしていきます。
スクレイピングの流れは
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文で回しながらタイムと着差を取得していきます。
ほしい要素は右クリック→検証で見ることが出来ます。
スクリーンショット 2021-02-10 14.01.49.png
すると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時間くらいかかりました。)
スクリーンショット 2021-02-10 13.56.38.png

偶数行にタイム、奇数行に着差が入った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)#もとのデータに結合

結合後はこんな感じです。
スクリーンショット 2021-02-10 13.53.46.png
ちゃんと結合できてますね。
着差についてはクビとか鼻を何秒とかに直したほうが良さそうですね。クビの着差ってコンマ何秒とかだと思いますが、秒に直してタイムと足すことで本当の走破タイムを計算できます。
タイムについてもそのまま使うとリークを起こすので、時系列でソートして過去のデータを使うなどの工夫が必要です。
これらを使って、競馬AIをグレードアップしてみます。
最後までご覧いただきありがとうございました。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?