0 前言

K-Means是一种非监督学习,解决聚类问题。K代表K类,Means代表中心,本质是确定K类的中心点,当你找到了这些中心点,也就完成聚类。

问题:

  • 咋确定K类的中心点?
  • 咋将其他点划分到K类中?
  • 咋区分K-Means与KNN?

如果理解了上面这3个问题,那么对K-Means的原理掌握得也就差不多了。

有20支亚洲足球队,想按成绩划分3等,咋分?

工作原理

亚洲球队水平,你也有自己判断。如一流的伊朗或韩国;二流的中国;三流越南。这都是靠经验划分,那伊朗、中国、越南可谓三个等级的典型代表,即我们每个类的中心点。

咋确定K类的中心点?

一开始可随机指派的,当确认中心点后,就可按距离将其他足球队划分到不同类别。这就是K-Means中心思想,就这么简单直接。如一开始选一流球队中国,二流球队伊朗,三流球队韩国,中心点选错咋办?不用担心,K-Means有自我纠正机制,不断迭代过程,会纠正中心点。中心点在整个迭代过程,并非唯一,只是你需要一个初始值,一般算法会随机设置初始的中心点。

K-Means工作原理总结

  1. 选取K个点作为初始的类中心点,这些点一般从数据集中随机抽取
  2. 将每个点分配到最近的类中心点,形成K个类,再重新计算每个类的中心点
  3. 重复第二步,直到类不变或你也可设置最大迭代次数,这样即使类中心点变,但只要达到最大迭代次数就结束

咋给亚洲球队做聚类

对于机器,需数据才能判断类中心点。

国家

2019年国际排名

2018世界杯

2015亚洲杯

中国

73

40

7

日本

60

15

5

韩国

61

19

2

伊朗

34

18

6

沙特

67

26

10

伊拉克

91

40

4

卡塔尔

101

40

13

阿联酋

81

40

6

乌兹别克斯坦

88

40

8

泰国

122

40

17

越南

102

50

17

阿曼

87

50

12

巴林

116

50

11

朝鲜

110

50

14

印尼

164

50

17

澳洲

40

30

1

叙利亚

76

40

17

约旦

118

50

9

科威特

160

50

15

巴勒斯坦

96

50

161

先做数据规范化。把这些值划分到[0,1]或按均值为0,方差为1的正态分布进行规范化。先把数值都规范化到[0,1]的空间中,得到数值表:

国家

2019年国际排名

2018世界杯

2015亚洲杯

中国

0.3

0.71428571

0.375

日本

0.2

0

0.25

韩国

0.20769231

0.11428571

0.0625

伊朗

0

0.08571429

0.3125

沙特

0.25384615

0.31428571

0.5625

伊拉克

0.43846154

0.71428571

0.1875

卡塔尔

0.51538462

0.71428571

0.75

阿联酋

0.36153846

0.71428571

0.3125

乌兹别克斯坦

0.41538462

0.71428571

0.4375

泰国

0.67692308

0.71428571

1

越南

0.52307692

1

1

阿曼

0.40769231

1

0.6875

巴林

0.63076923

1

0.625

朝鲜

0.58461538

1

0.8125

印尼

1

1

1

澳洲

0.04615385

0.42857143

0

叙利亚

0.32307692

0.71428571

1

约旦

0.64615385

1

0.5

科威特

0.96923077

1

0.875

巴勒斯坦

0.47692308

1

0.9375

如随机选中国、日本、韩国为三个类的中心点,就要看这些球队到中心点距离。这里选欧氏距离作为距离标准,计算每个队伍分别到中国、日本、韩国的距离,根据距离远近划分。

看到大部分队和中国队聚类到一起。按中国、日本、韩国为3个分类的中心点,欧氏距离的计算结果:

国家

中国

日本

韩国

划分

中国

0

0.732003

0.682772

中国

日本

0.732003

0

0.219719

日本

韩国

0.682772

0.219719

0

韩国

伊朗

0.699291

0.226392

0.32627

日本

沙特

0.444169

0.446465

0.540491

中国

伊拉克

0.233083

0.755628

0.654889

中国

卡塔尔

0.432453

0.927185

0.96298

中国

阿联酋

0.087711

0.734986

0.667959

中国

乌兹别克斯坦

0.131224

0.769253

0.737402

中国

泰国

0.72986

1.140245

1.207925

中国

越南

0.72251

1.291077

1.327729

中国

阿曼

0.436906

1.1111

1.102322

中国

巴林

0.503528

1.151602

1.131322

中国

朝鲜

0.595017

1.210097

1.220271

中国

印尼

0.980947

1.484082

1.513654

中国

澳洲

0.53544

0.519463

0.358854

韩国

叙利亚

0.625426

1.043001

1.119026

中国

约旦

0.465919

1.123189

1.080807

中国

科威特

0.882894

1.407956

1.42288

中国

巴勒斯坦

0.655241

1.244726

1.273813

中国

再重新计算这三个类的中心点,咋计算?最简单的取平均值,再根据新的中心点按距离远近重新分配球队的分类,再根据球队的分类更新中心点的位置。一直迭代(重复上述计算过程:计算中心点和划分分类)到分类不再变:

国家

2019年国际排名

2018世界杯

2015亚洲杯

聚类

中国

73

40

7

0

