使用 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 > 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 中的相关矩阵自动删除共线变量的主要内容,如果未能解决你的问题,请参考以下文章