Press "Enter" to skip to content

“我如何使用机器学习在意大利幻想足球中取得胜利⚽”

Dall-E图片

通过人工智能揭开Fantacalcio的密码

作为一名对编程和计算机科学有浓厚兴趣的机械工程师,几年前我对机器学习和人工智能的世界产生了浓厚的兴趣。我认识到它们在各种工程学科中的潜力,于是开始了学习机器学习的旅程。然而,尽管我掌握了理论知识,但我很难找到实际应用和实践这些新技能的途径。尽管有现成的数据集可用,但它们并不能提供完整的数据收集和处理体验。于是,一个念头出现在我脑海中:为什么不将机器学习应用于帮助我在幻想足球比赛中取胜呢?

Fantacalcio简介

来源:Fantacalcio

Fantacalcio是意大利足球迷中非常受欢迎的游戏。参与者根据意大利顶级足球联赛Serie A中球员的表现,组建球队并在整个赛季中进行竞争。在赛季开始之前,参与者进行一次拍卖,以选秀超过20名球员。每个Serie A比赛日结束后,球员根据他们的表现得到评分,进球和助攻还有额外的奖励分。这些累积的评分和奖励分决定了参与者的得分。游戏的一个关键方面是选择每周的首发阵容,并决定哪些球员常规上场,哪些球员替补。

我的工作目标

我的机器学习算法的主要目标是根据球队的比赛来预测Serie A球员的评分和fanta-vote(评分加奖励分)。足球是一项不确定的运动,因为无法保证一个球员是否能得分。然而,某些球员与其他球员相比,更有可能得分,并且他们的表现可能会受到他们所面对的球队的影响。我的目标是找到一种客观的方法,以确定在任何给定的Serie A比赛日上,哪个球员有更高的概率提供更强的表现。

免责声明:本文将使用此类部分提供来自Fantacalcio的真实案例,以说明讨论的概念。如果您对这个游戏或Serie A球员不熟悉,可以跳过这些部分。

算法预测Fantacalcio阵容中球员表现的结果预览。作者:作者的图片。

收集和处理数据

一旦我下载了Fantacalcio的评分档案,下一步就是收集一套全面的特征,用于训练机器学习算法。为了构建这个数据集,我发现<stron

显示一些可用团队统计数据的表格。来源:FBref。

我采取的方法是构建一个数据集,其中每个球员有50多个特征。这个数据集将球员的平均统计数据与他们所在球队的统计数据以及对手球队在某个比赛日的统计数据合并在一起。数据集的每一行的目标输出是球员的得票和幻想得票。为了构建数据集,我考虑了意甲过去三个赛季的数据。

为了解决赛季中上场时间有限的球员统计数据不可靠的问题,我采用了三种策略:

  1. 用上个赛季的统计数据进行加权平均。
  2. 在没有可靠的历史数据的情况下,将球员的统计数据与类似角色的平均球员的数据进行平均。
  3. 我使用预定义的列表,将球员的统计数据部分平均化,与之前扮演类似角色的同一球队的前任球员的数据进行平均。

例如,对那不勒斯的新秀金的表现可以与前任球员库利巴利的表现进行比较,或者可以将托万的表现与他的前任德乌洛费进行评估(但这后来被证明是不正确的)。

表示每个数据集行的图表。球员的得票和幻想得票是目标输出,而所有其他统计数据和主场因素都被合并到特征集中。作者提供的图像。

算法的定义和训练

为了使事情更有趣,结果更易于可视化,机器学习算法被设计为超越简单的得票和幻想得票预测。相反,采用了一种概率性方法,利用TensorFlow和TensorFlow Probability构建了一个能够生成概率分布的神经网络。具体而言,该网络预测了sine-arcsine概率分布的参数。这种选择是为了考虑到球员表现得分分布的固有偏斜。例如,在进攻球员的情况下,尽管他们的平均幻想得票可能在6.5左右,但算法认识到得票为10(表示出色的表现,如进球)的可能性比得票为4(代表罕见的低迷表现)更大。

不同参数的Sinh-Arcsinh概率分布图。来源:ResearchGate。

用于此任务的深度神经网络架构包括多个稠密层,每个层都使用sigmoid激活函数。为了防止过拟合和提高泛化能力,采用了正则化技术,如Dropout和Early Stopping。Dropout在训练过程中随机关闭一部分神经网络单元,而Early Stopping则在验证损失不再改善时停止训练过程。训练模型选择的损失函数是负对数似然,它衡量预测的概率分布与实际结果之间的差异。

