前文回顾:
肘部法:SSE误差平方和
SSE(sum of the squared errors)是对簇松散度的衡量,作为目标函数其实是一个严格的坐标下降(Coordinate Decendet)过程。SSE不能保证找到全局最优解,只能确保局部最优解。也就是说,可能会造成多种 k 个簇的划分情况。但是可以重复执行几次kmeans算法,选取SSE最小的一次作为最终的聚类结果。
轮廓系数法(Silhouette Coefficient)
轮廓系数法结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。
指标:内部距离最小化,外部距离最大化。平均轮廓系数的取值范围为[-1,1],系数越大,聚类效果越好。
每次聚类后,每个样本都会得到一个轮廓系数,当它为1时,说明这个点与周围簇距离较远,结果非常好,当它为0,说明这个点可能处在两个簇的边界上,当值为负时,暗含该点可能被误分了。
Sklearn代码实现
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn import datasets, metrics
def km_sse_cs():
"""
KMeans算法效果评价
1、簇内误方差(SSE, sum of the squared errors),手肘法,肘部法,其大小表明函数拟合的好坏。
使用图形工具肘部法,根据簇的数量来可视化簇内误方差。下降率突然变缓时即认为是最佳的k值(拐点)。
当KMeans算法训练完成后,可以通过使用内置inertia属性来获取簇内的误方差。
2、轮廓系数法(Silhouette Coefficient)结合了聚类的凝聚度(Cohesion)和分离度(Separation)
平均轮廓系数的取值范围为[-1,1],系数越大,聚类效果越好。当值为负时,暗含该点可能被误分了。
:return:
"""
sample = load_data()
data = sample.data
# 存放设置不同簇数时的SSE值
sse_list = []
# 轮廓系数
silhouettes = []
# 循环设置不同的聚类簇数
for i in range(2, 15):
model = KMeans(n_clusters=i)
model.fit(data)
# kmeans算法inertia属性获取簇内的SSE
sse_list.append(model.inertia_)
# 轮廓系数
silhouette = metrics.silhouette_score(data, model.labels_, metric='euclidean')
silhouettes.append(silhouette)
# 绘制簇内误方差曲线
plt.subplot(211)
plt.title('KMeans 簇内误方差')
plt.plot(range(2, 15), sse_list, marker='*')
plt.xlabel('簇数量')
plt.ylabel('簇内误方差(SSE)')
# 绘制轮廓系数曲线
plt.subplot(212)
plt.title('KMeans 轮廓系数')
plt.plot(range(2, 15), silhouettes, marker='o')
plt.xlabel('簇数量')
plt.ylabel('轮廓系数')
plt.tight_layout()
plt.show()
def load_data():
"""
加载鸢尾花数据集
"""
return datasets.load_iris()
if __name__ == '__main__':
import matplotlib as mpl
# 汉字字体,优先使用楷体,如果找不到楷体,则使用黑体
mpl.rcParams['font.sans-serif'] = ['KaiTi', 'SimHei', 'FangSong']
# KMeans算法
km_sse_cs()
运行效果图,如下:
通过SSE图可明显看出拐点(肘部)的簇数量是3,与鸢尾花数据集的类别是吻合的。