『『ML』用』用Python实现聚类效果的评估(轮廓系数、互信息)实现聚类效果的评估(轮廓系数、互信息)
好的聚类:类内凝聚度高,类间分离度高。
本文介绍两种聚类评估方法,轮廓系数轮廓系数(Silhouette Coefficient)以及标准化互信息标准化互信息(NMI),并且用Python实现。
导航导航效果评估综述轮廓系数互信息参考文章
效果评估综述效果评估综述
这里直接贴上 聚类算法初探(七)聚类分析的效果评测
它摘自于中国科学院计算技术研究所周昭涛的硕士论文《文本聚类分析效果评价及文本表示研究》的第三章。建议先看看
原文,可以对聚类评估有一个很好的了解。
综合来说,我们希望最终的聚类结果是:同一个簇内的点是紧密的,而不同簇之间的距离是较远的;同时,它也要与我们
人工的判断相一致。
接下来介绍两种聚类评估方法:轮廓系数和标准化互信息。前者是无需数据标注,判断聚类的 类内距类内距 和 类间距类间距 ;而后者
是需要对于数据进行 标注标注 ,判断聚类的 准确性准确性 。
轮廓系数轮廓系数
在聚类时,如果 类别未知类别未知 时,可以选择轮廓系数作为聚类性能的评估指标。从 百度百科 摘取的轮廓系数的介绍:
轮廓系数是聚类效果好坏的一种评价方式。它结合内聚度内聚度和分离度分离度两种因素。可以用来在相同原始数据的基础上用来评价
不同算法、或者算法不同运行方式对聚类结果所产生的影响。
以K-Means举例。由于 kkk 的值是需要事先给定的。如果我们不太清楚数据分几个簇比较好,我们可以尝试用不同的 kkk
值来计算轮廓系数,从而选择 最优最优 的一个 kkk 值。计算过程如下:
对于一个簇中的一个点 iii
aaa ( iii ) = averageaverageaverage ( iii 向量到所有它属于的簇中其它点的距离 )
bbb ( iii ) = minminmin ( iii 向量到与它相邻最近的一簇内的所有点的平均距离 )
那么 iii 的轮廓系数为S(i)=(b(i)−a(i))/max{a(i),b(i)}S(i)=( b(i)-a(i) ) / max\{ a(i),b(i) \}S(i)=(b(i)−a(i))/max{a(i),b(i)}
将所有点的轮廓系数求平均,就是该聚类结果总的轮廓系数。
其中,aaa ( iii ) 可以理解为一点与簇内其他点不相似性的平均值,即类内的 凝聚度凝聚度 ;bbb ( iii ) 可以理解为一点与最近簇
的不相似性的平均值,即类间的 分离度分离度 。
我们也可以看到,S(i)S(i)S(i) 是介于[-1, 1]之间的。aaa ( iii ) 越小,bbb ( iii ) 越大,说明聚类效果越好,轮廓系数
S(i)S(i)S(i) 就越接近1。
那么,如果用Python来实现呢?给出它的伪代码:
输入:数据的个数m,k的取值范围
输出:每个k所对应的轮廓系数
在取值范围内的每一个k:
对于每一个簇:
对于每一个点i:
计算i与簇内其他点距离之和的平均值,记为a(i)
计算i与其他簇每个点距离之和的平均值,选择最小的那一个,记为b(i)
s(i) = (b(i)-a(i)) / max(a(i), b(i))
加总每一个点的轮廓系数,记为 sum
轮廓系数 s = sum / m
接下来用代码实现,K-Means 具体细节可以参考 利用K-Means聚类算法对未标注数据分组。
因此,运行K-Means的代码我就不贴啦,我就直接附上轮廓系数的代码。代码中的一些细节在上面的博客中得到了解释,
有什么疑问可以先看看那篇博文哦。
首先,我的数据集为testSet.txt,运行 K-Means 的代码为biKMeans(data, k),datadatadata 为传入的数据集矩阵,kkk 是簇的
个数。这个函数返回两个值,一个是中心点,另一个是clusterAssment,它一共有 mmm 行( mmm 为数据集的行数),两列,
第一列保存这一点所在簇的索引,第二列保存到簇中心距离的平方。
if __name__ == '__main__':
data = np.mat(loadDataSet('testSet.txt'))
m = np.shape(data)[0] # 一共有m行数据