Scikit学习-K-平均-肘部-标准

2024-06-11 19:12:05 发布

您现在位置:Python中文网/ 问答频道 /正文

今天我想学习一些关于K-means的知识。我了解算法,也知道它是如何工作的。现在我在找合适的k。。。我发现肘部标准是一种检测右k的方法,但我不知道如何使用它与scikit学习?!在scikit中,我以这种方式对事物进行聚类

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

那么,对于n_簇=1…n,我应该多次这样做,并以错误率观察以得到正确的k吗?你觉得这会很愚蠢而且会花很多时间?!


Tags: 方法算法data标准init方式聚类scikit
2条回答

如果事先不知道真正的标签(如您的情况),那么可以使用肘部标准或轮廓系数来计算K-Means clustering

肘部标准法:

elbow方法的思想是在给定的数据集上对k(num_clusters,例如k=1到10)的一系列值运行k-means聚类,并对k的每个值计算平方误差之和(SSE)。

之后,为k的每个值绘制一个SSE的线图。如果线图看起来像一个arm-线图下面的一个红色圆圈(类似角度),那么arm上的“肘”就是最优k的值(簇数)。 在这里,我们要最小化SSE。当我们增加k时,SSE趋向于减少到0(当k等于数据集中的数据点数量时,SSE为0,因为每个数据点都是它自己的集群,并且它与集群中心之间没有错误)。

因此,我们的目标是选择一个SSE仍然较低的small value of k,肘部通常表示我们通过增加k开始有递减回报的地方

让我们考虑一下iris数据集

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是虹膜数据集的最佳簇数(红色包围),这是正确的。



轮廓系数法:

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.

单样本的轮廓系数如下:

s=b-a/max(a,b)

现在,为了找到KMeansk的最佳值,对KMeans中的n个簇循环1..n,并计算每个样本的轮廓系数。

较高的轮廓系数表明对象与自身的簇匹配良好,与相邻的簇匹配较差。

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_簇=2时,轮廓系数为0.680813620271
对于n_簇=3,轮廓系数为0.552591944521
对于n_簇=4,轮廓系数为0.496992849949
n_簇=5时,轮廓系数为0.488517550854
当n_簇=6时,轮廓系数为0.370380309351
n_簇=7时,轮廓系数为0.356303270516
n_簇=8时,轮廓系数为0.365164535737
对于n_簇=9,轮廓系数为0.346583642095
n_簇=10时,轮廓系数为0.328266088778

如我们所见,n_簇=2具有最高的轮廓系数。这意味着2应该是集群的最佳数量,对吧?

但有个问题。

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

  1. 虹膜数据集有3种。(最重要)
  2. n_簇=2具有第二高的轮廓系数值。

因此,选择n_clusters=3是虹膜数据集的最佳聚类数。

选择集群的最佳数量将取决于数据集的类型和我们试图解决的问题。但在大多数情况下,采用最高的轮廓系数可以得到最优的簇数。

希望有帮助!

肘部准则是一种直观的方法。我还没有看到一个强有力的数学定义。 但k-means也是一个相当粗糙的启发式方法。

所以是的,你需要用k=1...kmax运行k-means,然后绘制结果SSQ并决定一个“最优”k

有一些k-means的高级版本,比如X-means,它将从k=2开始,然后增加它,直到第二个标准(AIC/BIC)不再改进。平分k-means是一种方法,它也从k=2开始,然后重复地分割集群,直到k=kmax。你也许可以从中提取临时的ssq。

不管怎样,我的印象是,在任何k-mean非常好的实际用例中,您实际上预先知道您需要的k。在这些情况下,k-means实际上不是一个“聚类”算法,而是一个vector quantization算法。E、 g.将图像的颜色数目减少到k(通常您会选择k为例如32,因为那是5位颜色深度,并且可以以比特压缩的方式存储)。或者,在视觉词汇袋中,你可以手动选择词汇的大小。一个流行的值似乎是k=1000。然后你就不太关心“簇”的质量了,但重点是能够将图像减少到1000维稀疏向量。 900维或1100维表示的性能不会有实质性的不同。

对于实际的聚类任务,即当您想要手动分析生成的聚类时,人们通常使用比k-means更高级的方法。K-means更像是一种数据简化技术。

相关问题 更多 >