0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

競馬予想AIを作りたい(AI学習編1)

Last updated at Posted at 2024-06-21

はじめに

前回の記事で収集したデータを基に、1位になる馬の番号を予想させる。
上記記事にも書いたが、馬柱が記録され始めたのが2007年の後半からなので、今回の挑戦では2008年以降のデータのみ使用する。

要約

最終的な精度は、学習用データで35%程度、テスト用データでは20%程度と結構低い。
学習時には過学習の傾向も見られたので、色々と見直しが必要かも。
過学習の要因を考えると、馬柱が埋まっていないレースが多いことが原因の可能性があるので、その辺を考慮した学習データに整理して再び検証してみる予定。

今回のアプローチ

とりあえずディープラーニング使って1位を予想させればええやろガハハ

以下の2つを試した。

  1. DNNで予想
  2. CNNで予想

まずは、入力データを単純に一直線に並べてDNNに入力して精度を評価してみる。
その後、入力データそのまま(2次元構造)をCNNに入力して精度を評価する。

1.DNNで予想

DNNの構造は以下のプログラム。
損失関数はCategoricalCrossentropy
最適化関数はAdam(learning_rate=0.0001, beta_1=0.5, beta_2=0.999)

def CreateModel():
    inputs = Input(shape=(18 * 9,))
    dense = Dense(512, activation="relu")(inputs)
    dense = Dense(256, activation="relu")(dense)
    dense = Dense(128, activation="relu")(dense)
    dense = Dense(64, activation="relu")(dense)
    outputs = Dense(18, activation="softmax")(dense)

    return inputs, outputs

これで学習させた結果が以下のグラフ。

  • lossの変化
    loss_keras.png

  • accの変化
    acc_keras.png

とても分かりやすく過学習してる。
今回のデータの入力形式は、単純に一直線に並べただけなので、その影響もあるかもしれない。

2.CNNで予想

kerasでは何故かCNNが動かなかったのでpytorchに変えて実験。

CNNの構造は以下のプログラム。
損失関数はnn.CrossEntropyLoss
最適化関数はAdam(model.parameters(), lr=0.001, betas=(0.5, 0.999))

def __init__(self):
    super(Model2d, self).__init__()
    bias = True
    
    self.input = nn.Sequential(
        nn.Conv2d(in_channels=1,
                  out_channels=32,
                  kernel_size=(1, 1),
                  padding=(0, 0),
                  stride=(1, 1),
                  bias=bias),
        nn.ReLU(),
    )
    
    self.hidden = nn.Sequential(
        nn.Conv2d(in_channels=32,
                  out_channels=32,
                  kernel_size=(3, 3),
                  padding=(1, 1),
                  stride=(1, 1),
                  bias=bias),
        nn.Dropout(0.2),
        nn.ReLU(),
    
        nn.Conv2d(in_channels=32,
                  out_channels=64,
                  kernel_size=(3, 3),
                  padding=(1, 1),
                  stride=(1, 1),
                  bias=bias),
        nn.Dropout(0.2),
        nn.ReLU(),
    
        nn.Conv2d(in_channels=64,
                  out_channels=64,
                  kernel_size=(3, 3),
                  padding=(1, 1),
                  stride=(1, 1),
                  bias=bias),
        nn.Dropout(0.2),
        nn.ReLU(),
    )
    
    self.output = nn.Sequential(
        nn.Conv2d(in_channels=64,
                  out_channels=1,
                  kernel_size=(1, 1),
                  padding=(0, 0),
                  stride=(1, 1),
                  bias=bias),
        nn.Flatten(),
        nn.Linear(18 * 9, 128),
        nn.ReLU(),
        nn.Linear(128, 64),
        nn.ReLU(),
        nn.Linear(64, 18),
    )

def forward(self, x):
    input = self.input(x)
    middle = self.hidden(input)
    output = self.output(middle)
    return output

これで学習させた結果が以下の2つのグラフ。
過学習の気配があるので60epoch程度で中断した。

  • lossの変化
    loss_torch.png

  • Accuracyの変化
    acc_torch.png

CNNを使う場合でも、やはり学習時はlossが下がり続け、accが上がり続ける結果となった。
傾向はDNNと似たような感じである。
学習時のlossは順調に下り続けるが、テスト時は、最初は減少傾向で途中から上がり始める。
accは、学習時は順調に上がり続け、テスト時は早々に頭打ちになる。
めちゃくちゃ過学習してそう。

要因分析

現時点での仮説は以下のとおり。

  • 勝つ馬の番号が偏っている
  • 馬柱がちゃんと埋まっているデータが2割くらいしか無い

勝つ馬の番号が偏っている

2008年~2022年の中央競馬で、1位になった馬の番号を集計したのが以下の棒グラフ。
左から順に1番、2番、……、18番。
縦軸はレース数。

win_bar.png

割合にしたのが以下の表。

馬番 勝率(%)
1 7
2 7
3 7
4 8
5 7
6 7
7 7
8 7
9 7
10 7
11 6
12 6
13 5
14 4
15 3
16 3
17 0
18 0

という感じで、ある馬番に偏ってるわけではなさそう。(すごい)
なお、後ろの番号ほど割合が減っているのは、単純に少ない頭立てのレースが多いから。
頭立て数の影響もあるだろうが、こんだけ綺麗に分布してるなら影響力は弱い気がする。

よって、「勝つ馬の番号が偏っている」という仮説は否定された。

馬柱が埋まっているデータが2割程度

2008年~2022年のデータのレース数は51808。
そのうち、馬柱が5枠全て埋まっていたレースは11615。
割合としては約22.4%となる。

2023年に開催されたレース数は3400。
そのうち、馬柱が5枠全て埋まっていたレースは707。
割合としては約20.8%。

よって、この仮説は正しそう。
馬柱がちゃんと埋まっているレースであれば高い割合で予想できる可能性がある。

結論

2008年~2022年の中央競馬の全レースのデータを使った場合、予想精度がかなり低く、過学習してそうな気配があった。
その要因を分析したところ、馬柱のデータがちゃんと埋まっているレースについては正しく予想できている可能性が浮上した。
今後はそのデータだけを使って分析できるか試す予定。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?