r - 如何使用 FactoMineR 包以编程方式确定主成分的列索引?

标签 r cluster-analysis pca feature-selection unsupervised-learning

给定一个包含混合变量(即分类变量和连续变量)的数据框,例如,

digits = 0:9
# set seed for reproducibility
set.seed(17)
# function to create random string
createRandString <- function(n = 5000) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}

df <- data.frame(ID=c(1:10), name=sample(letters[1:10]),
                 studLoc=sample(createRandString(10)),
                 finalmark=sample(c(0:100),10),
                 subj1mark=sample(c(0:100),10),subj2mark=sample(c(0:100),10)
                 )

我使用包 FactoMineR 执行无监督特征选择
df.princomp <- FactoMineR::FAMD(df, graph = FALSE)

变量 df.princomp是一个列表。

此后,为了可视化我使用的主要组件fviz_screeplot()fviz_contrib()喜欢,
#library(factoextra)
factoextra::fviz_screeplot(df.princomp, addlabels = TRUE,
                           barfill = "gray", barcolor = "black",
                           ylim = c(0, 50), xlab = "Principal Component", 
                           ylab = "Percentage of explained variance",
                           main = "Principal Component (PC) for mixed variables")

factoextra::fviz_contrib(df.princomp, choice = "var", 
                         axes = 1, top = 10, sort.val = c("desc"))

这给出了以下图1

enter image description here

和图2

enter image description here

图1说明 :Fig1 是碎石图。碎石图是一个简单的线段图,它显示了由每个主成分 (PC) 解释或表示的数据中总方差的比例。所以我们可以看到前三台PC共同负责43.8%的总方差。现在自然会出现一个问题,“这些变量是什么?”。我已经在图2中展示了这一点。

图2说明 :此图从主成分分析 (PCA) 的结果中可视化行/列的贡献。从这里我可以看到变量,name , studLocfinalMark是最重要的变量,可用于进一步分析。

进一步分析 - 我被困在 :推导出上述变量的贡献name , studLoc , finalMark .我使用主成分变量 df.princomp (见上文)喜欢 df.princomp$quanti.var$contrib[,4]df.princomp$quali.var$contrib[,2:3] .

我必须手动指定列索引 [,2:3][,4] .

我要什么 : 我想知道如何进行动态列索引分配,这样我就不必手动编码列索引[,2:3]在列表中 df.princomp ?

我已经看过以下类似的问题 1 , 2 , 34但找不到我的解决方案?任何解决此问题的帮助或建议都会有所帮助。

最佳答案

不确定我对您问题的解释是否正确,如果不正确,请道歉。据我所知,您正在使用 PCA 作为初始工具,向您展示哪些变量在解释数据集时最重要。然后,您希望返回原始数据,快速选择这些变量,而无需每次都手动编码,并将它们用于其他一些分析。

如果这是正确的,那么我已经保存了贡献图中的数据,过滤掉了贡献最大的变量,并使用该结果创建了一个仅包含这些变量的新数据框。

digits = 0:9
# set seed for reproducibility
set.seed(17)
# function to create random string
createRandString <- function(n = 5000) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}

df <- data.frame(ID=c(1:10), name=sample(letters[1:10]),
                 studLoc=sample(createRandString(10)),
                 finalmark=sample(c(0:100),10),
                 subj1mark=sample(c(0:100),10),subj2mark=sample(c(0:100),10)
)

df.princomp <- FactoMineR::FAMD(df, graph = FALSE)

factoextra::fviz_screeplot(df.princomp, addlabels = TRUE,
                           barfill = "gray", barcolor = "black",
                           ylim = c(0, 50), xlab = "Principal Component", 
                           ylab = "Percentage of explained variance",
                           main = "Principal Component (PC) for mixed variables")

#find the top contributing variables to the overall variation in the dataset
#here I am choosing the top 10 variables (although we only have 6 in our df).
#note you can specify which axes you want to look at with axes=, you can even do axes=c(1,2)

f<-factoextra::fviz_contrib(df.princomp, choice = "var", 
                         axes = c(1), top = 10, sort.val = c("desc"))

#save data from contribution plot
dat<-f$data

#filter out ID's that are higher than, say, 20

r<-rownames(dat[dat$contrib>20,])

#extract these from your original data frame into a new data frame for further analysis

new<-df[r]

new

#finalmark name    studLoc
#1         53    b POTYQ0002N
#2         73    i LWMTW1195I
#3         95    d VTUGO1685F
#4         39    f YCGGS5755N
#5         97    c GOSWE3283C
#6         58    g APBQD6181U
#7         67    a VUJOG1460V
#8         64    h YXOGP1897F
#9         15    j NFUOB6042V
#10        81    e QYTHG0783G

根据您的评论,您说要“在 Dim.1 AND Dim.2 中查找值大于 5 的变量并将这些变量保存到新的数据框中”,我会这样做:
#top contributors to both Dim 1 and 2

f<-factoextra::fviz_contrib(df.princomp, choice = "var", 
                         axes = c(1,2), top = 10, sort.val = c("desc"))

#save data from contribution plot
dat<-f$data

#filter out ID's that are higher than 5

r<-rownames(dat[dat$contrib>5,])

#extract these from your original data frame into a new data frame for further analysis

new<-df[r]

new

(这将所有原始变量保留在我们的新数据框中,因为它们都对总方差的贡献超过 5%)

关于r - 如何使用 FactoMineR 包以编程方式确定主成分的列索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51379618/

相关文章:

r - PCA 使用行而不是列作为变量

r - 没有适用于 'anti_join' 的方法应用于类 "factor"的对象

r - R data.table i = MYVAR!=%like% “something|somethingelse|somethingmore”,

r - 在R中,使用gridBase在绘图中嵌入子图时如何防止pdf中出现空白页

python - 使用 Numpy 实现 PCA

python - python中PCA的内存错误

c++ - 是否有一个 c++ 矩阵库,我可以在其中像 R 中那样使用非连续 vector 索引矩阵?

data-mining - 来自观察集合的高维聚类

r - clusplot - 显示变量

machine-learning - 使用sklearn DBSCAN模型对新条目进行分类