首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Mclust进行集群会产生一个空集群

使用Mclust进行集群会产生一个空集群
EN

Stack Overflow用户
提问于 2020-10-13 02:41:48
回答 1查看 267关注 0票数 1

我正在尝试使用Mclust对我的经验数据进行聚类。当使用下面的代码时,非常简单:

代码语言:javascript
复制
library(reshape2)
library(mclust)

data <- read.csv(file.choose(), header=TRUE,  check.names = FALSE)
data_melt <- melt(data, value.name = "value", na.rm=TRUE)

fit <- Mclust(data$value, modelNames="E", G = 1:7)
summary(fit, parameters = TRUE)

R给出了以下结果:

代码语言:javascript
复制
---------------------------------------------------- 
Gaussian finite mixture model fitted by EM algorithm 
---------------------------------------------------- 

Mclust E (univariate, equal variance) model with 4 components: 

log-likelihood    n df       BIC       ICL
  -20504.71 3258  8 -41074.13 -44326.69

Clustering table:
1    2    3    4 
0 2271  896   91 

Mixing probabilities:
    1         2         3         4 
0.2807685 0.4342499 0.2544305 0.0305511 

Means:
   1        2        3        4 
1381.391 1381.715 1574.335 1851.667 

Variances:
   1        2        3        4 
7466.189 7466.189 7466.189 7466.189 

编辑:这里是我的数据下载https://www.file-upload.net/download-14320392/example.csv.html

我不容易理解为什么Mclust给我一个空的集群(0),特别是与第二个集群的平均值几乎相同的集群。只有在专门寻找单变量等方差模型时才会出现这种情况。例如,使用modelNames="V“或将其保留为默认值,不会产生此问题。

这个线程:Cluster contains no observations有一个类似的问题,但是如果我理解正确的话,这似乎是由于随机生成的数据?

我有点不知道我的问题在哪里,或者我是否遗漏了什么明显的东西。如有任何帮助,我们不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-13 07:01:35

正如你注意到的,集群1和集群2的均值非常相似,而且碰巧那里有相当多的数据(参见直方图上的尖峰):

代码语言:javascript
复制
set.seed(111)
data <- read.csv("example.csv", header=TRUE,  check.names = FALSE)
fit <- Mclust(data$value, modelNames="E", G = 1:7)
hist(data$value,br=50)
abline(v=fit$parameters$mean,
col=c("#FF000080","#0000FF80","#BEBEBE80","#BEBEBE80"),lty=8)

简而言之,mclust或gmm是概率模型,它估计集群的均值/方差以及属于每个集群的每个点的概率。这与k-means提供硬赋值不同。因此,模型的可能性是属于每个集群的每个数据点的概率之和,您可以查看also in mclust's publication

在这个模型中,簇1和簇2的平均值接近,但它们的预期比例不同:

代码语言:javascript
复制
fit$parameters$pro
[1] 0.28565736 0.42933294 0.25445342 0.03055627

这意味着如果你有一个平均值在1或2左右的数据点,它将被一致地分配到集群2,例如,让我们尝试预测从1350到1400的数据点:

代码语言:javascript
复制
head(predict(fit,1350:1400)$z)
             1         2          3            4
[1,] 0.3947392 0.5923461 0.01291472 2.161694e-09
[2,] 0.3945941 0.5921579 0.01324800 2.301397e-09
[3,] 0.3944456 0.5919646 0.01358975 2.450108e-09
[4,] 0.3942937 0.5917661 0.01394020 2.608404e-09
[5,] 0.3941382 0.5915623 0.01429955 2.776902e-09
[6,] 0.3939790 0.5913529 0.01466803 2.956257e-09

通过取具有最大概率的列来获得$classification。所以,同样的例子,所有的东西都被分配给2:

代码语言:javascript
复制
 head(predict(fit,1350:1400)$classification)
[1] 2 2 2 2 2 2

回答你的问题,不,你没有做错任何事情,这是一个后备,至少对于GMM的实现。我想说这有点过度拟合,但你基本上只能选择有成员资格的集群。

如果你使用model="V",我认为解决方案同样有问题:

代码语言:javascript
复制
fitv <- Mclust(Data$value, modelNames="V", G = 1:7)
plot(fitv,what="classification")

使用scikit learn GMM,我没有看到类似的问题..因此,如果您需要使用具有球面均值的高斯混合,请考虑使用模糊kmeans:

代码语言:javascript
复制
library(ClusterR)
plot(NULL,xlim=range(data),ylim=c(0,4),ylab="cluster",yaxt="n",xlab="values")
points(data$value,fit_kmeans$clusters,pch=19,cex=0.1,col=factor(fit_kmeans$clusteraxis(2,1:3,as.character(1:3))

如果不需要相等的方差,也可以使用ClusterR包中的GMM函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64323572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档