1)在说KMeans算法之前,先简单说说聚类。
聚类就是对大量未知标注的数据集,按数据的内在相似性将数据集划分为多个类别,使类别内的数据相似度较大而类别间的数据相似度较小。聚类属于无监督学习。
2)KMeans算法是聚类算法的一种经典算法。它的原理大致如下:
第一步:随机选择K个样本作为K个聚类的中心,计算每个样本到各个聚类中心的欧氏距离,将该样本分配到与之距离最近的聚类中心所在类别中(也称为“簇”(cluster))。
第二步:根据第一步得到的聚类划分情况,分别计算每个聚类的中心,作为新的聚类中心,重复第一步,直到计算所得几何中心与聚类中心吻合或接近重合为止。
3)根据以上描述,我们了解到实现kmeans算法的主要三点:
(1)簇个数 k 的选择
k 的选择一般是按照实际需求进行决定,或在实现算法时直接给定 k 值。
(2)各个样本点到“聚类中心”(也称簇中心)的距离
我们一般采用欧氏距离,计算公式如下:
分别是:一维向量,二维向量,三维向量的计算方法。
(3)根据新划分的簇,更新“聚类中心”
4)kmeans算法过程如果自己用python代码来写的话,会比较长。不过好在python有丰富的机器学习库,直接将kmeans的算法封装了,我们要使用的时候,直接调用就好。下面,我就以一个简单的实际案例为大家演示一下吧。
import numpy as np
import pandas as pd
import sklearn.cluster as sc
import matplotlib.pyplot as mp
# 导入数据,因为是excel格式,所以用pandas读取,在转换成数组格式
data = pd.read_excel("watermelon4.0.xlsx",header=None)
data = np.array(data)
data[:5] #显示数组前5行
[out:]
array([[0.697, 0.46 ],
[0.774, 0.376],
[0.634, 0.264],
[0.608, 0.318],
[0.556, 0.215]])
# 用散点图看一看数据的大致分布情况
mp.figure('data', facecolor='lightgray')
mp.title('data', fontsize=14)
mp.xlabel('x', fontsize=12)
mp.ylabel('y', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(data[:,0], data[:,1], s=60, marker='o',cmap='brg',label='Sample Points') #显示所有数据点
mp.legend()
mp.show()
# 使用KMeans模型来训练模型
model = sc.KMeans(n_clusters=4) #将整个数据分为4簇
model.fit(data)
#获取分类标签
pred_y = model.predict(data)
# 获取聚类中心
centers = model.cluster_centers_
# 打印看看pred_y centers长什么样子
print(pred_y)
print(centers)
[out:]
[1 1 3 1 3 2 2 2 3 2 2 2 3 3 0 3 3 2 2 2 3 1 0 0 0 1 0 0 1 0]
[[0.471 0.39928571]
[0.7115 0.40566667]
[0.348 0.18955556]
[0.6515 0.16325 ]]
# 将结果展现在散点图中
# “○”是样本数据,“+”是聚类中心点
mp.figure('KMeans', facecolor='lightgray')
mp.title('KMeans', fontsize=14)
mp.xlabel('x', fontsize=12)
mp.ylabel('y', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
#显示所有样本点
mp.scatter(data[:,0], data[:,1], s=60, marker='o', c=pred_y, cmap='brg',label='Sample Points')
#显示所有聚类中心点
mp.scatter(centers[:,0], centers[:,1], s=350, marker='+', color='red',label='Centers')
mp.legend()
mp.show()
5)kmeans算法由于初始“聚类中心”点是随机选取的,因此最终求得的簇的划分与随机选取的“聚类中心”有关,也就是说,可能会造成多种 k 个簇的划分情况。这是因为kmeans算法收敛到了局部最小值,而非全局最小值。
如何解决这种问题呢,下一次我在抽时间来写一写。
数据集来源于周志华老师的《机器学习》西瓜数据集4.0,地址是:https://github.com/Microstrong0305/machine_learning/tree/master/K-means
地址里还有详细的算法推到公式,有兴趣的同学,可以自己研究。