繁体   English   中英

R中的快速非负分位数和Huber回归

[英]Fast nonnegative quantile and Huber regression in R

我正在寻找一种在R中进行非负分位数和Huber回归的快速方法(即约束所有系数都> 0)。 我尝试使用CVXR包进行分位数和Huber回归,并使用quantreg包进行分位数回归,但CVXR非常慢,当我使用非负性约束时, quantreg似乎有问题。 有人知道R中的一个好的和快速的解决方案,例如使用Rcplex包或R gurobi API ,从而使用更快的CPLEX或gurobi优化器?

请注意,我需要运行一个类似于80 000次以下的问题大小,我只需要在每次迭代中更新y向量,但仍然使用相同的预测矩阵X 从这个意义上讲,我觉得在CVXR我现在必须做obj <- sum(quant_loss(y - X %*% beta, tau=0.01)); prob <- Problem(Minimize(obj), constraints = list(beta >= 0))是低效的obj <- sum(quant_loss(y - X %*% beta, tau=0.01)); prob <- Problem(Minimize(obj), constraints = list(beta >= 0)) obj <- sum(quant_loss(y - X %*% beta, tau=0.01)); prob <- Problem(Minimize(obj), constraints = list(beta >= 0))在每次迭代中,当问题实际上保持不变并且我想要更新的全部是y 有没有想过要做得更好/更快?

最小的例子:

## Generate problem data
n <- 7 # n predictor vars
m <- 518 # n cases 
set.seed(1289)
beta_true <- 5 * matrix(stats::rnorm(n), nrow = n)+20
X <- matrix(stats::rnorm(m * n), nrow = m, ncol = n)
y_true <- X %*% beta_true
eps <- matrix(stats::rnorm(m), nrow = m)
y <- y_true + eps

使用CVXR的非负分位数回归:

## Solve nonnegative quantile regression problem using CVX
require(CVXR)
beta <- Variable(n)
quant_loss <- function(u, tau) { 0.5*abs(u) + (tau - 0.5)*u }
obj <- sum(quant_loss(y - X %*% beta, tau=0.01))
prob <- Problem(Minimize(obj), constraints = list(beta >= 0))
system.time(beta_cvx <- pmax(solve(prob, solver="SCS")$getValue(beta), 0)) # estimated coefficients, note that they ocasionally can go - though and I had to clip at 0
# 0.47s
cor(beta_true,beta_cvx) # correlation=0.99985, OK but very slow

非负Huber回归的语法是相同的,但会使用

M <- 1      ## Huber threshold
obj <- sum(CVXR::huber(y - X %*% beta, M))

使用quantreg包的非负分位数回归:

### Solve nonnegative quantile regression problem using quantreg package with method="fnc"
require(quantreg)
R <- rbind(diag(n),-diag(n))
r <- c(rep(0,n),-rep(1E10,n)) # specify bounds of coefficients, I want them to be nonnegative, and 1E10 should ideally be Inf
system.time(beta_rq <- coef(rq(y~0+X, R=R, r=r, tau=0.5, method="fnc"))) # estimated coefficients
# 0.12s
cor(beta_true,beta_rq) # correlation=-0.477, no good, and even worse with tau=0.01...

要加速CVXR,您可以在开始时获取一次问题数据,然后在循环内修改它并将其直接传递给求解器的R接口。 这个代码是

prob_data <- get_problem_data(prob, solver = "SCS")

然后,解析出参数并将它们传递给scs库中的scs。 (参见solver.R中的Solver.solve)。 你将不得不深入研究规范化的细节,但我希望如果你只是在每次迭代时改变y,它应该是一个简单的修改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM