大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia_


点一下关注吧!!!非常感谢!!持续更新!!!

目前已经更新到了:

  • Hadoop(已更完)
  • HDFS(已更完)
  • MapReduce(已更完)
  • Hive(已更完)
  • Flume(已更完)
  • Sqoop(已更完)
  • Zookeeper(已更完)
  • HBase(已更完)
  • Redis (已更完)
  • Kafka(已更完)
  • Spark(已更完)
  • Flink(已更完)
  • ClickHouse(已更完)
  • Kudu(已更完)
  • Druid(已更完)
  • Kylin(已更完)
  • Elasticsearch(已更完)
  • DataX(已更完)
  • Tez(已更完)
  • 数据挖掘(正在更新…)

章节内容

上节我们完成了如下的内容:

  • KMeans Python 实现
  • 算法验证 sklearn n_clusters labels

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__机器学习

sklearn实现 K-Means

cluster.cluster_centers_

centroid = cluster.cluster_centers_
centroid
centroid.shape

运行结果如下图所示:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__python_02

cluster.inertia_

查看总距离的平方和:

inertia = cluster.inertia_
inertia

运行结果如下图所示:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__数据挖掘_03


如果我们把簇的数量换成 4,Inertia 会怎么样?

n_clusters = 4
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_

运行结果如下图所示:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__人工智能_04


如果换成 5:

n_clusters = 5
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_

执行结果如下图所示:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__大数据_05


如果换成 6:

n_clusters = 6
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_

执行结果如下图所示:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__python_06

聚类算法模型评估:轮廓系数

不同于分类模型和回归,聚类算法的模型评估不是一件简单的事,在分类中,有直接结果(标签)的输出,并且分类结果有正负之分,所以我们使用预测的准确度,混淆矩阵,ROC 曲线等等指标来进行评估,但无论如何评估,都是在”模型找到正确答案“的能力。而回归中,由于要拟合数据,我们有 SSE 均方误差,有损失函数来衡量模型的拟合程度,但这些衡量指标都不能够使用于聚类。

如何衡量聚类算法的效果

聚类模型的结果不是某种标签输出,并且聚类的结果是不确定的,其优劣由业务需求或算法需求来决定,并且永远没有正确答案。那我们如何衡量聚类的效果呢?
记得我们说过,KMeans 的目标是确保“簇内差异小,簇外差异大”,我们就可以通过衡量簇内差异来衡量聚类的效果。我们刚才说过,Inertia 是用距离来衡量簇内差异的指标,因此,我们是否可以使用 Inertia 来作为聚类的衡量指标呢?Inertia 越小模型越好。
可以,但是这个指标的缺点和极限太大了:

  • 它不是有界的,我们只知道,Inertia 是越小越好,是 0 最好,但我们不知道,一个较小的Inertia究竟有没有达到模型的极限,是否能够继续提高。
  • 它的计算太容易受到特征数目的影响,数据维度很大的时候,Inertia 的计算量会陷入维度诅咒之中,计算量会爆炸,不适合用来一次次评估模型。
  • 它会收到超参数 K 的影响,在我们之前的尝试中其实我们已经发现,随着 K 的越大,Intertia 会越来越小,但是这不能代表我们的模型越来越好。
  • Inertia 作为评估指标,会让聚类算法在一些细长簇,环形簇,或者不规则的表现不佳。

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__python_07


那我们可以使用什么指标呢?聚类是没有标签的,即不知道真实答案的预测算法,我们必须完全依赖评价簇内稠密程度(簇内差异小)和簇间的离散程度(簇外差异大)来评估聚类的效果。其中轮廓系数是最常用的聚类算法的评价指标。它是对每个样本来定义的,它能够同时衡量:

  • 样本与其自身所在的簇中的其他样本的相似度 a,等于样本与同一簇所有其他点之间的平均距离
  • 样本与其他簇中的样本相似度 b ,等于样本与下一个最近的簇中的所有点之间的平均距离

根据聚类的要求:“簇内差异小,簇外差异大”,我们希望 b 永远大于 a,并且大的越多越好,单个样本的轮廓系数为:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__数据挖掘_08


这个公式可以被解析为:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__机器学习_09

很容易理解的轮廓系数范围是:(-1,1):

  • 轮廓系数越接近 1:样本与自己所在簇中的样本很相似,并且与其他簇中的样本不相似
  • 轮廓系数为 0 时,两个簇中的样本相似度一致,两个簇本应该是一个簇。
  • 轮廓为负时:样本点与簇外的样本更相似。

如果一个簇中的大多数样本具有比较高的轮廓系数,则簇会有较高的总轮廓系数,则整个数据集的平均轮廓系数较高,则聚类时合适的。
如果许多样本点具有低轮廓系数甚至负值,则聚类是不合适的,聚类的超参数 K 可能设定的太大或者太小。

在 sklearn 中,我们使用模块 metrics 中的类 sihouette_score 来计算轮廓系数,它返回的是一个数据集中,所有样本的轮库系数的均值,但我们还有同在 metrics 模块中的 sihouette_sample,它的参数与轮廓系数一致,但返回的数据集中每个样本自己的轮廓系数:

from sklearn.metrics import silhouette_score
from sklearn.metrics import silhouette_samples

X
y_pred

执行结果如下图所示:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__python_10


观察一下不同的 K ,轮廓系数发生了什么变化?

#观察一下不同的K下,轮廓系数发生什么变化?
cluster = KMeans(n_clusters=3, random_state=0).fit(X)
silhouette_score(X,cluster_.labels_) #计算所有样本的轮廓系数均值。
silhouette_samples(X,cluster.labels_) #计算每个样本的轮廓系数。

运行之后生成的结果如下:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__大数据_11

我们继续编写代码:

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# 定义存储评分的列表
score = []

# 进行 KMeans 聚类并计算 silhouette_score
for i in range(2, 100):
    cluster = KMeans(n_clusters=i, random_state=0).fit(X)
    score.append(silhouette_score(X, cluster.labels_))

# 绘制 silhouette_score 的变化曲线
plt.plot(range(2, 100), score)

# 找到 silhouette_score 最小值对应的索引,并绘制一条垂直线
plt.axvline(pd.DataFrame(score).idxmin()[0] + 2, ls=':')

# 添加标题和坐标轴标签
plt.title('Silhouette Score vs Number of Clusters')
plt.xlabel('Number of Clusters')
plt.ylabel('Silhouette Score')

# 显示图形
plt.show()

执行结果如下图所示:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__python_12


生成的图片结果如下:

大数据-215 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn cluster.cluster_centers_ inertia__python_13


轮廓系数有很多优点,它在有限的空间中取值,使得我们对模型的聚类效果有一个参考,并且,轮廓系数对数据的分布没有假设,因此在很多数据集上都表现良好,但它在每个簇的分割比较清洗时表现最好。但轮廓系数也有缺陷,比如基于密度进行的聚类,或通过 DBSCAN 获得的聚类结果,如果使用轮廓系数来衡量,则会表现出比真实聚类效果更高的分数。


上一篇:Qt邮箱程序改良版(信号和槽)