下面是构建神经网络的代码片段:

callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 10)neg_log_likelihood = lambda x, rv_x: -rv_x.log_prob(x)inputs = tfk.layers.Input(shape=(X_len,), name="input")x = tfk.layers.Dropout(0.2)(inputs)x = tfk.layers.Dense(16, activation="relu") (x)x = tfk.layers.Dropout(0.2)(x)x = tfk.layers.Dense(16, activation="relu") (x)prob_dist_params = 4def prob_dist(t):     return tfp.distributions.SinhArcsinh(loc=t[..., 0], scale=1e-3 + tf.math.softplus(t[..., 1]), skewness = t[..., 2],                                         tailweight = tailweight_min + tailweight_range * tf.math.sigmoid(t[..., 3]),                                        allow_nan_stats = False)x1 = tfk.layers.Dense(8, activation="sigmoid")(x)x1 = tfk.layers.Dense(prob_dist_params, activation="linear")(x1)out_1 = tfp.layers.DistributionLambda(prob_dist)(x1)x2 = tfk.layers.Dense(8, activation="sigmoid")(x)x2 = tfk.layers.Dense(prob_dist_params, activation="linear")(x2)out_2 = tfp.layers.DistributionLambda(prob_dist)(x2)modelb = tf.keras.Model(inputs, [out_1, out_2])modelb.compile(optimizer=tf.keras.optimizers.Nadam(learning_rate = 0.001),               loss=neg_log_likelihood)modelb.fit(X_train.astype('float32'), [y_train[:, 0].astype('float32'), y_train[:, 1].astype('float32')],               validation_data = (X_test.astype('float32'), [y_test[:, 0].astype('float32'), y_test[:, 1].astype('

利用神经网络进行预测

经过训练的算法为球员的投票和梦幻投票提供了概率分布预测。通过考虑球员的平均统计数据、球队信息、对手数据以及主/客场因素,它能够预测球员未来意甲比赛的表现。通过对概率分布进行后处理,可以得出预期的数值投票预测和最大潜在投票,简化Fantacalcio阵容选择的决策过程。

以蓝色显示球员投票,以绿色显示梦幻投票的概率分布图。图片作者提供。

利用蒙特卡洛技术,每个球员的概率分布被用于预测阵容的预期总投票。蒙特卡洛方法涉及运行多个随机模拟以估计潜在结果。就是这样!我拥有了所有的工具,可以在每个意甲比赛日为我的Fantacalcio阵容选择最佳阵容。

通过蒙特卡洛模拟获得的阵容得分概率分布图。图片作者提供。

算法成功的地方

作为一个额外的指标,我将预期投票与我的主观期望进行了比较,结果令人满意。该算法在“Mantra” Fantacalcio变体中表现出色,该变体涉及球员扮演类似真实足球的多个角色,从中后卫和边后卫到边锋和前锋不等。从可用模块中选择最佳阵容提出了一个复杂的挑战,因为并不总是进攻球员胜过防守球员。

此外,通过使用算法来预测选择一支统计上平均的意甲球队作为对手,它在准备一月份的市场拍卖时非常有用。它使我能够识别被大众观点低估的被低估球员。

埃尔·沙拉维和奥索里尼等球员是意甲赛季后期表现出色的明显例子。该算法预测到他们的预期表现与其他顶级中场球员相当,甚至在一月份就已经达到了这个水平。

表格显示了在某个意甲比赛日为Fantacalcio阵容生成的投票预测。图片作者提供。

算法的失败或改进之处

该算法在预测守门员表现方面的弱点在于它的表现。开发了一个单独的神经网络,利用不同的特征,并将不失球概率作为输出。然而,结果并不令人满意,可能是由于守门员数量有限(每队只有一个)与场上球员相比。这导致数据集的多样性较低,增加了过拟合的风险。

此外,该算法仅考虑了每个球员在整个赛季中的平均统计数据。虽然这种方法已经足够,但是加入球员在某个比赛日之前两三场比赛的数据,可以增强算法对他们当前状态的考虑能力。这将提供对球员最近表现的更全面的评估。

所有工作都公开

你可以在Github上找到为这个项目编写的代码,以及为几个意甲比赛日生成的结果。我计划在时间允许的情况下进一步改进下个赛季的工作。如果你有任何问题或需要澄清,欢迎联系我。

Leave a Reply

Your email address will not be published. Required fields are marked *