競馬予測AIの作成⑩(開催レースの順位予測)

機械学習

はじめに

開催予定のレース情報をJRAのサイトから取得し、取得した情報と以前に作成した予測モデルを用いて順位を予測するプログラムを作成しました。

作成したプログラムは2つあります。

  1. 前回作成したプログラムの改修
    プログラム名:JRA_scraping_raceinfo.py
    前回作成したプログラムは、東京と阪神で開催されるレースの情報は取得できましたが、その他の札幌、中山、中京などで開催されるレースの情報は取得できませんでした。開催場所がどこであってもレース情報を取得できるように前回のプログラムを改修しました。
  2. 取得したレース情報から順位を予測するプログラム
    プログラム名:predict_rank.py
    取得したレース情報と以前に作成した予測モデルを用いて、レースの順位予測を出力するプログラムを作成しました。1~3位を出力するようにしています。

<取得したレース情報の出力例>

<順位予測プログラムの出力例>

赤枠内が順位予測の結果です。

プログラムの概要

JRA_scraping_raceinfo.pyの概要

該当行 概要
1~16 モジュールとライブラリの読み込み
22 メイン処理の開始位置
27 seleniumでJRAの出走表にアクセスする
30 出走表から開催場所を抽出する
33 抽出した開催場所のURLを取得する
36~40 開催場所ごとの各ラウンド情報のURLを取得する
43~51 各ラウンドのレース情報の抽出と整形を行い、データフレームに追記保存する
54~116 開催場所ごとの天候と馬場情報を取得し、データフレームに追記保存する
119~124 作成したデータフレームを整形する
127~128 データフレームをCSVファイルに保存する
139~476 自作した関数

predict_rank.pyの概要

該当行 概要
1~15 モジュールとライブラリの読み込み
21 メイン処理の開始位置
26~27 JRA_scraping_raceinfo.pyで取得したレース情報のCSVファイルを読み込む
30 レース情報の開催日の型をdate方に変換する
33 作成した予測モデル、レース情報をエンコードしたオブジェクトのパスを設定する
36 作成した予測モデルを読み込む
39~42 レース情報をエンコードする
45 レース情報をdmatrixに変換する
48~49 タイムを予測し、レース情報に追加する
52 レース名と開催場所、ラウンドをラベルエンコードする
55 エンコードされたレース名からユニークなレース名を抽出する
58 予測順位を保存するデータフレームを用意する
61~81 各レースに対して、追加した予測タイムで昇順に並び替えて順位を着ける
用意したデータフレームには、1~3位までのデータを追記する
84~90 データフレームから不要な列の削除と列の並び替えを行う
93~98 予測順位を含めたデータフレームをCSVファイルに保存する
108~132 自作した関数

作成したプログラム

JRA_scraping_raceinfo.py

# ライブラリの読み込み
import pandas as pd
import urllib
import requests
import re
import time

# スクレイピングで使用するライブラリを読み込む
from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.options import Options

# プログレスバーを表示するためのライブラリを読み込む
from tqdm import tqdm


