python - Scikit Learn - K-Means - 弯头 - 标准

标签 python machine-learning scikit-learn cluster-analysis k-means

今天我想学习一些关于 K-means 的知识。我已经了解算法并且我知道它是如何工作的。现在我正在寻找正确的 k...我发现肘部标准是一种检测正确 k 的方法,但我不明白如何将它与 scikit learn 一起使用?!在 scikit learn 中,我以这种方式对事物进行聚类

kmeans = KMeans(init='k-means++', n_clusters=n_clusters, n_init=10) 
kmeans.fit(data)

所以我应该为 n_clusters = 1...n 执行几次并观察错误率以获得正确的 k 吗?认为这会很愚蠢并且会花费很多时间?!

最佳答案

如果事先不知道真正的标签(如您的情况),则可以使用肘准则或轮廓系数评估 K-Means 聚类

肘部标准法:

肘部方法背后的想法是在给定数据集上运行 k-means 聚类,以获得一系列 k 值(num_clusters,例如 k=1 到 10),以及每个 k 值,计算误差平方和 (SSE)。

之后,为每个 k 值绘制 SSE 的折线图。如果折线图看起来像一条 ARM - 折线图下方的红色圆圈(如角度),则 ARM 上的“肘部”是最佳 k 的值(簇数)。 在这里,我们希望最小化 SSE。随着k的增加,SSE趋向于向0减小(当k等于数据集中数据点的数量时,SSE为0,因为这样每个数据点都是自己的簇,它与中心之间没有误差它的集群)。

所以我们的目标是选择一个 k 的小值 仍然具有低 SSE,而肘部通常代表我们通过增加 k 开始 yield 递减的位置。

让我们考虑虹膜数据集,

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris['feature_names'])
#print(X)
data = X[['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)']]

sse = {}
for k in range(1, 10):
    kmeans = KMeans(n_clusters=k, max_iter=1000).fit(data)
    data["clusters"] = kmeans.labels_
    #print(data["clusters"])
    sse[k] = kmeans.inertia_ # Inertia: Sum of distances of samples to their closest cluster center
plt.figure()
plt.plot(list(sse.keys()), list(sse.values()))
plt.xlabel("Number of cluster")
plt.ylabel("SSE")
plt.show()

以上代码的情节: enter image description here

我们可以在图中看到,3 是 iris 数据集的最佳聚类数(红色圈出),这确实是正确的。



剪影系数法:

来自 sklearn documentation ,

更高的轮廓系数分数与具有更好定义的集群的模型相关。轮廓系数是为每个样本定义的,由两个分数组成: `

a: The mean distance between a sample and all other points in the same class.

b: The mean distance between a sample and all other points in the next nearest cluster.

然后给出单个样本的轮廓系数为:

现在,要为 KMeans 找到 k 的最佳值,循环 1..n 以获取 KMeans 中的 n_clusters 并计算轮廓系数每个样本。

更高的轮廓系数表明对象与其自己的集群匹配良好,而与相邻的集群匹配不佳。

from sklearn.metrics import silhouette_score
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans

X = load_iris().data
y = load_iris().target
   
for n_cluster in range(2, 11):
    kmeans = KMeans(n_clusters=n_cluster).fit(X)
    label = kmeans.labels_
    sil_coeff = silhouette_score(X, label, metric='euclidean')
    print("For n_clusters={}, The Silhouette Coefficient is {}".format(n_cluster, sil_coeff))

输出 -

对于 n_clusters=2,轮廓系数为 0.680813620271
对于 n_clusters=3,剪影系数为 0.552591944521
对于 n_clusters=4,轮廓系数为 0.496992849949
对于 n_clusters=5,轮廓系数为 0.488517550854
对于 n_clusters=6,轮廓系数为 0.370380309351
对于 n_clusters=7,轮廓系数为 0.356303270516
对于 n_clusters=8,轮廓系数为 0.365164535737
对于 n_clusters=9,轮廓系数为 0.346583642095
对于 n_clusters=10,剪影系数为 0.328266088778

我们可以看到,n_clusters=2 具有最高的轮廓系数。也就是说 2 应该是最优的簇数吧?

但这就是问题所在。

Iris 数据集有 3 种花卉,这与 2 作为最佳聚类数相矛盾。因此,尽管 n_clusters=2 具有最高的轮廓系数,我们仍将 n_clusters=3 视为最佳集群数,因为 -

  1. 鸢尾花数据集有 3 个物种。 (最重要)
  2. n_clusters=3 具有第二高的轮廓系数值。

所以选择 n_clusters=3 是最佳选择。虹膜数据集的聚类。

选择最佳编号。集群的数量取决于数据集的类型和我们试图解决的问题。但大多数情况下,采用最高的轮廓系数会产生最佳的聚类数。

希望对你有帮助!

关于python - Scikit Learn - K-Means - 弯头 - 标准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19197715/

相关文章:

python - 移动每行的最后一个非空值 - Pandas

python - 使用 python 从 mysql 行 fetchall 创建具有多个值的嵌套字典

python - 我的模型是否应该始终在训练数据集上提供 100% 的准确率?

python - 如何使用Python的FastFM库(分解机)做推荐任务?

machine-learning - 随机森林子采样中的选定特征

python - Django NameError [应用程序名称] 未定义

python - 如何遍历一行中的列以找到满足某些条件的第一个

machine-learning - 如何评价一个具有相关顺序的建议系统?

python - 提取多个回归变量的网格搜索值

algorithm - 点对点节点的机器学习算法