SS00019.algorithm——|Arithmetic&Machine.v19|——|Machine:无监督学习算法.v04|

一、聚类算法的模型评估指标:轮廓系数
### --- 聚类算法的模型评估指标:轮廓系数

~~~     不同于分类模型和回归,聚类算法的模型评估不是一件简单的事。
~~~     在分类中,有直接结果(标签)的输出,并且分类的结果有正误之分,
~~~     所以我们使用预测的准确度,混淆矩阵,ROC 曲线等等指标来进行评估,
~~~     但无论如何评估,都是在”模型找到正确答案“的能力。
~~~     而回归中,由于要拟合数据,我们有 SSE均方误差,有损失函数来衡量模型的拟合程度。
~~~     但这些衡量指标都不能够使用于聚类。
~~~     面试高危问题:如何衡量聚类算法的效果?
~~~     聚类模型的结果不是某种标签输出,并且聚类的结果是不确定的,
~~~     其优劣由业务需求或者算法需求来决定,并且没有永远的正确答案。那我们如何衡量聚类的效果呢?

~~~     记得我们说过,KMeans 的目标是确保“簇内差异小,簇外差异大”,
~~~     我们就可以通过衡量簇内差异来衡量聚类的效果。
~~~     我们刚才说过,Inertia 是用距离来衡量簇内差异的指标,
~~~     因此,我们是否可以使用Inertia 来作为聚类的衡量指标呢?Inertia 越小模型越好。
~~~     可以,但是这个指标的缺点和极限太大。

~~~     它不是有界的。我们只知道,Inertia 是越小越好,是 0 最好,但我们不知道,
~~~     一个较小的Inertia究竟有没有达到模型的极限,能否继续提高。

~~~     它的计算太容易受到特征数目的影响,数据维度很大的时候,
~~~     Inertia 的计算量会陷入维度诅咒之中,计算量会爆炸,不适合用来一次次评估模型。

~~~     它会受到超参数 K 的影响,在我们之前的尝试中其实我们已经发现,
~~~     随着 K 越大,Inertia 注定会越来越小,但这并不代表模型的效果越来越好了。

~~~     Inertia 作为评估指标,会让聚类算法在一些细长簇,环形簇,
~~~     或者不规则形状的流形时表现不佳:
~~~     # 那我们可以使用什么指标呢?聚类是没有标签,即不知道真实答案的预测算法,
~~~     # 我们必须完全依赖评价簇内的稠密程度(簇内差异小)和簇间的离散程度(簇外差异大)来评估聚类的效果。
~~~     # 其中轮廓系数是最常用的聚类算法的评价指标。它是对每个样本来定义的,它能够同时衡量:

~~~     样本与其自身所在的簇中的其他样本的相似度 a,等于样本与同一簇中所有其他点之间的平均距离
~~~     样本与其他簇中的样本的相似度 b,等于样本与下一个最近的簇中的所有点之间的平均距离
~~~     根据聚类的要求”簇内差异小,簇外差异大“,我们希望 b 永远大于 a,并且大得越多越好。
~~~     单个样本的轮廓系数计算为:
~~~     # 很容易理解轮廓系数范围是(-1,1):

~~~     轮廓系数越接近 1:样本与自己所在的簇中的样本很相似,并且与其他簇中的样本不相似。
~~~     轮廓系数为 0 时:两个簇中的样本相似度一致,两个簇本应该是一个簇。
~~~     轮廓系数为负时:样本点与簇外的样本更相似。
~~~     如果一个簇中的大多数样本具有比较高的轮廓系数,则簇会有较高的总轮廓系数,
~~~     则整个数据集的平均轮廓系数越高,则聚类是合适的。
~~~     如果许多样本点具有低轮廓系数甚至负值,则聚类是不合适的,
~~~     聚类的超参数 K 可能设定得太大或者太小。

~~~     在 sklearn 中,我们使用模块 metrics 中的类 silhouette_score 来计算轮廓系数,
~~~     它返回的是一个数据集中,所有样本的轮廓系数的均值。
~~~     但我们还有同在 metrics 模块中的 silhouette_sample,它的参数与轮廓系数一致,
~~~     但返回的是数据集中每个样本自己的轮廓系数。
~~~     我们来看看轮廓系数在我们自建的数据集上表现如何:
from sklearn.metrics import silhouette_score
from sklearn.metrics import silhouette_samples

X
y_pred
array([[-6.92324165e+00, -1.06695320e+01],
[-8.63062033e+00, -7.13940564e+00],
[-9.63048069e+00, -2.72044935e+00],
[-2.30647659e+00…]])
array([0, 0, 2, 1, 2, 1, 2, 2, 2, 2, 0, 0, 2, 1, 2, 0, 2, 0, 1, 2, 2, 2,
2, 1, 2, 2, 1, 1, 2, 2…])
~~~     # 观察一下不同的 K 下,轮廓系数发生什么变化?

~~~     # 观察一下不同的K下,轮廓系数发生什么变化?
cluster = KMeans(n_clusters=3, random_state=0).fit(X)
silhouette_score(X,cluster_.labels_) #计算所有样本的轮廓系数均值。
silhouette_samples(X,cluster.labels_) #计算每个样本的轮廓系数。
array([ 3.32141517e-01, 5.02867308e-01, 5.69286243e-01, 8.26239736e-01,
3.52953508e-01, 7.40603896e-01, 6.92621728e-01, 5.90288043e-01,
4.17153302e-02, 7.35814660e-01…])
import pandas as pd
score=[]
for i in range(2,100):
cluster= KMeans(n_clusters=i, random_state=0).fit(X)
score.append(silhouette_score(X,cluster.labels_))
plt.plot(range(2,100),score)
plt.axvline(pd.DataFrame(score).idxmin()[0]+2,ls=':')
~~~     轮廓系数有很多优点,它在有限空间中取值,使得我们对模型的聚类效果有一个“参考”。
~~~     并且,轮廓系数对数据的分布没有假设,因此在很多数据集上都表现良好。
~~~     但它在每个簇的分割比较清洗时表现最好。
~~~     但轮廓系数也有缺陷,比如基于密度进行的聚类,
~~~     或通过 DBSCAN 获得的聚类结果,如果使用轮廓系数来衡量,则会表现出比真实聚类效果更高的分数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yanqi_vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值