# メイン処理
# JRAの「出走表」に掲載されているレース情報を取得する
# 取得したレース情報はCSVファイルに保存する
def main():
    # プログラムの開始時刻を取得する
    start_time = time.time()

    # seleniumで出走表にアクセスする
    soup = access_entries()

    # レース開催場所を取得する
    location_list = get_locations(soup)

    # 開催場所のURLを取得する
    location_url = get_location_url(soup)

    # 開催場所ごとのラウンドのURLを取得する
    round_url = []
    for i in location_url:
        res = requests.get(i)
        soup = BeautifulSoup(res.content, 'html5lib')
        round_url.extend(get_round_url(soup))

    # レース情報の抽出と整形を行い、データフレームに追記保存する
    races_info = pd.DataFrame()
    print('レース情報の取得を開始します')
    for i in tqdm(round_url):
        soup = preparing_data(i)
        try:
            races_info = pd.concat([races_info, get_race_info(soup)])
        except BaseException as err:
            print(err)
            print('予測に必要なデータが掲載されていません')

    # 天候と馬場情報を取得する
    for location in location_list:
        if '札幌' in location:
            sapporo = riding_ground('札幌')
            sapporo.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, sapporo)

        if '函館' in location:
            hakodate = riding_ground('函館')
            hakodate.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, hakodate)

        if '福島' in location:
            fukushima = riding_ground('福島')
            fukushima.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, fukushima)

        if '新潟' in location:
            niigata = riding_ground('新潟')
            niigata.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, niigata)

        if '東京' in location:
            tokyo = riding_ground('東京')
            tokyo.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, tokyo)

        if '中山' in location:
            nakayama = riding_ground('中山')
            nakayama.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, nakayama)

        if '中京' in location:
            chuukyo = riding_ground('中京')
            chuukyo.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, chuukyo)

        if '京都' in location:
            kyoto = riding_ground('京都')
            kyoto.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, kyoto)

        if '阪神' in location:
            hanshin = riding_ground('阪神')
            hanshin.get_weather_condition_info()

            # 天候、馬場情報を設定する
            races_info = set_weather_condition(races_info, hanshin)

    # 列を並び替える
    races_info = races_info.reindex(columns=['horse', 'age', 'rider_weight',
                                             'rider', 'odds', 'popular',
                                             'horse_weight', 'distance',
                                             'weather', 'ground', 'condition',
                                             'date', 'race_name', 'location',
                                             'round'])

    # CSVにレース情報を保存する
    file_name = '予測対象のレース情報.csv'
    races_info.to_csv(file_name, encoding='cp932', index=False, errors='ignore')

    # プログラムの実行時間を表示する
    run_time = time.time() - start_time
    print('実行時間:{:.2f}秒'.format(run_time))


# chromeを起動し、jra.go.jpにアクセスして出走表を表示する
# 直接、https://jra.go.jp/JRADB/accessD.htmlにアクセスするとエラーになるので、seleniumでアクセスする
# 引数:なし
# 戻値:BeautifulSoup4オブジェクト
def access_entries():
    # chromeを起動する
    browser = webdriver.Chrome(ChromeDriverManager().install())

    # 競馬データベースを開く
    browser.get('https://www.jra.go.jp/')
    browser.implicitly_wait(20)  # 指定した要素が見つかるまでの待ち時間を20秒と設定する

    # 出馬表をクリック
    xpath = '//*[@id="quick_menu"]/div/ul/li[2]/a'
    elem_search = browser.find_element(By.XPATH, value=xpath)
    elem_search.click()

    # 「今週の出馬表」の左端の開催をクリック
    xpath = '//*[@id="main"]/div[2]/div/div/div[1]/a'
    elem_search = browser.find_element(By.XPATH, value=xpath)
    elem_search.click()

    # ラウンドをクリック
    xpath = '//*[@id="race_list"]/tbody/tr[1]/th'
    elem_search = browser.find_element(By.XPATH, value=xpath)
    elem_search.click()

    # 表示しているページのURLを取得する
    cur_url = browser.current_url
    res = requests.get(cur_url)  # 指定したURLからデータを取得する
    soup = BeautifulSoup(res.content, 'lxml')  # content形式で取得したデータをhtml形式で分割する

    return soup


# レース開催場所を抽出する
# 引数:BeautifulSoupオブジェクト
# 戻値:レース開催場所の一覧
def get_locations(soup):
    tag_div = soup.find_all('div', attrs={'class': 'link_list multi div3 center mid narrow'})
    tag_div_text = tag_div[0].text
    tag_div_text = re.sub(r'\d', '', tag_div_text)      # 数字を削除する
    location_list = re.sub(r'[回日]', '', tag_div_text)   # 回,日の文字を削除する
    location_list = location_list.split('\n')           # 改行で分割する
    location_list = list(filter(None, location_list))   # 空の要素を削除する

    return location_list


