在进行 PCA 和聚类分析时保持与观察相关的分组变量的实用方法

Practical way to keep grouping variables associated with observations when doing PCA and cluster analysis

考虑在此处创建的数据框 data

set.seed(123)
data <- data.frame(State =rep(c("NY","MA","FL","GA"), each = 100),
                   Loc = rep(letters[1:20], each = 20),
                   ID = sample(600,400,replace = F),
                   var1 = rnorm(400),
                   var2 = rnorm(400),
                   var3 = rnorm(400),
                   var4 = rnorm(400),
                   var5 = rnorm(400))

var1:var5 是对个体进行的测量,这些个体是从 Loc 列表示的各个位置随机抽样的,该列嵌套在较大的分组 State 中。每个人都有一个唯一的 ID 编号。请注意 ID 数字没有特定顺序,因此如果没有它们相关的分组变量,测量值相对没有意义。我正在使用 FactoMineRfactoextra 包进行 PCA 和聚类分析。 假设我做了一个 PCA 并决定我想保留前 3 个主要组件(我将坐标存储在一个名为 ind.cords:

的对象中
library(FactoMineR)
library(factoextra)
pca<- PCA(data[,4:8], scale.unit = T, graph = F)
a <- get_pca_ind(pca)
ind.cords <- a$coord[,1:3]

接下来我完成确定最佳聚类数的初步步骤,我决定使用 5 个。我 运行 最终的 kmeans 来获得聚类:

set.seed(123)
clustering <- kmeans(ind.cords, centers = 5, iter.max = 50, nstart = 25)
clustering

这是我遇到问题的地方:fviz_cluster() 使绘制集群变得容易: fviz_cluster(clustering, geom = "point", data = ind.cords) + ggtitle("k = 5") 但我想使用两个分组变量可视化哪些观察属于哪些集群。所以我需要将这些列用作标签。我可以返回到创建 ind.cords 的位置,并将 State LocID 列添加回其中:ind.cords <- cbind(data[,1:3], ind.cors)。 从这里开始,我可以通过指定要对哪些列执行操作(例如,kmeans(ind.cords[4:6]) 来继续,或者我可以创建一个名为 input 的新对象数字列(例如,input <- ind.cords[,4:6]),但在任何一种情况下,我都无法弄清楚如何获得 fviz_ 函数来通过 StateLoc 标记观察结果。有人可以展示一种实用的方法来做到这一点或解释如何重组我进行此分析的方式,以便我可以可视化哪些观察和组在哪些集群中? 最终(除非有人对可视化包含多个组的集群有更好的建议)我相信如果使用彩色文本而不是分组变量的点(StateLoc),可视化集群会更容易, 并在点周围绘制椭圆以显示它们属于哪个集群,所以这就是我在图表中拍摄的内容。

一种方法是在它上面叠加一层,因为我不知道要在 fviz_cluster() 中映射任何其他内容。您可以调整 alpha 以便您可以辨认出它们。 geom_point()

示例
set.seed(123)
data <- data.frame(State =rep(c("NY","MA","FL","GA"), each = 100),
                   Loc = rep(letters[1:20], each = 20),
                   ID = sample(600,400,replace = F),
                   var1 = rnorm(400),
                   var2 = rnorm(400),
                   var3 = rnorm(400),
                   var4 = rnorm(400),
                   var5 = rnorm(400))

library(FactoMineR)
library(factoextra)

pca <- PCA(data[,4:8], scale.unit = T, graph = F)
a <- get_pca_ind(pca)
ind.cords <- a$coord[,1:3]
ind.cords <- cbind(data[,1:3], ind.cords)

clustering <- kmeans(ind.cords[,4:6], centers = 5, iter.max = 50, nstart = 25)

fviz_cluster(clustering, geom = "point", data = ind.cords[,4:6], shape = 16) + ggtitle("k = 5") +
  geom_point(aes(shape = ind.cords$State), alpha = 0.5)

您也可以使用 geom_text():


fviz_cluster(clustering, geom = "point", data = ind.cords[,4:6], shape = 16) + ggtitle("k = 5") +
  geom_text(aes(label = paste0(ind.cords$State, ":", ind.cords$Loc)), alpha = 0.5, size = 3, nudge_y = 0.1, show.legend = FALSE)

reprex package (v0.3.0)

于 2020-06-08 创建

编辑:设置 geom = NULL 也有效,因此您可以抑制 fviz_cluster():

完成的 geom_point()

fviz_cluster(clustering, geom = NULL, data = ind.cords[,4:6], shape = 16) + ggtitle("k = 5") +
  geom_text(aes(label = paste0(ind.cords$State, ":", ind.cords$Loc)), size = 3, show.legend = FALSE)

编辑:与簇的颜色相同:


fviz_cluster(clustering, geom = NULL, data = ind.cords[,4:6]) + 
  ggtitle("k = 5") +
  geom_text(aes(label = paste0(ind.cords$State, ":", ind.cords$Loc),
                color = as.factor(clustering$cluster)),
            size = 3, show.legend = FALSE)