【发布时间】:2022-01-21 11:43:03
【问题描述】:
我试图生成一个能够预测足球比赛结果(赢、输、平)的神经网络 (LSTM)。特别是,我试图在this 论文中扩展该算法,使其能够预测平局,而不仅仅是输赢。 训练数据集完全具有第 3 页中描述的列。这些列都已缩放,以便在 0 到 1 的范围内。第 9 列和第 10 列是赢/输/平局编码为 1 2 和 3,列从 11 到18 是二进制值。 我修改了在同一个 github 存储库中创建的网络,结果如下:
import numpy as np
from sklearn.model_selection import train_test_split
from tensorflow import keras
import pandas as pd
# Build the RNN model
def build_model(allow_cudnn_kernel=True):
input_dim = 27
units = 64
output_size = 3 # labels are from Win or Loss
# CuDNN is only available at the layer level, and not at the cell level.
# This means `LSTM(units)` will use the CuDNN kernel,
# while RNN(LSTMCell(units)) will run on non-CuDNN kernel.
if allow_cudnn_kernel:
# The LSTM layer with default options uses CuDNN.
lstm_layer = keras.layers.LSTM(units, input_shape=(input_dim, 1))
else:
# Wrapping a LSTMCell in a RNN layer will not use CuDNN.
lstm_layer = keras.layers.RNN(
keras.layers.LSTMCell(units), input_shape=(input_dim, 1)
)
model = keras.models.Sequential(
[
lstm_layer,
keras.layers.BatchNormalization(),
keras.layers.Dense(output_size),
]
)
return model
def final_model():
batch_size = 64
data = pd.read_csv("onehotencoder/allAtt_onehot_large_train.csv")
dataTrain, dataTest = train_test_split(data, test_size=0.2)
row_count = dataTrain.shape[0]
x_train, y_train = dataTrain.iloc[:, 2:29].values, dataTrain.iloc[:, 29:].values
x_train = np.reshape(x_train, (row_count, 27, 1))
row_count = dataTest.shape[0]
x_test, y_test = dataTest.iloc[:, 2:29].values, dataTest.iloc[:, 29:].values
x_test = np.reshape(x_test, (row_count, 27, 1))
model = build_model(allow_cudnn_kernel=True)
model.compile(
loss=keras.losses.CategoricalCrossentropy(from_logits=True),
optimizer="Adam",
metrics=["categorical_accuracy"],
)
model.fit(
x_train, y_train, validation_data=(x_test, y_test), batch_size=batch_size, epochs=10
)
return model
model = final_model()
然后,我预测了一些结果:
data = pd.read_csv("onehotencoder/allAtt_onehot_large_train.csv")
dataTrain, dataTest = train_test_split(data, test_size=0.2)
x_test, y_test = dataTest.iloc[:, 2:29].values, dataTest.iloc[:, 29:].values
pred = model.predict(x_test)
j = 0
truth = []
correct_win = 0
correct_lose = 0
correct_draw = 0
for i in pred:
if i[0] > i[1] and i[0] > i[2]:
w = 1
elif(i[1] > i[0] and i[1] > i[2]):
w = 0
else:
w = 2 #draw
if y_test[j][0] == 1:
truth.append(1)
elif y_test[j][1] == 1:
truth.append(2)
else:
truth.append(0)
if truth[j] == w:
if w == 1:
correct_win+=1
elif w == -1:
correct_lose+=1
else:
correct_draw+=1
j+=1
print(str(correct_win)+"/"+str(truth.count(1)))
print(str(correct_lose)+"/"+str(truth.count(0)))
print(str(correct_draw)+"/"+str(truth.count(2)))
我保留了 github 存储库中的 cmets,但并不真正了解此模型的工作原理。 用作 y_train 的三列分别代表胜利、失败和平局,只有当事件发生时才应为一列。我认为这是传递输入的好方法。输出是一个列表中的许多数组,每个数组都有一堆数字,我认为这些数字是某种概率,所以我选择了结果预测的最高值。 我也知道,我计算模型性能的方式可能不是最好的,而且我知道我应该使用在训练的任何时候都没有包含的测试数据。但是,我认为它的表现应该比这更好:
160/190 correct wins
0/131 correct lost
16/95 correct draws
模型创建过程中一定有逻辑错误,但我不知道如何解决这个问题。我没有要求任何人为我创建这个模型,但我很想了解哪里出了问题以及是否可以解决这个问题。我知道足球预测的预测非常复杂,但我想有可能比这表现得更好。
【问题讨论】:
-
1.为什么lstm在这里?尝试一个只有几个密集层的 nn 来解决这个分类问题。 2. 你的训练指标是什么意思?你的损失怎么了? 3. 带有 if else if 的 for 循环有点太时髦了 :)
-
我知道循环很糟糕,但是如果还不明显的话,我对 ml 库和 keras 非常缺乏经验。我在网上看到那个人并不是唯一一个使用 lstm 的人,所以我认为这是一个不错的选择。感谢您的帮助@B.Kocis!
-
确保您基本上可以在任何地方使用lstm,这更多是手头问题的问题。尽管如此,查看训练指标总是有帮助的。
-
你能和我分享文件
onehotencoder/allAtt_onehot_large_train.csv,我可以运行它,看看我的输出是什么。另外,我注意到您将数据拆分了两次(一次在模型中,然后再次用于测试/预测)。你不应该那样做(除非你设置一个种子,这样你就得到了完全相同的分裂)。否则,当您做出这些预测时,您可能会将模型训练时使用的一些数据泄露到测试数据集中。 -
然后是的,你的逻辑有缺陷。您将 w 的值返回为 1、0 或 2。但是当计算正确的值时,您会让它寻找 w 为 1 或 -1,(然后是其他)。
标签: python machine-learning keras neural-network prediction