我需要生成关于多次测定系数的给定值的数据。 例如,如果我指示R ^ 2 = 0.77,我想生成数据,创建回归模型,R ^ 2 = 0.77
但这些数据必须在一定范围内。例如,sample = 100,我需要4个变量(x1 - dependent var),其中的值范围为5-15。怎么样? 我使用optim
optim(0.77, fn, gr = NULL,
method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN",
"Brent"),
lower = 5, upper = 15,
control = list(), hessian = FALSE)
但我不知道如何为我的目的创建函数fn
。请帮忙写这个函数
答案 0 :(得分:4)
首先,这是一个解决方案:
library(mvtnorm)
get.r <- function(x) c((x+sqrt(x**2+3*x))/(3),(x-sqrt(x**2+3*x))/(3))
set.seed(123)
cv <- get.r(0.77)[1]
out <- rmvnorm(100,sigma=matrix(c(1,cv,cv,cv,cv,1,cv,cv,cv,cv,1,cv,cv,cv,cv,1),ncol=4))
out1 <- as.data.frame(10*(out-min(out))/diff(range(out))+5)
range(out1)
# [1] 5 15
lm1 <- lm(V1~V2+V3+V4,data=out1)
summary(lm1)
# Call:
# lm(formula = V1 ~ V2 + V3 + V4, data = out1)
#
# Residuals:
# Min 1Q Median 3Q Max
# -1.75179 -0.64323 -0.03397 0.64770 2.23142
#
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 0.36180 0.50940 0.710 0.479265
# V2 0.29557 0.09311 3.175 0.002017 **
# V3 0.31433 0.08814 3.566 0.000567 ***
# V4 0.35438 0.07581 4.674 9.62e-06 ***
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 0.927 on 96 degrees of freedom
# Multiple R-squared: 0.7695, Adjusted R-squared: 0.7623
# F-statistic: 106.8 on 3 and 96 DF, p-value: < 2.2e-16
现在让我解释一下我是如何到达那里的。我们可以在统计上构建这个。首先,我们需要了解一点关联和协方差。一个相关公式是
Corr(X,Y)= Cov(X,Y)/ sqrt(Var(X)Var(Y))
协方差的一个公式是:
Cov(X,Y)= E(XY)-E(X)E(Y)
在您的问题中,您希望获得回归模型的多重关联:
Y = X1 + X2 + X3
让这个尽可能简单,并强制所有变量的方差为1,让任意两个变量之间的成对相关相等,并将其称为r。
现在我们正在寻找Y和X1 + X2 + X3之间相关性的平方,即:
R ^ 2 = [Cov(Y,X1 + X2 + X3)] ^ 2 / [Var(Y)Var(X1 + X2 + X3)]
请注意
Cov(Y,X1 + X2 + X3)= Cov(Y,X1)+ Cov(Y,X2)+ Cov(Y,X3)
进一步注意,每个变量的方差为1,成对相关为r,因此上述结果相当于3r。
另请注意
Var(X1 + X2 + X3)= Var(X1)+ Var(X2)+ Var(X3)+ Cov(X1,X2)+ Cov(X1,X3)+ Cov(X2,X3)。
由于每个的方差为1,这相当于3 + 6r,所以
R ^ 2 = 9r ^ 2 /(3 + 6r)= 3r ^ 2 /(1 + 2r)
我们可以使用二次方程来求解r和得到
r =(R ^ 2 +/- sqrt((R ^ 2)^ 2 + 3R ^ 2))/ 3
如果我们用R ^ 2 = 0.77代替,则r = -0.3112633或0.8245966。我们可以使用rmvnorm()
包中的mvtnorm
来获取您需要的内容。由于R ^ 2对线性变换是不变的,我们可以将结果变量转换为5到15之间。
<强>更新强>
如果我们想要使用n
个预测变量进行模拟,我们可以使用以下内容(请注意,我并没有改变每个预测变量的范围,但可以在不改变多个R ^ 2的情况下完成) :
get.r <- function(x,n) c(((n-1)*x+sqrt(((n-1)*x)**2+4*n*x))/(2*n),
((n-1)*x-sqrt(((n-1)*x)**2+4*n*x))/(2*n))
sim.data <- function(R2, n) {
sig.mat <- matrix(get.r(R2,n+1)[1],n+1,n+1)
diag(sig.mat) <- 1
out <- as.data.frame(rmvnorm(100,sigma=sig.mat))
return(out)
}
答案 1 :(得分:2)
这不是答案,但我想分享我的所作所为。我不相信optim
可以按照你想要的方式使用。我尝试了一种“蛮力”方法来找到一个可行的数据集,但最高的r平方我“randomed”是0.23:
# Initializing our boolean and counter.
rm(list = ls())
Done <- FALSE
count <- 1
maxr2 <- .000001
# I set y ahead of time.
y <- sample(5:15, 100, replace = TRUE)
# Running until an appropriate r-squared is found.
while(!Done) {
# Generating a sample data set to optimize y on.
a <- sample(5:15, 100, replace = TRUE)
b <- sample(5:15, 100, replace = TRUE)
c <- sample(5:15, 100, replace = TRUE)
data <- data.frame(y = y, a = a, b = b, c = c)
# Making our equation and making a linear model.
EQ <- "y ~ a + b + c" # Creating the equation.
model <- lm(EQ, data) # Running the model.
if (count != 1) { if (summary(model)$r.squared > maxr2) { maxr2 <- summary(model)$r.squared } }
r2 <- summary(model)$r.squared # Grabbing the r-squared.
print(r2) # Printing r-squared out to see what is popping out.
if (r2 <= 0.78 & r2 >= 0.76) { Done <- TRUE } # If the r-squared is satfisfactory, pop it out.
count <- count + 1 # Incrementing our counter.
if (count >= 1000000) { Done <- TRUE ; print("A satisfactory r-squared was not found.") } # Setting this to run at most 1,000,000 times.
}
# Data will be your model that has an r-squared of 0.77 if you found one.
optim
的问题在于它优化了单个参数,单个值。 optim
中的第一个参数是par
参数,它是要优化的值的列表。这可以用于通过某些衰减函数来优化r平方,该函数依赖于几个值(这些值将是您的par
值)。但是,在这种情况下,您要求优化整个列以最大化r平方,这对optim
来说没有意义(据我所知)。