我想在R中执行加权非负最小二乘(即,所有拟合系数都> = 0的约束)。 nnls
包中的nnls
函数似乎不支持权重。我是否正确,我可以在weights
函数内模拟nnls
,将协变量矩阵X
和因变量y
乘以{{1的平方根}} vector,似乎表示为here?或者有更好的方法来做到这一点吗?
答案 0 :(得分:4)
1)nnls 是的,它是等价的,因为加权最小二乘最小化:
sum( w * (Y - X %*% beta)^2 )
= sum_i( (sqrt(w[i]) * X[i, ] %*% beta - sqrt(w[i]) * Y[i])^2 )
受制约束,其中sum_i表示对i求和。因此sqrt(w[i])
乘以X的第i行和Y的第i个元素,相当于使用sqrt(w) * X
和sqrt(w) * Y
。 (请注意,它们也分别等于diag(sqrt(w)) %*% X
和c(diag(sqrt(w)) %*% Y)
。)
2)CVXR CVXR包可以直接进行加权非负最小二乘。有一个例子是在其小插图中执行非负最小二乘法。
vignette("cvxr_intro")
只需更改代码中的目标即可添加权重:
objective <- Minimize(sum((w *(Y - X %*% betaHat)^2)))
3)nls nls
如果您使用port
算法,其下限为全0,则R可以执行非负加权最小二乘。(在下面的代码我们从零开始,通常从边界开始并不是一个好主意但是在这里给出线性并不重要。)
zeros <- numeric(ncol(X))
nls(Y ~ X %*% b, start = list(b = zeros), weights = w, lower = zeros, alg = "port")
运行所有三种方法来仔细检查答案。