# 開催場所のURLを取得する
# 「5回東京5日」「5回阪神5日」などのURLを取得する
# 引数:BeautifulSoupオブジェクト
# 戻値:開催場所のURLをリストで返す
def get_location_url(soup):
    locations_info = soup.find_all('div', attrs={'class': 'link_list multi div3 center mid narrow'})

    # 開催場所のURLを保存するリストを用意
    location_url = []

    # 取得したdivタグから追加でaタグを取得し、aタグからhrefを抽出する
    # 'https://www.jra.go.jp'と抽出したhrefを結合してlocation_urlに保存する
    for locations in locations_info:
        for location in locations.find_all('a'):
            url = urllib.parse.urljoin('https://www.jra.go.jp', location.get('href'))
            location_url.append(url)

    return location_url


# ラウンドのURLを取得する
# ラウンドへのリンクはページの上部と下部の2箇所に配置されている
# 上部のリンクを用いてラウンドのURLを取得する
# 引数:BeautifulSoupオブジェクト
# 戻値:ラウンドのURLをリストで返す
def get_round_url(soup):
    rounds_info = soup.find('ul', attrs={'class': 'nav race-num mt15'})

    # ラウンドのURLを保存するリストを用意
    round_url = []

    tmp = rounds_info.find_all('a')
    # リンクページのURLを作成する
    for round in rounds_info.find_all('a'):
        url = urllib.parse.urljoin('https://www.jra.go.jp', round.get('href'))
        round_url.append(url)

    return round_url


