我想Y = x1 + x2 + x3 + x4 + x5
使用普通最小二乘法最小化一个简单的线性函数,其约束条件是所有系数的总和必须等于 5。如何在 R 中实现这一点?我见过的所有软件包似乎都允许对单个系数进行约束,但我不知道如何设置影响系数的单个约束。我不依赖于 OLS;如果这需要迭代方法,那也很好。
2 回答
基本数学如下:我们从
mu = a0 + a1*x1 + a2*x2 + a3*x3 + a4*x4
我们想找到a0
-最小化和我们的响应变量a4
之间的SSQ 。mu
y
如果我们将最后一个参数 (say a4
) 替换为 (say)C-a1-a2-a3
以遵守约束,我们最终会得到一组新的线性方程
mu = a0 + a1*x1 + a2*x2 + a3*x3 + (C-a1-a2-a3)*x4
= a0 + a1*(x1-x4) + a2*(x2-x4) + a3*(x3-x4) + C*x4
(注意a4
已经消失了……)
像这样的东西(未经测试!)在 R 中实现它。
原始数据框:
d <- data.frame(y=runif(20), x1=runif(20), x2=runif(20), x3=runif(20), x4=runif(20))
创建一个转换版本,其中除最后一列之外的所有内容都将最后一列“扫除”,例如
x1 -> x1-x4; x2 -> x2-x4; ...
dtrans <- data.frame(y=d$y, sweep(d[,2:4], 1, d[,5], "-"), x4=d$x4)
重命名为
tx1
,tx2
, ... 以尽量减少混淆:names(dtrans)[2:4] <- paste("t",names(dtrans[2:4]),sep="")
系数总和约束:
constr <- 5
现在用偏移量拟合模型:
lm(y~tx1+tx2+tx3,offset=constr*x4,data=dtrans)
使这个更通用并不难。
与简单地为固定优化程序指定约束相比,这需要更多的思考和操作。另一方面,(1)它可以很容易地被包装在一个方便的函数中;(2) 它比调用通用优化器效率更高,因为问题仍然是线性的(实际上比您开始使用的维度小一维)。它甚至可以用大数据来完成(例如biglm
)。(实际上,我想到如果这是一个线性模型,你甚至不需要偏移量,尽管使用偏移量意味着你完成后不必计算a0=intercept-C*x4
。)
既然你说你对其他方法持开放态度,这也可以用二次规划(QP)来解决:
最小化二次目标:平方误差之和,
受线性约束:您的权重总和必须为 5。
假设 X 是您的 n×5 矩阵,Y 是长度(n)的向量,这将解决您的最佳权重:
library(limSolve)
lsei(A = X,
B = Y,
E = matrix(1, nrow = 1, ncol = 5),
F = 5)