R 中的加权非负最小二乘法

Tom*_*ers 2 r least-squares

我想在 R 中执行加权非负最小二乘法(即所有拟合系数 >=0 的约束)。nnls包中的函数似乎nnls不支持权重。我是否正确,我可以通过将协变量矩阵和因变量乘以向量的平方根weights来在函数内进行模拟,正如此处所示?或者有更好的方法来做到这一点吗?nnlsXyweights

G. *_*eck 5

1) nnls是的,它是等价的,因为加权最小二乘最小化:

sum( w * (Y - X %*% beta)^2 )
= sum_i( (sqrt(w[i]) * X[i, ] %*% beta - sqrt(w[i]) * Y[i])^2 )
Run Code Online (Sandbox Code Playgroud)

受约束,其中 sum_i 表示 i 上的总和。因此sqrt(w[i])将 X 的第 i 行与 Y 的第 i 个元素相乘,相当于使用 sqrt(w) * Xsqrt(w) * Y。(请注意,它们也分别等于diag(sqrt(w)) %*% Xc(diag(sqrt(w)) %*% Y)。)

2)CVXR CVXR包可以直接做加权非负最小二乘。在其小插图中有一个执行非负最小二乘的示例。

vignette("cvxr_intro")
Run Code Online (Sandbox Code Playgroud)

只需更改代码中的目标即可添加权重:

objective <- Minimize(sum((w *(Y - X %*% betaHat)^2)))
Run Code Online (Sandbox Code Playgroud)

nls3)如果你使用下界全为0的算法,R自带的nlsport可以做非负加权最小二乘。(在下面的代码中,我们从零开始,通常从边界开始不是一个好主意但考虑到这里的线性,这实际上并不重要。)

zeros <- numeric(ncol(X))
nls(Y ~ X %*% b, start = list(b = zeros), weights = w, lower = zeros, alg = "port")
Run Code Online (Sandbox Code Playgroud)

运行所有三种方法来仔细检查答案。