# レース情報を取得する
# 引数:BeautifulSoupオブジェクト
# 戻値:取得したレース情報をデータフレームで返す
def get_race_info(soup):
    # 出走情報を保存するデータフレームを用意する
    race_info = pd.DataFrame()

    # tableデータを抽出する
    tbody = soup.find('tbody')
    tbody = tbody.find_all('tr')

    # 作業用のデータフレームを用意する
    df = pd.DataFrame()
    df_tmp1 = pd.DataFrame()

    # tableデータを1行ごとにデータフレームに代入する
    # 除外、取消の出走馬は、データフレームに含めない
    for tb in tbody[0:]:
        tmp = tb.text.split('\n')
        if '除外' in tmp or '取消' in tmp:
            continue
        df_tmp1 = pd.Series(tmp)
        df = pd.concat([df, df_tmp1], axis=1)

    # 人気を抽出する
    popular_list = []
    for i in df.iloc[5]:
        popular = re.findall('\(.*\)', i) # 「(x番人気)」を抽出する
        popular = re.sub(r'\D', '', popular[0])  # 数字を抽出する
        popular_list.append(popular)

    # 名前を抽出する
    horse_list = []
    for i in df.iloc[5]:
        horse = re.findall('[\u30A1-\u30FF]+', i)[0]  # カタカナを抽出する
        horse_list.append(horse)

    # 単勝オッズを抽出する
    # 「キリシマラッキー274.6(14番人気)」の場合、「(」で分割して、カタカナを削除すると、
    # 「274.6」が抽出できる
    odds_list = []
    for i in df.iloc[5]:
        tmp = i.split('(')
        odds = re.sub('[\u30A1-\u30FF]+', '', tmp[0])
        odds_list.append(odds)

    # 馬体重を抽出する
    horse_weight_list = []
    for i in df.iloc[7]:
        tmp = i.split('kg')
        horse_weight = tmp[0]

        # int型への変換処理を入れることで、文字列だった場合はエラーを返すようにする
        horse_weight = int(horse_weight[-3:])
        horse_weight_list.append(horse_weight)

    # 性齢を抽出する
    # 'せん'をnetkeibaの'セ'に合わせる
    age_list = []
    for i in df.iloc[13]:
        tmp = i.split('/')
        age = tmp[0].replace('せん', 'セ')
        age_list.append(age)

    # 斤量を抽出する
    # 騎手の斤量増減を示すマークは削除する
    rider_weight_list = []
    for i in df.iloc[15]:
        tmp = i.split('kg')
        rider_weight = tmp[0]
        rider_weight_list.append(rider_weight)

    # 騎手名を抽出する
    rider_list = []
    for i in df.iloc[17]:
        rider = i.replace('▲', '').replace('△', '').replace('☆', '').replace('◇', '').replace('★', '').replace(' ', '')
        rider_list.append(rider)

    # ラウンド数を取得する
    # 'レース'をnetkeibaの' R'に合わせる
    round = soup.find_all('div', attrs={'class': 'race_number'})
    round = round[0].next_element.attrs['alt']
    round = round.replace('レース', ' R')

    # 開催日、開催場を抽出する
    # 開催日のrace_dateに代入する値は、race_base_infoを空白でsplitした「2022年11月19日(土曜)」を
    # 追加で'('でsplitして、「2022年11月19日」の形式
    # 'x回東京x日'をnetkeibaの'x回東京x日目'に合わせる
    race_base_info = soup.find_all('div', attrs={'class': 'cell date'})
    race_date = race_base_info[0].text.split()[0]
    race_date = race_date.split('(')[0]
    race_location = race_base_info[0].text.split()[1]
    race_location = race_location.replace('日', '日目')

    # レース名を取得する
    race_name = soup.find_all('span', attrs={'class': 'race_name'})
    race_name = race_name[0].text

    # レース距離を取得する
    race_course_info = soup.find_all('div', attrs={'class': 'cell course'})
    race_distance = race_course_info[0].text.split()
    race_distance = re.sub(r'\D', '', race_distance[0])

    # 馬場を取得する
    ground = str(race_course_info[0].text.split())

    if 'ダート' in ground:
        ground = 'ダート'

    if '芝' in ground:
        ground = '芝'

    # 出走情報のデータフレームに'horse_list'を追記する
    race_info['horse'] = horse_list

    # 出走情報のデータフレームに'age'を追記する
    race_info['age'] = age_list

    # 出走情報のデータフレームに'rider_weight'を追記する
    race_info['rider_weight'] = rider_weight_list

    # 出走情報のデータフレームに'rider'を追記する
    race_info['rider'] = rider_list

    # 出走情報のデータフレームに'odds'を追記する
    race_info['odds'] = odds_list

    # 出走情報のデータフレームに'popular'を追記する
    race_info['popular'] = popular_list

    # 出走情報のデータフレームに'horse_weight'を追記する
    race_info['horse_weight'] = horse_weight_list

    # 出走情報のデータフレームに'distance'を追記する
    race_info['distance'] = race_distance

    # 出走情報のデータフレームに'gournd'を追記する
    race_info['ground'] = ground

    # 出走情報のデータフレームに'race_date'を追記する
    race_info['date'] = race_date

    # 出走情報のデータフレームに'race_name'を追記する
    race_info['race_name'] = race_name

    # 出走情報のデータフレームに'race_location'を追記する
    race_info['location'] = race_location

    # 出走情報のデータフレームに'round'を追記する
    race_info['round'] = round

    return race_info


# 指定したURLからHTML情報を取得し、データを整形する
# ブリンカーを着用している馬は、他の馬より1つデータが多いため、その後の処理でエラーが出る
# ブリンカー着用のタグを削除してデータを整える
# 引数:ラウンドのURL
# 戻値:BeautifulSoupオブジェクト
def preparing_data(url):
    res = requests.get(url)  # 指定したURLからデータを取得する
    soup = BeautifulSoup(res.content, 'html5lib')  # lxmlだと失敗するページがあったので、html5libを設定

    # ブリンカー着用のクラスを削除する
    class_blinker_tag = soup.find_all('span', attrs={'class': 'horse_icon blinker'})
    for i in class_blinker_tag:
        i.decompose()

    # ブリンカー着用のタグを削除しても、不要な改行が残るので、改行を空文字で置換する
    num_tag = soup.find_all('td', attrs={'class': 'num'})
    for i in soup.find_all('td', attrs={'class': 'num'}):
        num = i.text.replace('\n', '')
        i.replace_with(num)

    return soup