日本

60

15

5

2

韩国

61

19

2

2

伊朗

34

18

6

2

沙特

67

26

10

2

伊拉克

91

40

4

0

卡塔尔

101

40

13

1

阿联酋

81

40

6

0

乌兹别克斯坦

88

40

8

0

泰国

122

40

17

1

越南

102

50

17

1

阿曼

87

50

12

1

巴林

116

50

11

1

朝鲜

110

50

14

1

印尼

164

50

17

1

澳洲

40

30

1

2

叙利亚

76

40

17

1

约旦

118

50

9

1

科威特

160

50

15

1

巴勒斯坦

96

50

16

1

  • 看出第一梯队有日本、韩国、伊朗、沙特、澳洲
  • 第二梯队有中国、伊拉克、阿联酋、乌兹别克斯坦
  • 第三梯队有卡塔尔、泰国、越南、阿曼、巴林、朝鲜、印尼、叙利亚、约旦、科威特和巴勒斯坦

咋用sklearn的K-Means算法

sklearn可以实现分类、聚类、回归、降维、模型选择和预处理等功能。用sklearn的聚类函数库:

from sklearn.cluster import KMeans

K-Means只是sklearn.cluster中的一个聚类库,实际上包括K-Means在内,sklearn.cluster一共提供了9种聚类方法,比如Mean-shift,DBSCAN,Spectral clustering(谱聚类)等。这些聚类方法的原理和K-Means不同,这里不做介绍。

K-Means创建:

KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm='auto')
  • n_clusters: 即K值,一般需要多试一些K值来保证更好的聚类效果。你可以随机设置一些K值,然后选择聚类效果最好的作为最终的K值;
  • max_iter: 最大迭代次数,如果聚类很难收敛的话,设置最大迭代次数可以让我们及时得到反馈结果,否则程序运行时间会非常长;
  • n_init:初始化中心点的运算次数,默认是10。程序是否能快速收敛和中心点的选择关系非常大,所以在中心点选择上多花一些时间,来争取整体时间上的快速收敛还是非常值得的。由于每一次中心点都是随机生成的,这样得到的结果就有好有坏,非常不确定,所以要运行n_init次, 取其中最好的作为初始的中心点。如果K值比较大的时候,你可以适当增大n_init这个值;
  • init: 即初始值选择的方式,默认是采用优化过的k-means++方式,你也可以自己指定中心点,或者采用random完全随机的方式。自己设置中心点一般是对于个性化的数据进行设置,很少采用。random的方式则是完全随机的方式,一般推荐采用优化过的k-means++方式;
  • algorithm:k-means的实现算法,有“auto” “full”“elkan”三种。一般来说建议直接用默认的"auto"。简单说下这三个取值的区别,如果你选择"full"采用的是传统的K-Means算法,“auto”会根据数据的特点自动选择是选择“full”还是“elkan”。我们一般选择默认的取值,即“auto” 。

在创建好K-Means类之后,就可以使用它的方法,最常用的是fit和predict这个两个函数。你可以单独使用fit函数和predict函数,也可以合并使用fit_predict函数。其中fit(data)可以对data数据进行k-Means聚类。 predict(data)可以针对data中的每个样本,计算最近的类。

20支亚洲球队的聚类

# coding: utf-8from sklearn.cluster import KMeansfrom sklearn import preprocessingimport pandas as pdimport numpy as np# 输入数据data = pd.read_csv('data.csv', encoding='gbk')train_x = data[["2019年国际排名","2018世界杯","2015亚洲杯"]]df = pd.DataFrame(train_x)kmeans = KMeans(n_clusters=3)# 规范化到[0,1]空间min_max_scaler=preprocessing.MinMaxScaler()train_x=min_max_scaler.fit_transform(train_x)# kmeans算法kmeans.fit(train_x)predict_y = kmeans.predict(train_x)# 合并聚类结果,插入到原数据中result = pd.concat((data,pd.DataFrame(predict_y)),axis=1)result.rename({0:u'聚类'},axis=1,inplace=True)print(result)

总结

咋确定K类的中心点?其中包括了初始的设置,以及中间迭代过程中中心点的计算。在初始设置中,会进行n_init次的选择,然后选择初始中心点效果最好的为初始值。在每次分类更新后,你都需要重新确认每一类的中心点,一般采用均值的方式进行确认。

如何将其他点划分到K类中?这里实际上是关于距离的定义,我们知道距离有多种定义的方式,在K-Means和KNN中,我们都可以采用欧氏距离、曼哈顿距离、切比雪夫距离、余弦距离等。对于点的划分,就看它离哪个类的中心点的距离最近,就属于哪一类。

如何区分K-Means和KNN这两种算法呢?刚学过K-Means和KNN算法的同学应该能知道两者的区别,但往往过了一段时间,就容易混淆。所以我们可以从三个维度来区分K-Means和KNN这两个算法:

  • 首先,这两个算法解决数据挖掘的两类问题。K-Means是聚类算法,KNN是分类算法。
  • 这两个算法分别是两种不同的学习方式。K-Means是非监督学习,也就是不需要事先给出分类标签,而KNN是有监督学习,需要我们给出训练数据的分类标识。
  • 最后,K值的含义不同。K-Means中的K值代表K类。KNN中的K值代表K个最接近的邻居