【问题标题】:Weighted nonnegative least squares in RR中的加权非负最小二乘
【发布时间】:2018-06-02 00:11:27
【问题描述】:

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

【问题讨论】:

  • 希望此链接对您有所帮助:cran.r-project.org/web/packages/srvyr/vignettes/… srvy 包允许您使用您指定的权重创建矩阵。我使用调查数据并遇到同样的问题。使用此包,您可以创建一个已应用权重的矩阵,并将其与任何其他包一起使用,这样您就不需要包本身包含特定参数来加权数据
  • 我熟悉常规加权最小二乘法,这不是问题 - 我正在寻找一个函数,尽管它允许我将所有系数限制为正...
  • 我认为你可以使用 glmnet 包:stackoverflow.com/questions/35927521/…
  • 是的,我知道 glmnet,它允许权重和约束,并且 lambda 设置为零,它不会进行任何正则化。它比 nnls 慢得多,因此我的问题是在 nnls 中将 X 和 y 乘以 sqrt(weights) 是否正确?

标签: r least-squares


【解决方案1】:

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) * Xsqrt(w) * Y。 (请注意,这些也分别等于diag(sqrt(w)) %*% Xc(diag(sqrt(w)) %*% Y)。)

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

vignette("cvxr_intro")

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

objective <- Minimize(sum((w *(Y - X %*% betaHat)^2)))

3) nls nls 附带的 R 可以做非负加权最小二乘,如果你使用下界为 0 的 port 算法。(在下面的代码中,我们有从零开始,通常从边界开始不是一个好主意,但考虑到这里的线性,这真的无关紧要。)

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

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

【讨论】:

  • 对于我的问题大小加权 nnls 需要 0.25 秒,lambda=0 和 lower.limits=0 的 glmnet 需要 2 秒(慢 8 倍),而 CVXR 需要 95 秒(慢 380 倍)。可惜 CVX 太慢了,因为我喜欢它的灵活性——希望他们将来可以加入像 CPLEX 这样更快的求解器……没有尝试 nls,因为我知道它不是那么健壮……
  • 我建议你也试试 nls。对此的评论确实不准确,尤其是对于像这样的线性问题。
  • 刚刚尝试过,nls 给了我错误“'收敛失败:奇异收敛 (7)'' - 所以不幸的是,这证实了我的怀疑,它往往不是很健壮......
  • 我不会得出这样的结论。如果您的 X 矩阵是单数的,这可能会发生,但这只是意味着您提供了一个模棱两可的规范。
  • 好吧,我确信我的 X 矩阵并不完全是奇异的——即使有很大的共线性......
猜你喜欢
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多