# レース開催場所の天候、馬場情報を取得する
# 引数:レース開催場所の名前(東京、阪神、福島、など)
# 戻値:なし
class riding_ground:
    def __init__(self, location):
        self.location = location
        self.weather = ''
        self.shiba_condition = ''
        self.dart_condition = ''

    # レース開催場所の天候、馬場状態を取得する
    def get_weather_condition_info(self):
        url = 'https://www.jra.go.jp/keiba/baba/'
        res = requests.get(url)
        soup = BeautifulSoup(res.content, 'lxml')

        # 天候の情報を取得する
        class_cell_txt = soup.find('div', attrs={'class': 'cell txt'})
        self.weather = class_cell_txt.text.replace('天候:', '')

        # レース開催予定の馬場と情報が掲載されているURLを取得する
        location_list = []
        location_url = []
        class_nav_tab = soup.find_all('div', attrs={'class': 'nav tab'})
        tag_a = class_nav_tab[0].find_all('a')

        for i in tag_a:
            location_list.append(i.text)
            url = urllib.parse.urljoin(url, i.get('href'))
            location_url.append(url)

        # 「XX競馬場」を「XX」に置換する
        location_list = [s.replace('競馬場', '') for s in location_list]

        # 指定されたレース開催場所の馬場情報URLを抽出する
        index_num = location_list.index(self.location)
        url = location_url[index_num]

        # urlの馬場情報を取得する
        res = requests.get(url)
        soup = BeautifulSoup(res.content, 'lxml')

        class_data_list_unit = soup.find_all('div', attrs={'class': 'data_list_unit'})
        for i in class_data_list_unit:
            tag_h4 = i.find_all('h4')

            # h4が存在しない場合、次の処理に進む
            if len(tag_h4) == 0:
                continue

            if tag_h4[0].text == '芝':
                tag_p = i.find_all('p')
                self.shiba_condition = tag_p[0].text

            if tag_h4[0].text == 'ダート':
                tag_p = i.find_all('p')
                self.dart_condition = tag_p[0].text


# 天候と馬場情報を設定する
# 引数:レース情報の一覧、レース開催場所の情報
# 戻値:天候と馬場情報を追加したレース情報の一覧
def set_weather_condition(df, place_name):
    # インデックスをリセットする
    df = df.reset_index(drop=True)

    # 天気を設定する
    df.loc[df['location'].str.contains(place_name.location), 'weather'] = place_name.weather

    # 馬場情報を設定する
    df.loc[(df['location'].str.contains(place_name.location)) &
           (df['ground'].str.contains('芝')), 'condition'] = place_name.shiba_condition
    df.loc[(df['location'].str.contains(place_name.location)) &
           (df['ground'].str.contains('ダート')), 'condition'] = place_name.dart_condition

    return df


if __name__ == "__main__":
    main()

predict_rank.py

# システム用のライブラリ
import datetime
import time

# 数値解析用のライブラリ
import pandas as pd

# モデル保存用のライブラリ
import joblib

# xgboostのライブラリ
import xgboost as xgb

# ラベルエンコードのライブラリ
from sklearn.preprocessing import LabelEncoder


