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 - β2x_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

我认为模式很清楚...您只需要从其余变量中减去一个变量 x1x2x3... ) 并将该变量的系数 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的系数。我们看到所有方法确实导致相同的系数。