我有一个变量ZZ
,其整数级别为1,2或3,我希望尽可能与数据框中的其余变量不相关。
我本质上是通过选择值1,2或3来重新创建变量,以最小化它与其他数据帧变量的相关性。
如何在R中完成此操作?我不清楚如何实现这种选择整数来优化R的机制。
我的函数计算相关的绝对值之和。
mincorr <- function(x){
abs(cor(df[, x], df$PS))+ abs(cor(df[, x], df$PROG))+ abs(cor(df[, x], df$RX))
}
以下是部分数据的示例:
df <- read.table(text="PS PROG RX ZZ
2 2 1 1
2 3 2 2
2 2 2 1
1 2 1 1
2 2 2 2
2 2 2 3
3 2 1 1
2 2 2 1
2 2 1 2
2 2 1 2", header=T)
我认为,由于可能值(1-3)的范围很小,我可以进行网格搜索。
library(NMOF)
gridSearch(mincorr("ZZ"), list(seq(1,3)))$minlevels
当然,上面的代码失败了。我是否需要以某种方式将ZZ的每一行指定为列表中的约束?我的数据集不是太大 - 700行,但我想成像这可能无法管理。任何其他方法也非常感谢。
答案 0 :(得分:0)
这是一个非常原始但可能的解决方案:我们可以使用模拟退火来扰动目标向量,从而最小化相关系数。
tmpx <- sort(sample(1:3, size = 100, replace = T))
df <- data.frame(x = tmpx,
y = sample(tmpx, prob = (1:length(tmpx))^2),
z = sample(tmpx, prob = (length(tmpx):1)^3))
objective_fun <- function(x, df) {
sum(cor(x, df)^2)
}
objective_sann_simple_swap <- function(x, df) {
idx <- sample(seq_along(x), size = 2)
xx <- x
xx[idx] <- x[rev(idx)]
return(xx)
}
optimRes <- optim(par = df$x,
fn = objective_fun,
gr = objective_sann_simple_swap,
method = "SANN",
df = subset(df, select = - x))
newx <- optimRes$par
cor(newx, df)
基本上otim
在objective_sann_simple_swap
的每次迭代中调用SANN
,其中魔法发生,即我们随机地将两个元素相互交换。 (如果你有另一个想法,你可以放在这里)。根据目标函数objective_fun
评估新向量。如果它&#34;优化&#34;目标值(与0的相关性)比这个新的向量保持产生&#34;后代&#34;的概率要大。 (阅读Simulated Annealing works的方式。)
基本上就是这样。对于较大的向量,使用更多迭代(在optim中的控制参数,参见关于SANN的?optim
部分)。希望它有所帮助。