用K-Means对亚洲足球队分了个类

1.18号FIFA刚对全球足球队伍进行了排名,国足给力前进了一名现全球排名70,亚洲排名第6。这两天也正好在复习机器学习算法,打算用K-Means对亚洲的足球队伍进行自动聚类,看看国足到底属于哪个档次。


用K-Means对亚洲足球队分了个类_第1张图片
Rank.png
K-Means简介

K-Means 是一种无监督学习算法,能对一系列无标签的数据进行聚类,发现数据中所包含的隐藏信息和结构。说简单点,你现在手上有一堆没有标签的数据,而你现在需要将其分成K类,K-Means要解决的任务就是在不知道数据标签,不知道数据的归属情况下,对其聚类。

算法思想:

  1. 初始化K个聚类中心
  2. 遍历所有样本计算与聚类中心的欧氏距离,并将其分类到距离最近的中心形成簇
  3. 重新计算K个簇的中心,计算方式取簇中所有元素各自维度的均值
  4. 将样本按新的聚类中心重新聚类
  5. 重复步骤4,直到结果收敛
  6. 输出结果

那怎么依据球队数据进行自动聚类呢?

首先,数据!数据!数据!获取数据是第一步,有时候一个优质的数据集对计算结果有很大影响。从FIFA官网给出的数据可以看到,每支球队的当前排名是由最近四年的分数加权平均得到,离得越近权重越大。分数来源是对每支队伍的参赛成绩进行统计,踢得多,赢球场次多,分数也就高。

那我们就简单点来,拿球队2015-2018的分数作为数据集(去除加权),取前20支队伍作为聚类样本,那么每支球队也就有四个维度的数据,数据收集如下:


用K-Means对亚洲足球队分了个类_第2张图片
sample.png

数据有了那就开始写算法吧~~
这一部分用于计算距离,这里我用的欧氏距离,将样本划分到最近的聚类中心

def findClosestCentroids(X,centroids):
    #read the input information
    (m,n)=X.shape
    idx=np.zeros((m,1))
    K=centroids.shape[0]
    #compute the cluster
    K_value = np.zeros((K, 1))
    for i in range(m):
        for j in range(K):
            K_value[j]=np.linalg.norm(X[i,:]-centroids[j,:],2)
        idx[i,0]=np.where(K_value==np.min(K_value))[0][0]
    return idx

这一部分计算各簇中所有元素各自维度的均值用来更新簇中心。

#compute the new centroids by means
def computeCentroids(idx,X,K):
    #read the input information
    (m,n)=X.shape
    new_centroids=np.zeros((K,n))
    #compute means
    for i in range(K):
        centroids_temp=np.zeros((1,n))
        for j in range(m):
            if int(idx[j])==i:
                centroids_temp=np.vstack((centroids_temp,X[j,:]))
        new_centroids[i,:]=np.mean(centroids_temp,axis=0)
    return new_centroids

此外,还需要迭代上面的计算过程直到结果收敛:

ef runKmeans(X,centroids,maxiter):
    K=centroids.shape[0]
    for i in range(maxiter):
        idx=findClosestCentroids(X,centroids)
        centroids=computeCentroids(idx,X,K)
    return centroids,idx

好,算法写完了,可以试试我们的数据了
将队伍档次分成三档,一流,二流和三流,设置K=3,初始化聚类中心为伊朗,卡塔尔和吉尔吉斯斯坦,求取结果如下

levels.png

有点出乎预料啊,国足竟然冲到亚洲一流的档次上了,赶紧做个可视化看看情况。由于数据维度是四维的,为了可视化只取前2-3维数据。
用K-Means对亚洲足球队分了个类_第3张图片
figure1.png

这是二维聚类图,数据的分类情况还行,蓝色的点是一流档次,绿色的是二流,红色的是三流,叉是最终的聚类中心。
用K-Means对亚洲足球队分了个类_第4张图片
figure2.png

这是三维情况的图,从图示信息可以看到K-Means还是能清楚的将数据自动聚类。Ok, it works 但国足真的已经强到能在亚洲处于一流的地位吗?听说国足会打很多热身赛,热身赛也对分数也有贡献所以取这样的数据样本是有瑕疵的,应该用一些国际杯赛数据。先这样,明天再用世界杯和亚洲杯的数据做一次分析(还有很多小东西可以发掘,先Mark)。

隔了几天重新收集了一波数据,我采集了三年的世界杯数据和三年的亚洲杯数据,评分规则如下:
对于世界杯,如果打入决赛圈则取其最终排名作为得分,未能进入决赛圈的按其能否进入世界杯预选赛八强或十强(注:2006年亚洲预选赛为八强,后两届为十强)的标准评分,若进入八强或十强则赋40(因为世界杯决赛圈32强,用40作为一个区分),未能进入的则赋50。
对于亚洲杯,如果进入四强则取其最终排名作为得分,进入八强的赋予5,进入十六强的赋予9,预选赛未能出线的赋予17。

用K-Means对亚洲足球队分了个类_第5张图片
Data.png

这样的评分规则参考了其它博文,而且相比于FIFA的排名数据,以这样的国际杯赛数据作为样本更明了,更有说服力。
重复上述的初始化过程:取日本,卡塔尔,越南作为三簇的聚类中心,K=3,迭代次数maxiter=10,得到的结果如下:
Rank2.png

看,国足还能坚挺的处在二流水平。另外在一流队伍中,伊朗距离聚类中心最远,相比于其它三个强队还有一定距离,而国足在二流队伍中处于一个中下水平的地位。喜欢的小伙伴可以进一步挖掘。

你可能感兴趣的:(用K-Means对亚洲足球队分了个类)