Kmeans 使用 silhouette_score

数据挖掘 Python scikit-学习 聚类
2021-09-25 14:42:39

我正在使用silhouette_score来找到最佳的 k 值。所以我正在运行一个带有一系列可能 k 值的 for 循环。我在下面添加了我的代码。这个程序需要很长时间才能运行。您能否提出一些改进以提高运行时间?

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from sklearn.cluster import KMeans
from sklearn import metrics

data=np.load(filename)


coeffs=[]


for i in range(2,8):

    clusters=KMeans(n_clusters=i)
    clusters.fit(data)
    labels = clusters.labels_
    sil_coeff = metrics.silhouette_score(data, labels,metric='euclidean')
    coeffs.append(sil_coeff)


coeffs=np.array(coeffs)    
k=np.argmax(coeffs)+2
2个回答

做一些测量来确定你的瓶颈。

在这里,我建议不要使用剪影。因为它比 k-means 慢得多。Silhouette 每次运行都需要 O(n²) 距离计算!

很明显,要加快速度,只需计算和存储一次距离矩阵。这对k-means没有帮助,但它会使多个Silhouette运行得更快一些(它仍然是O(n²),但现在只有数组查找而不是距离计算)。然而,这将无法扩展到大数据。

更好的方法是使用更便宜的启发式来猜测 k 的“最佳”值。无论如何,没有一个这样的措施是完美的。

从算法上讲,您的代码很好。关于为什么您的代码运行缓慢,我的主要猜测是您有很多实例。你到底有多少个实例?

有一些提高速度的方法KMeans,这里有几个:

  • 利用 GridSearchCV

您正在尝试做的是超参数调整。Sklearn 已经有一个内置的方法来使用GridSearchCV来做到这一点。这将优化一些流程。

  • 使用n_jobs论据

这将有助于并行化一些流程

  • MiniBatchKMeans改为使用

MiniBatchKMeans在每一步仅使用部分数据,因此计算距离的成本会更低。

  • 使用预先计算的距离计算轮廓分数

正如其他人提到的那样,计算每个 K 的所有实例之间的距离是没有意义的,因为您的实例不会改变。计算这些距离一次,并将距离矩阵传递为X,并metric="precomputed"根据文档进行设置