# メイン処理
# 作成した予測モデルで予測対象のレース情報の順位を予測する
# 予測した結果はCSVファイルに出力する
def main():
    # プログラムの開始時刻を取得する
    start_time = time.time()

    # 予測対象のレース情報を読み込む
    df_file = 'C:\\Users\\sakur\\Google ドライブ\\Web_Scraping\\予測対象のレース情報.csv'
    df = pd.read_csv(df_file, encoding='cp932')

    # 開催日の型をdate型に変換する
    df['date'] = pd.to_datetime(df['date'], format='%Y年%m月%d日')

    # 作成したモデル、予測対象データをエンコードしたオブジェクトのパス
    dir_path = r'C:\Users\sakur\Google ドライブ\競馬AI\trainData_2022_2022_20221201_131639'

    # 作成したモデルを読み込む
    gbm = joblib.load(dir_path + '\gbm.pkl')

    # 予測対象データのエンコード
    oe_x = joblib.load(dir_path + '\oe_x.pkl')
    x_test_encoded = oe_x.fit_transform(df)             # Dataframeからndarrayに変わるとカラムがなくなり、
    x_test_encoded = pd.DataFrame(x_test_encoded)       # 特徴量分析で特徴量名がf0,f1,f2,,となるのでndarrayからDataframeに戻す
    x_test_encoded.columns = list(df.columns.values)    # カラムを付ける

    # データをdmatrixに変換する
    dtest = xgb.DMatrix(x_test_encoded)

    # タイムを予測し、予測結果を予測対象レース情報に追加する
    predict_time = gbm.predict(dtest)
    df['predict_time'] = predict_time

    # レース名と開催場所、ラウンドをラベルエンコードする
    df = labelencode_race_location_round(df)

    # レース名_エンコードのユニークを抽出する
    race_encoded_unique_list = df['race_name_encoded'].unique()

    # 予測順位を保存するデータフレームを用意する
    df_predict_eval = pd.DataFrame()

    # 同一レース名があるので、レース名と開催場所、ラウンドでレース結果を絞る
    for i in race_encoded_unique_list:
        df_race = df[df['race_name_encoded'] == i]
        location_encoded_list = df_race['location_encoded'].unique()

        for j in location_encoded_list:
            df_race_location = df_race[df_race['location_encoded'] == j]
            round_encoded_list = df_race['round_encoded'].unique()

            for k in round_encoded_list:
                df_race_location_round = df_race_location[df_race_location['round_encoded'] == k]

                # 該当するデータの有無を確認し、該当データがなければ予測順位の追加処理を飛ばす
                if df_race_location_round.empty:
                    continue

                # 予測順位を追加する
                df_race_location_round_assign_rank = assign_rank(df_race_location_round)

                # 1位,2位,3位を抽出する
                df_predict_rank = df_race_location_round_assign_rank[df_race_location_round_assign_rank['predict_rank'] < 4]
                df_predict_eval = pd.concat([df_predict_eval, df_predict_rank])

    # 列の並び替えと不要な情報を削除する
    drop_list = ['race_name_encoded', 'location_encoded', 'round_encoded', 'age', 'rider_weight',
                 'rider', 'horse_weight', 'weather', 'ground', 'condition']
    df_predict_eval = df_predict_eval.drop(drop_list, axis=1)

    sort_list = ['predict_rank', 'predict_time', 'horse', 'odds', 'popular', 'distance',
                 'date', 'race_name', 'location', 'round']
    df_predict_eval = df_predict_eval.reindex(columns=sort_list)

    # CSVのファイル名に実行日時を付与する
    dt_now = datetime.datetime.now()
    timestamp = dt_now.strftime('%Y%m%d_%H%M%S')
    file_name = timestamp + '_1~3位の順位予測.csv'

    # 1~3位の順位予測の結果をCSVファイルに保存する
    df_predict_eval.to_csv(file_name, encoding='cp932', index=False, errors='ignore')

    # プログラムの実行時間を表示する
    run_time = time.time() - start_time
    print('実行時間:{:.2f}秒'.format(run_time))


