競艇AI開発日記 第30話|特徴量探索を止めてVer.1を作る

前回、いろいろな特徴量を試してきた結果、これ以上複雑にしていくよりも、まずはシンプルなAIを作ってみることにしました。

ここまでの分析で、「この特徴量を入れれば、かなり良くなりそう」という決定打は見つかっていません。

それなら、いったん特徴量探しを止めて、実際にAIを作って、どこまでできるのか確認してみよう。

そう考えました。

もともと、今回のAIは長期的にモニタリングしていくことも考えていました。

そのため、最初から複雑なものを作るよりも、あとから結果を振り返りやすい、シンプルなAIをVer.1のコンセプトにすることにしました。

ただし、ここでいう「シンプル」は、適当に作るという意味ではありません。

今回は、「何を残して、何を捨てるか」を決めたうえで、あえて範囲を絞ることにしました。

まず「何を予測するAIなのか」を決める

今回のAIが予測するのは、**「イン逃げ有利・不利」**です。

ここは、これまでの開発で考えてきたことから変えません。

今回のAIでは、

  • 1号艇が1着になるか
  • どの外艇が攻めるのか
  • 3連単の買い目は何か

といったところまで直接予測するわけではありません。

あくまで、「このレースはイン逃げにとって有利なのか、不利なのか」をAIに判断してもらいます。

そして、その結果を既存の予想ロジックに組み合わせる。

つまり、AI単体で予想を完成させるのではなく、予想を補助する役割として使うことにしました。

使う特徴量もシンプルにする

ここまで、かなりいろいろなものを調べてきました。

平均ST、標準偏差、ST差、STの分布、選手同士の相関、グループ内の連動性、スロー・ダッシュの関係、1号艇との比較などです。

実際に分析してみると、それぞれに面白い部分はありました。

ただ、「これを入れれば明らかに良くなる」と言える特徴量は見つかりませんでした。

そこで、今回は新しい特徴量をさらに探し続けるのではなく、これまで中心的に使ってきた平均STをベースにすることにしました。

「結局、何が一番使えそうなのか」と考えたとき、平均ST以外に決定的なものが見つかっていなかったからです。

平均STに「中央値」を加える

Ver.1で使う特徴量は、

6艇それぞれの平均STと中央値

です。

つまり、

  • 1号艇:平均ST・中央値
  • 2号艇:平均ST・中央値
  • 3号艇:平均ST・中央値
  • 4号艇:平均ST・中央値
  • 5号艇:平均ST・中央値
  • 6号艇:平均ST・中央値

という、合計12個の特徴量です。

標準偏差も候補にはありました。

ただ、選手×コースによってはデータ数が十分ではなく、標準偏差を使うことに難しさがありました。

そこで今回は中央値を加えることにしました。

中央値そのものがSTの「ばらつき」を直接表すわけではありません。

それでも、平均値だけではなく、もう一つ中心を表す値を入れることで、STの情報を少しでも残しておきたかったからです。

まずは、このくらいシンプルな構成で試してみます。

データが足りないレースは予測しない

今回、もう一つ決めたことがあります。

必要な特徴量を作れないレースは、無理に予測しないということです。

12個の特徴量のうち、どれか一つでも作れない場合、そのレースはVer.1の検証対象から外します。

理由は二つあります。

一つは、長期モニタリングをしたときに、結果を振り返りやすくするためです。

もう一つは、そもそも判断材料が不足しているレースで舟券を買うことは避けたい、という考え方です。

AIに無理やり予測させるのではなく、

判断材料が足りないなら、今回は見送る。

という考え方にしました。

一番気をつけたのは「未来を見ない」こと

今回のAIを作るうえで、特に気をつけたのがデータリークです。

AIが未来のデータを見てしまった状態で検証すると、本来より良い結果が出てしまいます。

それでは、実際に未来のレースを予測するときの状態を再現できません。

そこで今回は、データを時系列に沿って追加していく方法にしました。

例えば4月22日のレースを予測するときは、4月21日までのデータだけを使います。

そして4月22日のレースが終わったら、その日の実際のSTを過去データに追加する。

次の4月23日の予測では、4月22日までのデータを使う。

このように、

予測する → 実際の結果が出る → データを追加する → 次のレースを予測する

という流れにします。

とにかく、過去データと未来データのリークを避ける。

ここは今回のVer.1でかなり重要なポイントです。

学習期間とテスト期間も時間で分ける

検証もランダムにデータを分けるのではなく、時間で分けます。

学習期間は、

2026年4月22日〜6月30日

テスト期間は、

2026年7月1日〜8月11日

です。

過去のデータで学習して、その後の期間のデータでテストする形です。

実際に運用するときも、未来のレースは当然まだ分かりません。

そのため、今回の検証もできるだけ実際の使い方に近づけたいと考えました。

「イン逃げ有利・不利」の定義も変えない

AIに教える正解ラベルについても、今回のVer.1では変更しません。

これまで検証してきた、

「外側の艇が、1号艇以外の内側の艇より0.05秒以上速く、なおかつ1号艇以上のSTだった場合、イン逃げ不利」

というルールを使います。

