R:强制回归系数加起来为 1
R: Force regression coefficients to add up to 1
我正在尝试 运行 一个简单的 OLS 回归,其限制是两个变量的系数之和加起来为 1。
我要:
Y = α + β1 * x1 + β2 * x2 + β3 * x3,
where β1 + β2 = 1
我找到了如何在系数之间建立关系,例如:
β1 = 2* β2
但我还没有找到如何进行限制,例如:
β1 = 1 - β2
在这个简单的示例中我将如何做?
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)
谢谢!
β1 + β2 = 1
要β1 + β2 = 1
你必须适应的模型是
fit <- lm(Y ~ offset(x1) + I(x2 - x1) + x3, data = df)
也就是
Y = α + x1 + β2 * (x2 - x1) + β3 * x3
代入后β1 = 1 - β2; x_new = x2 - x1
并且 x1
的系数为 1。
β1 + β2 + β3 = 1
fit <- lm(Y ~ offset(x1) + I(x2 - x1) + I(x3 - x1), data = df)
Y = α + x1 + β2 * (x2 - x1) + β3 * (x3 - x1)
替换后β1 = 1 - β2 - β3
β1 + β2 + β3 + ... = 1
我认为模式很清楚...您只需要从其余变量中减去一个变量 x1
(x2
、x3
、...
) 并将该变量的系数 x1
设为 1.
示例 β1 + β2 = 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]
1) CVXR 我们可以通过指定 objective 和约束直接使用 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
objective是残差平方和等于:
soln$value
## [1] 0.07142857
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
3) limSolve 这个包也可以求解带有约束的回归问题的系数。参数与 (2) 中的相同。
library(limSolve)
lsei(X, data$D, c(0, 1, 1, 0), 1)
给予:
$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"
检查
我们可以使用另一个答案中的 lm
方法仔细检查以上内容:
lm(D ~ I(A-B) + C + offset(B), data)
给予:
Call:
lm(formula = D ~ I(A - B) + C + offset(B), data = data)
Coefficients:
(Intercept) I(A - B) C
1.6429 -0.3571 -0.1429
I(A-B)
系数等于原公式中A
的系数减一就是C
的系数。我们看到所有方法确实导致相同的系数。
我正在尝试 运行 一个简单的 OLS 回归,其限制是两个变量的系数之和加起来为 1。
我要:
Y = α + β1 * x1 + β2 * x2 + β3 * x3,
where β1 + β2 = 1
我找到了如何在系数之间建立关系,例如:
β1 = 2* β2
但我还没有找到如何进行限制,例如:
β1 = 1 - β2
在这个简单的示例中我将如何做?
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)
谢谢!
β1 + β2 = 1
要β1 + β2 = 1
你必须适应的模型是
fit <- lm(Y ~ offset(x1) + I(x2 - x1) + x3, data = df)
也就是
Y = α + x1 + β2 * (x2 - x1) + β3 * x3
代入后β1 = 1 - β2; x_new = x2 - x1
并且 x1
的系数为 1。
β1 + β2 + β3 = 1
fit <- lm(Y ~ offset(x1) + I(x2 - x1) + I(x3 - x1), data = df)
Y = α + x1 + β2 * (x2 - x1) + β3 * (x3 - x1)
替换后β1 = 1 - β2 - β3
β1 + β2 + β3 + ... = 1
我认为模式很清楚...您只需要从其余变量中减去一个变量 x1
(x2
、x3
、...
) 并将该变量的系数 x1
设为 1.
示例 β1 + β2 = 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]
1) CVXR 我们可以通过指定 objective 和约束直接使用 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
objective是残差平方和等于:
soln$value
## [1] 0.07142857
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
3) limSolve 这个包也可以求解带有约束的回归问题的系数。参数与 (2) 中的相同。
library(limSolve)
lsei(X, data$D, c(0, 1, 1, 0), 1)
给予:
$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"
检查
我们可以使用另一个答案中的 lm
方法仔细检查以上内容:
lm(D ~ I(A-B) + C + offset(B), data)
给予:
Call:
lm(formula = D ~ I(A - B) + C + offset(B), data = data)
Coefficients:
(Intercept) I(A - B) C
1.6429 -0.3571 -0.1429
I(A-B)
系数等于原公式中A
的系数减一就是C
的系数。我们看到所有方法确实导致相同的系数。