寻找k聚类的另一个比肘部法更有用的方法

我在尝试为机器学习中的k-means方法找到合适的k聚类。我使用了肘部法,但它耗时且复杂度高。有人能告诉我另一个替代方法吗?非常感谢


回答:

你可以用来评估聚类结果的一个指标是轮廓系数。这个值基本上是计算出来的:

silhouette coefficient = 1 - (intra-cluster cohesion) / (inter-cluster separation)

这个值的范围是从-1到+1,但通常你希望值更接近1.0。因此,如果你运行一个聚类算法(例如k-means或层次聚类)来生成3个聚类,你可以调用轮廓库来计算一个轮廓系数值,例如0.50。如果你再次运行你的算法来生成4个聚类,你可能会计算出另一个轮廓系数值,例如0.55。你可以得出结论,4个聚类是更好的聚类,因为它有更高的轮廓系数。

以下是我使用R在二维空间中创建三个不同聚类的示例数据集。注意:现实世界的数据永远不会像这样干净,且聚类之间的分隔如此明显。即使是像费希尔 Iris 数据集这样简单的数据,也会在标记的聚类之间有重叠。

enter image description here

然后你可以使用R的轮廓库来计算轮廓系数。(更多信息可以在STHDA网站找到。)以下是轮廓信息的图表。你想要的一个指标在左下角,显示“平均轮廓宽度:xxx”。那个值是所有水平条的平均值。

这是K=2聚类的轮廓系数。

plot(silhouette(kmeans(df, centers=2)$cluster, dist(df)))

enter image description here

这是K=3聚类的轮廓系数。

plot(silhouette(kmeans(df, centers=3)$cluster, dist(df)))

enter image description here

这是K=4聚类的轮廓系数。

plot(silhouette(kmeans(df, centers=4)$cluster, dist(df)))

enter image description here

通过查看轮廓系数,你可以得出结论,K=3聚类是最好的聚类,因为它具有最高的轮廓系数。

你可以通过简单地扫描多个K值候选(例如从2到10)并跟踪找到的最高轮廓系数来以编程方式找到最佳的K值。下面我已经做了同样的事情,同时还构建了一个轮廓系数(y轴)与K值(x轴)的图表。输出显示:

最佳轮廓系数=0.888926出现在k=3

enter image description here

library(cluster) # for silhouettelibrary(ggplot2) # for ggplotlibrary(scales) # for pretty_breaks# 创建包含聚类在点(1,1)、(2,4)和(3,1)周围的二维数据集示例x<- c(rnorm(n=25, mean=1,sd=.1), rnorm(n=25,mean=2,sd=.1),rnorm(n=25,mean=3,sd=.2))y<- c(rnorm(n=25, mean=1,sd=.1), rnorm(n=25,mean=4,sd=.1),rnorm(n=25,mean=1,sd=.2))df <- data.frame(x=x, y=y)xMax <- max(x)yMax <- max(y)print(ggplot(df, aes(x,y)) + geom_point() + xlim(0, max(xMax, yMax)) + ylim(0, max(xMax,yMax)))# 使用Iris数据集。#df <- subset(iris, select=-c(Species))#df <- scale(df)# 运行多个候选K值聚类。xValues <- c() # 保存k值(x轴)yValues <- c() # 保存轮廓系数值(y轴)bestKValue <- 0bestSilhouetteCoefficient <- 0kSequence <- seq(2, 5)for (kValue in kSequence) {    xValues <- append(xValues, kValue)    kmeansResult <- kmeans(df, centers=kValue, nstart=5)    silhouetteResult <- silhouette(kmeansResult$cluster, dist(df))    silhouetteCoefficient <- mean(silhouetteResult[,3])    yValues <- append(yValues, silhouetteCoefficient)    if (silhouetteCoefficient > bestSilhouetteCoefficient) {        bestSilhouetteCoefficient <- silhouetteCoefficient        bestKValue <- kValue    }}# 创建一个数据框供ggplot绘制累积的轮廓值。dfSilhouette <- data.frame(k=xValues, silhouetteCoefficient=yValues)# 创建轮廓系数的ggplot线图。silhouettePlot<- ggplot(data=dfSilhouette, aes(k)) +    geom_line(aes(y=silhouetteCoefficient)) +    xlab("k") +    ylab("平均轮廓宽度") +    ggtitle("平均轮廓宽度") +    scale_x_continuous(breaks=pretty_breaks(n=20)) print(silhouettePlot)printf <- function(...) cat(sprintf(...))printf("最佳轮廓系数=%f出现在k=%d", bestSilhouetteCoefficient, bestKValue )

注意,我使用了来自这里的答案中的printf函数。

与你的问题相关的一个问题在这里

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注