# レース名と開催場所、ラウンドをラベルエンコーディング
# 引数:予測結果を追加した予測対象レース情報
# 戻値:レース名、開催場所、ラウンドをラベルエンコードした予測対象レース情報
def labelencode_race_location_round(df):
    le = LabelEncoder()
    race_name_encoded = le.fit_transform(df['race_name'].values)
    df['race_name_encoded'] = race_name_encoded

    # le = LabelEncoder()
    location_encoded = le.fit_transform(df['location'].values)
    df['location_encoded'] = location_encoded

    le = LabelEncoder()
    round_encoded = le.fit_transform(df['round'].values)
    df['round_encoded'] = round_encoded

    return df


# タイムでソートして、予測順位を追加する
# 引数:予測対象レース情報
# 戻値:予測順位を追加した予測対象レース情報
def assign_rank(df):
    # 予測順位を追加する
    df_sort_predict = df.sort_values('predict_time')
    df_sort_predict['predict_rank'] = range(1, len(df_sort_predict.index) + 1)

    return df_sort_predict


if __name__ == "__main__":
    main()

プログラムの補足

補足1
predict_rank.pyを実行するためには、事前にJRA_scraping_raceinfo.pyを実行して「予測対象のレース情報.csv」を生成しておく必要があります。

補足2
predict_rank.pyで使用する作成したモデルのパスを指定する必要があります。パスは33行目の箇所で指定します。

プログラムの実行結果

JRA_scraping_raceinfo.py

<実行結果>

C:\Users\sakur\anaconda3\envs\Web_Scraping\python.exe "C:/Users/sakur/Google ドライブ/Web_Scraping/JRA_scraping_raceinfo.py"

====== WebDriver manager ======
Current google-chrome version is 108.0.5359
Get LATEST chromedriver version for 108.0.5359 google-chrome
Trying to download new driver from https://chromedriver.storage.googleapis.com/108.0.5359.71/chromedriver_win32.zip
Driver has been saved in cache [C:\Users\sakur\.wdm\drivers\chromedriver\win32\108.0.5359.71]
C:\Users\sakur\Google ドライブ\Web_Scraping\JRA_scraping_raceinfo.py:141: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
  browser = webdriver.Chrome(ChromeDriverManager().install())
レース情報の取得を開始します
100%|██████████| 72/72 [00:47<00:00,  1.50it/s]
実行時間:66.61秒

<出力ファイル>
予測対象のレース情報.csv

predict_rank.py

<実行結果>

C:\Users\sakur\anaconda3\envs\predict_race\python.exe "C:/Users/sakur/Google ドライブ/競馬AI/predict_rank.py"
実行時間:0.99秒

<出力ファイル>
yyyymmdd_hhmmss_1~3位の順位予測.csv

<出力ファイルの一部>
赤枠内が順位予測。

次回、試したいこと

今週末(12/10と12/11)のレースについて、順位予測してtwitterに投稿したいと思います。

コメント

  1. たこあたま より:

    たびたびコメント失礼します。
    下記、36行目でロードしているのは⑧で作成したモデルファイル化と思うのですが、
    39行目のoe_x.pklはなにをロードさせているのでしょうか?
    ===========
    36: gbm = joblib.load(dir_path + ‘\gbm.pkl’)
    37:
    38: # 予測対象データのエンコード
    39: oe_x = joblib.load(dir_path + ‘\oe_x.pkl’)
    ===========
    よろしくお願いいたします

    • sakurater より:

      質問していただくことで、私自身の振り返りと学びにも繋がります。
      遠慮無く質問してください。

      ・oe_x.pklはLabelEncoderを用いてラベルエンコードしたモデルを保存したファイルです。
      競馬予想AIの作成⑧(AIの的中率を算出)で提示した「make_model.py」を実行すると生成されます。
      ・ラベルエンコードは、各特徴量(レース結果の各データ)を数値に変換するための処理です。
      ・LabelEncoderが各特徴量(レース結果の各データ)のカテゴリを整数に変換した情報を保存します。
      ・レースを予測する際、取得したレース情報はoe_x.pklに従ってラベルエンコードします。
      ・モデル作成時のoe_x.pklを読み込んでおかないと、作成したモデルでレース結果を正しく予測することができません。

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