众所周知,尤文图斯需要一座欧冠奖杯,C罗也还想再拿一座欧冠奖杯,为自己的荣誉簙上锦上添花。意甲霸主在意甲虽然风生水起,予取予求,但是在今年欧冠1/8决赛赛场上,被法甲球队里昂所淘汰,痛定思痛,球队解雇了主教练萨里,签约名宿皮尔洛,但是要想在欧冠赛场上夺冠,这还不够,球队还需要什么?没错,需要一名强力中锋,在正印中锋伊瓜因难堪大用的情况下,尤文图斯必须引进一名强力中锋。
现在的问题是,在新赛季即将开始、疫情下球队银根紧缩的背景下,到底谁才是合格的引援人选?本次我们使用基于Python3的factor_analyzer库来对球员进行分析,试图寻找尤文图斯最适合引援的球员。
首先我们来划定范围,先排除掉不可能的签约,比如拜仁的莱万多夫斯基,或者是热刺的哈里凯恩亦或是皇马的哈基姆本泽马,这三人都是世界级中锋,但是由于身价等多种因素导致他们加盟尤文图斯的可能性无限趋近于零。好吧,让我们现实点,巴萨的苏亚雷斯,罗马的哲科以及马竞的莫拉塔才是可能的人选,苏亚雷斯已经和巴萨闹翻,出走几乎是必然。莫拉塔下个赛季也不会出现在卡尔德隆球场,哲科在罗马虽然过得还不错,但是很明显他想要更高的荣誉。
数据分析首先就得有数据,让我们来看看他们三个上赛季的比赛数据。
首先来看看同在西甲的苏亚雷斯和莫拉塔:
这里我们抽取中锋最重要的两项数据,进球数和进球转化率,可以看到在进球数相差4个的情况下,莫拉塔的进球转化率仅为14.5%,落后于苏亚雷斯的19%。
作为中锋,除了进球,还需要一定的策应能力,这样就可以为C罗的后插上提供帮助:
可以看到在策应能力上,莫拉塔也落后于苏亚雷斯,让我们再看看同在意甲的哲科和伊瓜因的数据:
哲科在上个赛季无论是进攻能力还是策应能力都明显强于伊瓜因。
现在我们来抽取一些高阶数据,这里以进球、转换率和助攻作为特征样本,当然了,如果愿意,也可以添加一些别的特征,这里只是简单演示一下,但是需要注意一点,数据建模只有有限的参考价值,因为球员的个人因素如:球员国籍,球员丑闻,球员个人目标定位(或期望值),球员伤病史及严重程度等等,这些都是没有参考数据的。
所以,我们以纯能力数据为核心考量,球员转会身价及年薪这些成本因素不作年化成本计算,理论上也可以说是从主观角度根据转会新闻对此进行判断。同样,球员及所处球队的竞训水平也不作为参考数据,因为即便天赋再高的球员,长期和不在同一水平的球员或者教练员一起训练,也会导致与期望值有巨大偏差。
将数据添加到数据集:
import pandas as pd
import numpy as np
from pandas import DataFrame,Series
#构建数据集
mydata = {
'进球':[16,12,16,8],
'进球转化率':[19,14,13,10],
'助攻':[8,2,7,4],
}
data = DataFrame(mydata)
data.index=['苏亚雷斯','莫拉塔','哲科','伊瓜因']
print(data)
数据矩阵:
进球 进球转化率 助攻
苏亚雷斯 16 19 8
莫拉塔 12 14 2
哲科 16 13 7
伊瓜因 8 10 4
因子分析是通过对原始数据相关系数内部结构的研究,将多个指标转化为少量互相不相关且不可观测的随机变量(即因子),以提取原有指标的绝大部分的信息的统计方法。因子分析首先将原始数据标准化处理,建立相关系数矩阵并计算其特征值和特征向量,接着从中选择特征值大于等于1的特征值个数为公共因子数,或者根据特征值累计贡献率大于80%来确定公共因子,求得正交或斜交因子载荷矩阵,最后计算公因子得分和综合得分。
第一步,建立因子分析模型:
from factor_analyzer import FactorAnalyzer, Rotator
fa = FactorAnalyzer(rotation=None)
fa.fit(data)
print(fa.loadings_)
公共因子与原有变量指标之间的关联程度由因子载荷值体现,由于初始因子载荷矩阵结构不够简明,各个因子的含义不突出。为此采用方差最大法,使各个变量在某个因子上产生较高的载荷,而在其余因子上载荷较小。
但是公共因子与原有变量指标之间的关联程度由因子载荷值体现,由于初始因子载荷矩阵结构不够简明,各个因子的含义不突出。为此采用方差最大法,使各个变量在某个因子上产生较高的载荷,而在其余因子上载荷较小,经过特征数据迭代收敛,得到旋转后因子载荷矩阵:
rotator = Rotator()
print("旋转后矩阵:\n", rotator.fit_transform(fa.loadings_))
随后我们可以简单看一下变量方差,即是每个原始变量在每个共同因子的负荷量的平方和,也就是指原始变量方差中由共同因子所决定的比率。变量的方差由共同因子和唯一因子组成。共同性表明了原始变量方差中能被共同因子解释的部分,共同性越大,变量能被因子说明的程度越高,即因子可解释该变量的方差越多。共同性的意义在于说明如果用共同因子替代原始变量后,原始变量的信息被保留的程度。
print(fa.get_communalities())
也可以查看因子相关矩阵和特征值:
print(fa.get_eigenvalues())
当然了,我们的最终目的是根据因子模型对各个球员进行综合打分,最后使用各个因子方差贡献率占3个因子方差贡献率的比重作为权重进行加权汇总,得到各个球员的综合得分F,即:
def F(factors):
return sum(factors*fa.get_factor_variance()[1])
之后就可以在矩阵中依次进行计算:
scores = []
for i in range(len(fa.transform(data))):
new = F(fa.transform(data)[i])
scores.append(new)
print(scores)
得到分值数组:
[0.7294004536510521, -0.2958329655707666, 0.530110265958429, -0.9636777540387146]
然后我们就可以为原矩阵添加一列数据:
data['综合打分'] = scores
print(data)
得到新矩阵:
进球 进球转化率 助攻 综合打分
苏亚雷斯 16 19 8 0.729400
莫拉塔 12 14 2 -0.295833
哲科 16 13 7 0.530110
伊瓜因 8 10 4 -0.963678
同时可以指定按照新字段列进行排序,方便数据展示:
data = data.sort_values(by='综合打分',ascending=False)
得到排序后的矩阵:
进球 进球转化率 助攻 综合打分
苏亚雷斯 16 19 8 0.729400
哲科 16 13 7 0.530110
莫拉塔 12 14 2 -0.295833
伊瓜因 8 10 4 -0.963678
如果愿意,我们也可以对矩阵进行可视化操作,这里以水平柱状图为例子:
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
plt.barh(range(4), scores, height=0.7, color='steelblue', alpha=0.8)
plt.yticks(range(4), ['苏亚雷斯','莫拉塔','哲科','伊瓜因'])
plt.xlim(-1,2)
plt.xlabel("分数")
plt.title("引援打分")
for x, y in enumerate(scores):
plt.text(y + 0.2, x - 0.1, '%s' % y)
plt.show()
根据综合评分,苏亚雷斯无疑是最佳人选,退而求其次是哲科,第三选择是莫拉塔,无论如何,他们三位的综合能力都要比队内的伊瓜因都要强,从这个角度来看,就算选择莫拉塔,也是比让伊瓜因留队更好的选择。
结语:必须指出的一点是,球员特征所形成的数据结果,绝对不能成为做决策的主要依据,只能作为参考而存在,过度依赖数据往往可能适得其反,比如曾被誉为足坛“数据战术大师”的贝尼特斯,其根据数据排首发阵型的操作曾经聒噪一时,可现在呢?只能混迹于中超联赛。