寻找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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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