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
目标是残差平方和,它等于:
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 的系数。我们看到所有的方法都会导致相同的系数。