是否可以从 R 中的 k 均值聚类计算密度图?

Is it possible to compute the density plot from a k-means clustering in R?

我对我的数据进行了聚类分析并得到了结果。我想在密度图中绘制 k-means=3 的结果,并计算三组之间的交集以生成两个阈值,以便能够划分我的数据。

我的 k-means 代码如下:

library(readxl)
library(ggplot2)
AP <- read_excel("file.xlsx")
ggplot(AP, aes(x = volume)) + geom_density() + geom_vline(aes(xintercept = mean(volume, na.rm = T)),
             colour = "red", linetype ="longdash", size = .8)

library(cluster)
fit3       <- kmeans(AP, 3)
y_cluster3 <- fit3$cluster

fit1       <- kmeans(AP, 1)
y_cluster1 <- fit1$cluster

fit4       <- kmeans(AP, 4)
y_cluster4 <- fit4$cluster

fit2       <- kmeans(AP, 2)
y_cluster2 <- fit2$cluster

clusplot(AP, fit3$cluster, stand=TRUE,color=TRUE, labels=0, lines=0)
clusplot(AP, fit1$cluster, color=TRUE, shade=TRUE, labels=6, lines=0)
clusplot(AP, fit4$cluster, color=TRUE, shade=TRUE, labels=2, lines=0)
clusplot(AP, fit3$cluster, stand=TRUE,color=TRUE, labels=2, lines=0)

这是我想要获取和计算交集的内容:

数据集由不同体积 (v^3) 和比率 (ares/volume) 的值组成。我的分析基于这些比率,我想根据这些比率获得阈值。谢谢!!

您需要重新计算每个簇的密度,并找到其中一个簇的密度高于另一个簇的点,即开关

我以鸢尾花数据集为例:

library(ggplot2)
set.seed(100)
#exclude species
df = iris[,-5]
df$clus = factor(kmeans(df,3)$cluster)
p1 = ggplot(df,aes(x=Sepal.Length,col=clus)) + geom_density()

现在我们为每个聚类子集编写密度函数。关键是要有相同的坐标,使用 from 和 to option from density()

#define x limits
LIMS = range(df$Sepal.Length)
#function to extract y values (i.e density)
dens_grid = function(x,start,end){dens = density(x,from=start,to=end)$y}

# we iterate through each cluster, and get density for each cluster
# from start to end
DM = do.call(cbind,by(df$Sepal.Length,df$clus,dens_grid,start=LIMS[1],end=LIMS[2]))
# xcoordinates
xcoord = density(df$Sepal.Length,from=LIMS[1],to=LIMS[2])$x

我们可以看看这个密度矩阵,它从左边开始(x 在 4.3),其中簇 3 的密度比其他簇高..

head(cbind(xcoord,DM))
       xcoord            1            2         3
[1,] 4.300000 0.0002591290 3.547236e-17 0.2362330
[2,] 4.307045 0.0002982119 4.715919e-17 0.2463309
[3,] 4.314090 0.0003417903 4.890658e-18 0.2563679
[4,] 4.321135 0.0003901271 4.153097e-17 0.2663234
[5,] 4.328180 0.0004453972 8.467460e-17 0.2761633
[6,] 4.335225 0.0005087817 1.222466e-16 0.2858354

对于每一行,我们可以获得密度最高的簇:

apply(DM,1,which.max)
  [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 [38] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 [75] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
[112] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
[149] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[186] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[223] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[260] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[297] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[334] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[371] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[408] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[445] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[482] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

您可以看到它在第 165 个条目左右从 3 切换到 1,并在稍后从 1 切换到 2。要获得这些 "switches",我们需要

switches=which(diff(apply(DM,1,which.max))!=0)+1
xcoord[switches]
[1] 5.455382 6.279648

p1 + geom_vline(xintercept=xcoord[switches])