0 前言
K-Means是一种非监督学习,解决聚类问题。K代表K类,Means代表中心,本质是确定K类的中心点,当你找到了这些中心点,也就完成聚类。
问题:
- 咋确定K类的中心点?
- 咋将其他点划分到K类中?
- 咋区分K-Means与KNN?
如果理解了上面这3个问题,那么对K-Means的原理掌握得也就差不多了。
有20支亚洲足球队,想按成绩划分3等,咋分?
工作原理
亚洲球队水平,你也有自己判断。如一流的伊朗或韩国;二流的中国;三流越南。这都是靠经验划分,那伊朗、中国、越南可谓三个等级的典型代表,即我们每个类的中心点。
咋确定K类的中心点?
一开始可随机指派的,当确认中心点后,就可按距离将其他足球队划分到不同类别。这就是K-Means中心思想,就这么简单直接。如一开始选一流球队中国,二流球队伊朗,三流球队韩国,中心点选错咋办?不用担心,K-Means有自我纠正机制,不断迭代过程,会纠正中心点。中心点在整个迭代过程,并非唯一,只是你需要一个初始值,一般算法会随机设置初始的中心点。
K-Means工作原理总结
- 选取K个点作为初始的类中心点,这些点一般从数据集中随机抽取
- 将每个点分配到最近的类中心点,形成K个类,再重新计算每个类的中心点
- 重复第二步,直到类不变或你也可设置最大迭代次数,这样即使类中心点变,但只要达到最大迭代次数就结束
咋给亚洲球队做聚类
对于机器,需数据才能判断类中心点。
国家 | 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 KMeansK-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个最接近的邻居
















