自動投票の作り方【伍ノ型】

プログラミング

競艇予想プログラミングに関する記事を「投稿まとめ」で一覧にしてます。この記事は「自動投票」の一覧に含まれてます。一覧の順に読むとステップごとで分かりやすいです。

【伍ノ型】自動投票で条件ごとに異なる機械学習モデルを使う

【伍ノ型】は【肆ノ型】の派生になります。したがって【伍ノ型】を習得するには、【肆ノ型】を先に習得してください。

【肆ノ型】で伝授した方法だけでは、自動投票の機械学習モデルは、常に同じモデルを使うしかありませんでした。この記事では、何らかの条件ごとに異なるモデルを使う方法を説明します。

【伍ノ型】はモデルのファイルを指定する「モデル読み込み」の部分の予測用ソースコードを修正するだけなので、二値分類とかランキング学習とか、データの分析方法は関係なく全て共通です。

競艇場ごとに異なるモデルを使う

競艇場ごとに異なるモデルを使いたい場合は、ファイル名である引数のレース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_23.txt
  • 大村モデル → lambdarank_model_24.txt

ちなみに、競艇場ごとのモデルを作るときは学習用ソースコードで指定しているファイル名を毎回修正するのではなく、出力されたファイル名を修正したほうが効率的です。今回の例ではファイル名を、”lambdarank_model_” + 競艇場コード + “.txt” としてますが、ユーザーの好みで決めてもOKです。

進入固定競走で異なるモデルを使う

PythonでPostgreSQLに接続する

競艇場コードは引数のレースID(※1)から簡単に取得できます。しかし他の情報、例えば進入固定競走のフラグなどが必要な場合は、PostgreSQLに接続して「出走表(レースNo)」テーブルから目的の情報を取得する必要があります。

PythonでPostgreSQLに接続するには、事前に「ドライバ」と呼ばれる部品をインストールする必要があります。

psycopg2のインストール

Python用のPostgreSQLドライバはいくつかありますが、ここでは最も多くダウンロードされている「psycopg2」を紹介します。インストールは「LightGBMによるAI競艇予想(準備編)」の記事で紹介している方法と同じです。コマンドプロンプトに、以下のコマンドを入力して実行してください。

py -m pip install psycopg2

これでPythonでPostgreSQLに接続する準備ができました。

進入固定競走で異なるモデルを使う

次は、進入固定競走で異なるモデルを使う方法を説明します。モデルを、

  1. 進入固定
  2. 進入固定以外

で、2つ作った場合とします。まず、予測用ソースコードの一番上にimportの宣言を追記します。

import psycopg2

次に、予測用ソースコードを以下のように修正します。検索結果の取得には、既存のサンプルのソースコードで使ってる「pandas」の「read_sql」メソッドを使ってます。

予測用ソースコード修正前

# モデル読み込み
bst = lgb.Booster(model_file='lambdarank_model.txt')

予測用ソースコード修正後

# データベースに接続します
config = {
    'host': '127.0.0.1',
    'port': '5432',
    'database': 'pckyotei',
    '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]

sql = ''
sql += ' SELECT * FROM brd_l2 l2'
sql += ' WHERE 1 = 1'
sql += f' AND l2.kaisai_nen = \'{yyyy}\''
sql += f' AND l2.kaisai_tsukihi = \'{mmdd}\''
sql += f' AND l2.kyoteijo_code = \'{jj}\''
sql += f' AND l2.race_no = \'{rr}\''

# SQLを実行します
df = pd.read_sql(sql=sql, con=con)

# データベース接続を閉じます
con.close()

# 行インデックス, 列名 で任意の値を取得します
value = df.loc[0, 'shinnyukotei']

if value == '1':
    # 進入固定
    model_file = 'lambdarank_model_1.txt'
else:
    # 進入固定以外
    model_file = 'lambdarank_model_0.txt'

# モデル読み込み
bst = lgb.Booster(model_file=model_file)

PostgreSQLから任意の値を取得したら、あとはPythonでIF文を使って進入固定競走のモデルのファイル名を指定すればOK。あるいはSQLのCASE式でコードを編集しておいて、前章の競艇場コードようにファイル名を変数で設定してもOK。

条件分岐をPythonでやるか、SQLでやるか、どちらが良いかは状況次第ですが、判断基準の1つとしてステップ数(ソースコードの行数)の少なさを優先すれば良いと思います。理由は、ステップ数の少ないほうがバグが出る可能性が低いからです。

予測テーブルは同じテーブルを使う

異なる条件ごとに異なるモデルを使う場合に注意すべきことは、予測テーブルのテーブル定義は統一する必要があるということです。学習データとモデルをそのように設計してください。例えば「オリジナル展示タイム」を使うとすれば、以下のような感じになります。

説明変数桐生
xxxxxxxx
戸田
xxxxxxxx
江戸川
xxxxxxxx
展示タイム
半周
一周
まわり足
直線
【目的変数】着順
※ヘッダの’x’はレイアウト調整が目的の文字です

桐生と戸田にはオリジナル展示タイムが存在する一方、江戸川にはそのデータが存在しません。この場合、江戸川のモデルにもオリジナル展示タイムの項目を追加し、数値の”0″とかテキトーな初期値を設定した学習データでモデルを作ってください。◯は設定、▲にはテキトーな初期値です。

あるいは、江戸川は購入の対象外にするという方法も検討してください。

自動投票のテストを実行する

自動投票を実行する(テスト)」の記事を参考に、テストを実施します。

「自動投票実行(本番)」は「自動投票実行(テスト)」をバッチリ行ってから実行してください。

以上で【伍ノ型】の伝授は終わりです。

「投稿まとめ」にもどる