競馬予想プログラミングに関する記事を「投稿まとめ」で一覧にしてます。この記事は「自動投票」の一覧に含まれてます。一覧の順に読むとステップごとで分かりやすいです。
【伍ノ型】自動投票で条件ごとに異なる機械学習モデルを使う
【伍ノ型】は【肆ノ型】の派生になります。したがって【伍ノ型】を習得するには、【肆ノ型】を先に習得してください。
【肆ノ型】で伝授した方法だけでは、自動投票の機械学習モデルは、常に同じモデルを使うしかありませんでした。この記事では、何らかの条件ごとに異なるモデルを使う方法を説明します。
【伍ノ型】はモデルのファイルを指定する「モデル読み込み」の部分の予測用ソースコードを修正するだけなので、二値分類とかランキング学習とか、データの分析方法は関係なく全て共通です。
競馬場ごとに異なるモデルを使う
競馬場ごとに異なるモデルを使いたい場合は、ファイル名である引数のレースID(※1)に含まれる競馬場コードを使います。これは予測用ソースコードを修正すれば実現できます。
(※1)レースID | 年月日場R yyyymmddjjrr(12桁) |
---|
予測用ソースコード修正前
# モデル読み込み
bst = lgb.Booster(model_file='lambdarank_model.txt')
予測用ソースコード修正後
# 競馬場コード取得
jj = fname[8:10]
# モデル読み込み
bst = lgb.Booster(model_file='lambdarank_model_' + jj + '.txt')
見ての通り、引数のレースID(fname)から競馬場コードを取得して、ファイル名を変数で設定して、競馬場ごとのモデルが指定できるようにすればOK。もちろん、競馬場ごとのモデルを先に準備しておく必要があります。上記のソースコードだと、競馬場ごとのモデルのファイル名は以下のようにしておきます。
- 札幌モデル → lambdarank_model_01.txt
- 函館モデル → lambdarank_model_02.txt
- (…省略)
- 阪神モデル → lambdarank_model_09.txt
- 小倉モデル → lambdarank_model_10.txt
ちなみに、競馬場ごとのモデルを作るときは学習用ソースコードで指定しているファイル名を毎回修正するのではなく、出力されたファイル名を修正したほうが効率的です。今回の例ではファイル名を、”lambdarank_model_” + 競馬場コード + “.txt” としてますが、ユーザーの好みで決めてもOKです。
競走条件ごとに異なるモデルを使う
PythonでPostgreSQLに接続する
競馬場コードは引数のレースID(※1)から簡単に取得できます。しかし他の情報、例えばトラックコードや競走条件コードなどが必要な場合は、PostgreSQLに接続して「レース詳細」テーブルから目的の情報を取得する必要があります。
PythonでPostgreSQLに接続するには、事前に「ドライバ」と呼ばれる部品をインストールする必要があります。
psycopg2のインストール
Python用のPostgreSQLドライバはいくつかありますが、ここでは最も多くダウンロードされている「psycopg2」を紹介します。インストールは「LightGBMによるAI競馬予想(準備編)」の記事で紹介している方法と同じです。コマンドプロンプトに、以下のコマンドを入力して実行してください。
py -m pip install psycopg2
これでPythonでPostgreSQLに接続する準備ができました。
競走条件ごとに異なるモデルを使う
次は、競走条件ごとに異なるモデルを使う方法を説明します。モデルを、
- 新馬戦
- 未勝利戦
- 上記以外の条件戦
で、3つ作った場合とします。まず、予測用ソースコードの一番上にimportの宣言を追記します。
import psycopg2
次に、予測用ソースコードを以下のように修正します。検索結果の取得には、既存のサンプルのソースコードで使ってる「pandas」の「read_sql」メソッドを使ってます。
予測用ソースコード修正前
# モデル読み込み
bst = lgb.Booster(model_file='lambdarank_model.txt')
予測用ソースコード修正後
# データベースに接続します
config = {
'host': '127.0.0.1',
'port': '5432',
'database': 'pckeiba',
'user': 'postgres',
'password': 'postgres'
}
con = psycopg2.connect(**config)
# SQLを作成します
yyyy = fname[0:4]
mmdd = fname[4:8]
jj = fname[8:10]
rr = fname[10:12]
where = ''
where += ' WHERE 1 = 1'
where += f' AND ra.kaisai_nen = \'{yyyy}\''
where += f' AND ra.kaisai_tsukihi = \'{mmdd}\''
where += f' AND ra.keibajo_code = \'{jj}\''
where += f' AND ra.race_bango = \'{rr}\''
sql = ''
sql += ' SELECT * FROM jvd_ra ra'
sql += where
sql += ' UNION ALL'
sql += ' SELECT * FROM nvd_ra ra'
sql += where
# SQLを実行します
df = pd.read_sql(sql=sql, con=con)
# データベース接続を閉じます
con.close()
# 行インデックス, 列名 で任意の値を取得します
value = df.loc[0, 'kyoso_joken_code']
if value == '701':
# 新馬戦
model_file = 'lambdarank_model_701.txt'
elif value == '703':
# 未勝利戦
model_file = 'lambdarank_model_703.txt'
else:
# 上記以外の条件戦
model_file = 'lambdarank_model_999.txt'
# モデル読み込み
bst = lgb.Booster(model_file=model_file)
PostgreSQLから任意の値を取得したら、あとはPythonでIF文を使って競走条件ごとにモデルのファイル名を指定すればOK。あるいはSQLのCASE式でコードを編集しておいて、前章の競馬場コードようにファイル名を変数で設定してもOK。
条件分岐をPythonでやるか、SQLでやるか、どちらが良いかは状況次第ですが、判断基準の1つとしてステップ数(ソースコードの行数)の少なさを優先すれば良いと思います。理由は、ステップ数の少ないほうがバグが出る可能性が低いからです。
予測テーブルは同じテーブルを使う
異なる条件ごとに異なるモデルを使う場合に注意すべきことは、予測テーブルのテーブル定義は統一する必要があるということです。学習データとモデルをそのように設計してください。例えば「LightGBMによるAI競馬予想(準備編)」の記事にある学習データのサンプルを使うとすれば、以下のような感じになります。
説明変数 | 条件戦 xxxxxxxx | 未勝利戦 xxxxxxxx | 新馬戦 xxxxxxxx |
JRA-VANタイム型DM | ◯ | ◯ | ◯ |
馬体重 | ◯ | ◯ | ◯ |
1〜2走前 確定着順 | ◯ | ◯ | ▲ |
1〜2走前 4角順位 | ◯ | ◯ | ▲ |
1〜2走前 単勝人気順 | ◯ | ◯ | ▲ |
1〜2走前 後半3F順位 | ◯ | ◯ | ▲ |
1〜2走前 タイム差 | ◯ | ◯ | ▲ |
【目的変数】確定着順 | ◯ | ◯ | ◯ |
条件戦と未勝利戦では過去走データが重要である一方、新馬戦にはそのデータが存在しません。この場合、新馬戦のモデルにも過去走データの項目を追加し、数値の”0″とかテキトーな初期値を設定した学習データでモデルを作ってください。◯は設定、▲にはテキトーな初期値です。
あるいは、新馬戦は購入の対象外にするという方法も検討してください。
自動投票のテストを実行する
「自動投票を実行する(テスト)」の記事を参考に、テストを実施します。
「自動投票実行(本番)」は「自動投票実行(テスト)」をバッチリ行ってから実行してください。
以上で【伍ノ型】の伝授は終わりです。