Sklearn kmeans的肘部法等效方法

22

假设我正在研究最多10个聚类,使用scipy库通常按以下方式生成“肘部”图:

from scipy import cluster
cluster_array = [cluster.vq.kmeans(my_matrix, i) for i in range(1,10)]

pyplot.plot([var for (cent,var) in cluster_array])
pyplot.show()

我之后变得有动力使用sklearn进行聚类,但是我不确定如何创建需要用于绘图的数组,就像在scipy的情况中一样。我的最佳猜测是:

from sklearn.cluster import KMeans

km = [KMeans(n_clusters=i) for i range(1,10)]
cluster_array = [km[i].fit(my_matrix)]

不幸的是,这导致了一个无效命令错误。sklearn最好的方式是什么?

谢谢

3个回答

49

您可以使用Kmeans类的惯性属性。

假设X是您的数据集:

from sklearn.cluster import KMeans
from matplotlib import pyplot as plt

X = # <your_data>
distorsions = []
for k in range(2, 20):
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(X)
    distorsions.append(kmeans.inertia_)

fig = plt.figure(figsize=(15, 5))
plt.plot(range(2, 20), distorsions)
plt.grid(True)
plt.title('Elbow curve')

13

你的代码中有一些语法问题。现在它们已经被修复:

Ks = range(1, 10)
km = [KMeans(n_clusters=i) for i in Ks]
score = [km[i].fit(my_matrix).score(my_matrix) for i in range(len(km))]
< p > fit 方法返回一个 self 对象。在原始代码的这行中< /p >
cluster_array = [km[i].fit(my_matrix)]

cluster_array 最终将具有与 km 相同的内容。

您可以使用 score 方法来获取聚类适配度的估计值。要查看每个簇的得分,只需运行 plot(Ks, score)


格式化,score = [KMeans(i).fit(my_matrix).score(my_matrix) for i in Ks] - ExtractTable.com
2
稍微更符合Python风格的代码: score = [k.fit(my_matrix).score(my_matrix) for k in km] - Uri London
my_matrix 是如何定义的? - jbehrens94
请用你的数据、数据框等替换我的矩阵 @jbehrens94 - NomNomNom

6
你还可以使用欧几里得距离来计算数据与聚类中心的距离,以确定选择多少个聚类。以下是代码示例。
import numpy as np
from scipy.spatial.distance import cdist
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

iris = load_iris()
x = iris.data

res = list()
n_cluster = range(2,20)
for n in n_cluster:
    kmeans = KMeans(n_clusters=n)
    kmeans.fit(x)
    res.append(np.average(np.min(cdist(x, kmeans.cluster_centers_, 'euclidean'), axis=1)))

plt.plot(n_cluster, res)
plt.title('elbow curve')
plt.show()

1
其他答案使用sklearn kmeans对象的kmeans.inertia_属性来衡量拟合的好坏。sklearn文档中指出:“inertia_:样本到最近的聚类中心的平方距离之和,如果提供了样本权重,则加权。”因此,这与您建议的计算基本相同,但显然会更快,因为我猜测它已经被计算过了。 - gnoodle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接