それ以外は「イン逃げ有利」とします。

判定に必要なSTがないレースについては、対象外です。

ここでラベルの定義まで変えてしまうと、これまでの分析結果と比較しにくくなります。

今回は、まずこの定義を固定した状態でAIを作ることにしました。

AIのモデルはRandom Forest

AIのモデルにはRandom Forestを使います。

ここは、自分だけで選んだわけではありません。

AIに今回の目的やデータについて相談すると、いくつかのモデル候補を説明してくれました。

正直、素人なのでモデルごとの細かい違いまでは十分に理解できていません。

その中で、AIから説明を受けたうえで、今回はRandom Forestを使ってみることにしました。

Ver.1では、ここでモデルの種類やパラメータを大量に試すこともしません。

まずは一つのモデルで、決めた仕様を最後まで動かしてみます。

評価方法もAIに相談して決めた

AIの評価についても、Accuracyだけを見ることにはしません。

今回は、

  • Accuracy
  • Precision
  • Recall
  • F1
  • Macro F1
  • ROC-AUC
  • 混同行列
  • 多数派クラスを予測するだけのベースライン

などを確認します。

これも、自分が最初から全部知っていたわけではありません。

AIに「どう評価すればいいのか」を相談して、それぞれの指標が何を見るためのものなのかを説明してもらいました。

そのうえで、複数の指標を見ることにしました。

AIの精度が最終目標ではない

ここは、今回かなり大事にしたところです。

もちろん、スリット予測AIとしての精度は重要です。

ただ、自分が最終的にやりたいのは、スリット予測AIの精度を最大まで高めることではありません。

最終的な目的は、予想全体の回収率を良くすることです。

例えば、AIの分類精度が高くても、それを予想に組み込んだ結果として回収率が変わらなければ、自分にとっては十分な成果とは言えません。

逆に、スリット予測AIとしての精度をひたすら追求しなくても、その予測を使うことで目標としている回収率につながるのであれば、それでいいと考えています。

つまり、

「スリット予測AIとして何点取れるか」だけを見るのではなく、「その予測を使った結果、予想全体がどう変わるのか」を見る。

ということです。

これは、以前の第21話で「スタートを当てるAI」から「予想に使うAI」へ考え方を変えたことにもつながっています。

最終的には「AIを入れたらどうなるか」を見る

そこで、最終的な検証では二つを比較します。

A:これまでの予想ロジックだけ

B:これまでの予想ロジック+Ver.1のAI

既存の予想ロジック自体は変更しません。

そこにVer.1のAIを加えて、

  • 1号艇を頭にする
  • 1号艇を頭から外す

という既存の判断に対して、AIの「イン逃げ有利・不利」を組み合わせます。

AIを入れたことで、最終的な回収率などにどんな変化が出るのか。

ここを確認します。

Ver.1では、あえてやらないことも決めた

今回、やらないこともかなり明確にしました。

Ver.1では、

  • 12種類のスリットパターン予測
  • 攻める外艇の予測
  • 外艇の1着確率予測
  • 新しい相対ST特徴量の追加
  • 選手のサンプル数の追加
  • クラス不均衡への対応
  • テストデータを使った予測閾値の最適化
  • 大規模なハイパーパラメータ探索

などは行いません。

これまで分析してきた内容を全部AIに詰め込むのではなく、いったん範囲を絞ります。

ここでまた「もっと良い特徴量があるかもしれない」と探し始めると、いつまでもAIを作れません。

今回は、

仕様を決める → AIを作る → 未知のデータで検証する

ところまで進めることを優先します。

これでどうなるのか、見てみたい

ここまでいろいろな分析をしてきました。

平均STを調べたり、標準偏差を調べたり、ST差を見たり、選手同士の連動性を調べたりしました。

それぞれに発見はありましたが、分析だけでは、実際にAIを作ったときにどうなるのかは分かりません。

だから、ここからは実際に作ってみます。

正直なところ、仕様を決め終わったときの感覚は、

「これでどうなるか見てみたい」

というものでした。

これまで考えてきたことが、実際のAIにするとどんな結果になるのか。

過去のデータだけを使って学習し、その後の未知のデータに予測させる。

そして、その結果を確認する。

まずは、それをやってみたいと思いました。

ここから、Ver.1を実際に動かしてみる

今回のVer.1では、

  • 予測するもの
  • 使う特徴量
  • データが不足した場合の扱い
  • データリークを避ける方法
  • 学習期間とテスト期間
  • 正解ラベル
  • AIモデル
  • 評価方法
  • 最終的に見る指標

まで決めました。

ここから先は、仮説や分析だけではなく、実際の検証結果を見る段階です。

これまでは、

「AIに何を教えればいいのか?」

を探してきました。

ここからは、

「決めた仕様のAIを、未知のデータに当てたらどうなるのか?」

を確認していきます。

まずはVer.1。

これで、どんな結果が出るのかを見てみようと思います。

あわせて読みたい

競艇AI開発日記

← 第29話|グループ全体ではなく1号艇を見る

競艇AI開発日記

競艇AI開発日記 第31話|AIを予想に組み込んだら、回収率が下がった →

コメント

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