使用 R 中的相关矩阵自动删除共线变量

Posted

技术标签:

【中文标题】使用 R 中的相关矩阵自动删除共线变量【英文标题】:Automatically remove colinear variables using correlation matrix in R 【发布时间】:2015-05-08 19:03:28 【问题描述】:

我正在尝试以迭代方式自动创建基于矩阵相关的自变量对,然后我会将其放入回归模型中以删除这对中最不重要的一个。

到目前为止,我的代码如下所示:

#Correlation testing on only numeric variables
num.cols <- bind.data[,sapply(bind.data, is.numeric),with=FALSE]
cor.matrix <- cor(num.cols,use="complete.obs")

#Create a table of all pairings of potentially colinear variables
#start the process by hardcoding the first 2 iterations
cor.vars1 <- expand.grid(var1 = colnames(cor.matrix)[1], 
                     var2 = row.names(cor.matrix[which((abs(cor.matrix[,1]) > cor.cutoff) & (abs(cor.matrix[,1]) != 1)),]))
cor.vars1 <- as.data.table(cor.vars1)

cor.vars2 <- expand.grid(var1 = colnames(cor.matrix)[2], 
                     var2 = row.names(cor.matrix[which((abs(cor.matrix[,2]) > cor.cutoff) & (abs(cor.matrix[,2]) != 1)),]))
cor.vars2 <- as.data.table(cor.vars2)
cor.vars <- rbind(cor.vars1, cor.vars2)

#now create for-loop to automatically do the rest
for (i in 3:length(num.cols)) 
  cor.varsn <- expand.grid(var1 = colnames(cor.matrix)[i], 
                       var2 = row.names(cor.matrix[which((abs(cor.matrix[,i]) > cor.cutoff) & (abs(cor.matrix[,i]) != 1)),]))
  cor.vars <- rbind(cor.vars, cor.varsn)

基本思想是对于相关矩阵中的每一列,我想要一个由列名和变量的每一行名组成的扩展网格,这些变量与列变量的相关性大于某个截止值“cor.cutoff”。我将为每一列执行此操作并将它们全部绑定。最后,我将有一个 2 列的 data.table,其中每一行代表一对相关的独立预测变量。

我的问题是,当它到达与其他变量没有相关性的列时,for 循环会中断。它不会跳到满足要求的下一列,而是完全停止。有没有一种优雅的方式来做到这一点而不是“如果”语句?特别是当第一列是问题时(即 cor.vars1 或 cor.vars2 与其他变量没有相关性。

【问题讨论】:

如果您遇到共线性问题,仅查看成对相关可能无法解决所有问题。方差通货膨胀因子之类的东西会更好地为您服务,请参阅car::vif 听起来您正在寻找next 命令。您仍然必须将它与 if 语句一起使用。 (if 语句有什么不雅点??)运行for (i in 1:5) if(i == 3) next; print(i) 暂时无视@Gregor关于实际相关性的观点,你看过which(..., arr.ind = TRUE)吗?例如,尝试which(mtcars &gt; 200, arr.ind = TRUE)。它给出了满足特定标准的行/列对的扩展。 另一种方法是使用 BMA 包中的 bicreg 函数,该函数将为您选择一组最佳变量。 VIF 包对 NA 的处理能力如何? 【参考方案1】:

您可以尝试以下功能:

rmcl = function(cor_mat, threshold) 
  cor_mat = abs(cor_mat)
  stopifnot(sum(cor_mat[is.na(cor_mat)]) == 0) 
  for (i in 1:(nrow(cor_mat) - 1)) 
    for (j in (i+1):ncol(cor_mat)) 
      if(cor_mat[i, j] > threshold) 
        cor_mat[i, ] = rep(NA, ncol(cor_mat))
        break
      
    
  
  idx = which(!is.na(cor_mat[, 1]))
  cor_mat[idx, idx]

诀窍是保持相关矩阵的形状,以便迭代可以继续。

一个例子:

data = data.frame(x1 = rnorm(100), x2 = rnorm(100), x3 = rnorm(100))
# the last 3 columns are in perfect correlation with the first 3.
data$x4 = 2 * data$x1
data$x5 = 2 * data$x2
data$x6 = 2 * data$x3
c = cor(data)
c = rmcl(c, .9)
c


          x4         x5         x6
x4 1.0000000 0.08847400 0.03297110
x5 0.0884740 1.00000000 0.09915481
x6 0.0329711 0.09915481 1.00000000

【讨论】:

以上是关于使用 R 中的相关矩阵自动删除共线变量的主要内容,如果未能解决你的问题,请参考以下文章

matlab,循环执行后自动删除索引变量

R中的熔解相关矩阵

R 中的相关矩阵相关性显示为“?”在网格中

dbwritetable 删除 mysql 中的自动增量字段

我可以删除指针但保留变量吗[关闭]

R:如何删除矩阵中的特定行? [复制]