Dan*_*iel 4 regression r restriction linear-regression
我正在尝试运行一个简单的OLS回归,并限制两个变量的系数之和为1。
我想要:
Y = ? + ?1 * x1 + ?2 * x2 + ?3 * x3,
where ?1 + ?2 = 1
Run Code Online (Sandbox Code Playgroud)
我发现了如何在系数之间建立关系,例如:
?1 = 2* ?2
Run Code Online (Sandbox Code Playgroud)
但是我还没有找到如何进行限制的方法,例如:
?1 = 1 - ?2
Run Code Online (Sandbox Code Playgroud)
在这个简单的示例中我将如何做?
data <- data.frame(
A = c(1,2,3,4),
B = c(3,2,2,3),
C = c(3,3,2,3),
D = c(5,3,3,4)
)
lm(formula = 'D ~ A + B + C', data = data)
Run Code Online (Sandbox Code Playgroud)
谢谢!
要拥有?1 + ?2 = 1您必须适合的模型是
fit <- lm(Y ~ offset(x1) + I(x2 - x1) + x3, data = df)
Run Code Online (Sandbox Code Playgroud)
那是
Y =?+ x1 +?2 *(x2-x1)+?3 * x3
替换?1 = 1-?2之后 ; x_new = x2 - x1的系数为x11。
fit <- lm(Y ~ offset(x1) + I(x2 - x1) + I(x3 - x1), data = df)
Run Code Online (Sandbox Code Playgroud)
Y =?+ x1 +?2 *(x2-x1)+?3 *(x3-x1)
替代后 ?1 = 1 - ?2 - ?3
我认为,花纹清晰......你只需要减去一个变量,x1从其余变量(x2,x3,...),并具有可变的系数x1,1。
# Data
df <- iris[, 1:4]
colnames(df) <- c("Y", paste0("x", 1:3, collaapse=""))
# ?1 + ?2 = 1
fit <- lm(Y ~ offset(x1) + I(x2 - x1) + x3, data = df)
coef_2 <- coef(fit)
beta_1 <- 1 - coef_2[2]
beta_2 <- coef_2[2]
Run Code Online (Sandbox Code Playgroud)
1) CVXR我们可以通过指定目标和约束直接使用 CVXR 计算系数。我们假设 D 是响应,A 和 B 的系数之和必须为 1,b[1] 是截距,b[2]、b[3] 和 b[4] 是 A、B 和 C 的系数分别。
library(CVXR)
b <- Variable(4)
X <- cbind(1, as.matrix(data[-4]))
obj <- Minimize(sum((data$D - X %*% b)^2))
constraints <- list(b[2] + b[3] == 1)
problem <- Problem(obj, constraints)
soln <- solve(problem)
bval <- soln$getValue(b)
bval
## [,1]
## [1,] 1.6428605
## [2,] -0.3571428
## [3,] 1.3571428
## [4,] -0.1428588
Run Code Online (Sandbox Code Playgroud)
目标是残差平方和,它等于:
soln$value
## [1] 0.07142857
Run Code Online (Sandbox Code Playgroud)
2) pracma我们还可以使用 pracma 包来计算系数。我们指定 X 矩阵、响应向量、约束矩阵(在这种情况下,作为第三个参数给出的向量被视为单行矩阵)以及约束的右侧。
library(pracma)
lsqlincon(X, data$D, Aeq = c(0, 1, 1, 0), beq = 1) # X is from above
## [1] 1.6428571 -0.3571429 1.3571429 -0.1428571
Run Code Online (Sandbox Code Playgroud)
3) limSolve该包还可以求解带约束的回归问题的系数。参数与(2)中相同。
library(limSolve)
lsei(X, data$D, c(0, 1, 1, 0), 1)
Run Code Online (Sandbox Code Playgroud)
给予:
$X
A B C
1.6428571 -0.3571429 1.3571429 -0.1428571
$residualNorm
[1] 0
$solutionNorm
[1] 0.07142857
$IsError
[1] FALSE
$type
[1] "lsei"
Run Code Online (Sandbox Code Playgroud)
4) nls这可以表述为nlsB 系数等于 1 减去 A 系数的问题。
nls(D ~ b0 + b1 * A + (1-b1) * B + b2 * C, data,
start = list(b0 = 1, b1 = 1, b2 = 1))
## D ~ b0 + b1 * A + (1 - b1) * B + b2 * C
## data: data
## b0 b1 b2
## 1.6429 -0.3571 -0.1429
## residual sum-of-squares: 0.07143
##
## Number of iterations to convergence: 1
## Achieved convergence tolerance: 2.803e-08
Run Code Online (Sandbox Code Playgroud)
我们可以使用lm其他答案中的方法仔细检查上述内容:
lm(D ~ I(A-B) + C + offset(B), data)
Run Code Online (Sandbox Code Playgroud)
给予:
Call:
lm(formula = D ~ I(A - B) + C + offset(B), data = data)
Coefficients:
(Intercept) I(A - B) C
1.6429 -0.3571 -0.1429
Run Code Online (Sandbox Code Playgroud)
该I(A-B)系数等于原公式中 的系数A,一减去它就是 的系数C。我们看到所有方法都会产生相同的系数。