跟 scikit-learn 学机器学习—轮廓系数评估聚类结果

最初是在实验室合作项目的研究报告中了解到这个“轮廓系数”这个关键词的,当时对这个概念还是知其然不知其所以然。最近给项目加功能的时候,需要用到这个指标,重新看了下公式,查了查 scikit-learn 的文档,写个文档记录一下。

最近搜机器学习相关的内容,经常能经过几次跳转回到 scikit-learn 的文档中,打算后续继续跟着文档巩固一下算法的实现方面的内容吧。本文主要分为:定义、sklearn 中的方法介绍、应用介绍、源码分析

定义

轮廓系数(silhouette coefficient) 结合了凝聚度和分离度,其计算步骤如下:

  1. 对于第 i 个对象,计算它到所属簇中所有其他对象的平均距离,记 ai (体现凝聚度)
  2. 对于第 i 个对象和不包含该对象的任意簇,计算该对象到给定簇中所有对象的平均距离,记 bi (体现分离度)
  3. 第 i 个对象的轮廓系数为 si = (bi-ai)/max(ai, bi)  //回头研究一下 wordpress 的公式插件去

从上面可以看出,轮廓系数取值为[-1, 1],其值越大越好,且当值为负时,表明 ai<bi,样本被分配到错误的簇中,聚类结果不可接受。对于接近0的结果,则表明聚类结果有重叠的情况。

scikit-learn 中的轮廓系数

对应 scikit-learn 方法是 sklearn.metrics.silhouette_score。该方法是计算所有样本的平均值,另一个方法 silhouette_samples 会返回所有样本的轮廓系数。在文档中提到,轮廓系数需要聚类数大于2,小于(样本数-1)。方法包括几个参数,最终返回一个 float 的轮廓系数,通常是在全部样本上的。

  • X:二维样本,通常为[n_samples, n_features],当 metric 设置为”precomputed”时,应为[n_samples, n_samples]方阵
  • labels:一维矩阵,每个样本所属簇的 label
  • metric:预计算”precomputed”,或者为一个可调用的函数计算两个实例之间的距离。如果为 string,则必须是metrics.pairwise.pairwise_distances 中 metric 可选的(‘cityblock’, ‘cosine’, ‘euclidean’, ‘l1’, ‘l2’, ‘manhattan’ 或‘braycurtis’, ‘canberra’, ‘chebyshev’, ‘correlation’, ‘dice’, ‘hamming’, ‘jaccard’, ‘kulsinski’, ‘mahalanobis’, ‘matching’, ‘minkowski’, ‘rogerstanimoto’, ‘russellrao’, ‘seuclidean’, ‘sokalmichener’, ‘sokalsneath’, ‘sqeuclidean’, ‘yule’)——好多啊。
  • sample_size:随机取样一部分计算平均值,int 类型
  • random_state:当sample_size 为非空时用来生成随机采样。给定一个种子,或者使用 numpy.RandomState
  • **kwds:其他可选的 key-value 参数

应用举例

下图是K-Means 算法结果应用轮廓系数得到的,K 设置为3、4、5、6。可以看出3、5、6时会出现不同聚类簇之间轮廓系数差别较大的情况,且平均轮廓系数低于平均值,是一个不好的选择。对应的程序地址:plot_kmeans_silhouette_analysis.py





更多聚类相关的文档,参见 Cluster User Guide

源码

轮廓系数对应的文件为 /site-packages/sklearn/metrics/cluster/unsupervised.py 中,cluster 目录下还包括 supervised.py 按照分类应该属于利用内部指标进行结果评估的。

算法除去文档只有12行,多数为参数验证,根据是否 sample 决定如何调用 silhouette_sample 函数。在 silhouette_sample 函数中,又调用两个计算簇内距离和簇间距离的函数。看了代码,感叹 numpy 的方便和快速。

 

跟 scikit-learn 学机器学习—轮廓系数评估聚类结果》上有3条评论

  1. nameless

    “从上面可以看出,轮廓系数取值为[-1, 1],其值越大越好,且当值为负时,表明 aibi时表示错分吧?

    回复
    1. Guo 文章作者

      此时,对于第 i 个对象,和簇外对象的平均距离,大于和簇内对象的平均距离,说明它和当前分配的簇并不够“聚”

      回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注