【问题标题】:How to carry out constrained regression in R如何在R中进行约束回归
【发布时间】:2018-06-08 18:22:55
【问题描述】:

假设我有一个简单的回归方程

lm(y~., newdata=df)

我知道如果我想将截距减少到0,我会写

lm(y+0., newdata=df)

但是,有没有办法产生逐步回归,同时将每个系数限制在特定范围内?例如:

step(lm(y~.>1000, newdata=df)

上述方法不起作用,但有没有办法说产生一个回归,基本上产生最佳拟合并强制每个系数大于 1,000?或者,小于指定范围。

#as per Gautam    
minfunc <- function(coefs){
      out <- sum(sapply(3:314, function(z) return(coefs[z]*test2[, z])))
      return(out)
    }


    par = c(1, 1, 30) # initial value
    lb = c(-1, -1, -300000) # lower bound for coefs
    ub = c(30, 30, 30000) # upper bound 

    result <- hjkb(par = par, fn = minfunc, lower = lb, upper = ub)

谢谢,

【问题讨论】:

  • 您可以在 R 中运行约束优化。基本上,系数是未知的,但有界。要解决此问题,您可以选择最小化平方误差(或 RMSE)。您希望理想地选择无梯度算法。查看dfoptim 库。
  • @Gautam 感谢您的回复。我实际上一直在研究这个并玩弄代码。但无法弄清楚如何正确编码。请注意,我在过去 2-3 周内只使用 R。因此,新手。有没有办法以这种方式对其进行编码以包含所有变量,而无需手动输入所有 300 个独立变量,我使用“。”与上面的 lm() 类似?
  • 是的,我将在答案中发布一个示例 - 太长,无法在此处发布。
  • sapply 中的参数不正确 - 它必须是向量。 sapply(3:314, function(z) ... ) 应该可以工作。
  • 我的错,你不需要它是data.tabledata.frame 很好。您也可以删除库。我之前打算使用另一种方法,但后来改变了主意。

标签: r regression


【解决方案1】:

这是一个应该可以工作的代码。您需要调整边界等以获得您想要的。

library(data.table)
library(dfoptim)

minfunc <- function(coefs){
  # using mtcars as the sample data - you would read in your data here
  df <- as.data.table(mtcars)

  out <- (sum(coefs[1]*df$cyl + coefs[2]*df$wt + coefs[3]) - sum(df$mpg))^2
  return(out)
}


par = c(1, 1, 30) # initial value
lb = c(-1, -1, -300000) # lower bound for coefs
ub = c(30, 30, 30000) # upper bound 

result <- hjkb(par = par, fn = minfunc, lower = lb, upper = ub)

对比lm

> lm(mpg ~ cyl + wt, data = mtcars)

Call:
lm(formula = mpg ~ cyl + wt, data = mtcars)

Coefficients:
(Intercept)          cyl           wt  
     39.686       -1.508       -3.191  

> result$par
[1]  0.00000 -1.00000 23.30788 
#        cyl       wt constant

结果与预期不同。收敛和最终结果取决于优化算法的选择和初始输入。我以hjkb 为例,但它不是最好的算法。您可能想根据自己的需要尝试不同的算法。

【讨论】:

  • 您好,感谢您提供的示例答案。要实现的问题需要我输入所有 300 个系数。有没有办法说代码应该选择所有系数并将算法应用于所有?
  • 您可以使用rep 指定coefs 的初始值和边界(例如rep(4, ncols(df)))。对于乘法,将数据转换为矩阵并使用crossprod 或使用sapply 等(例如sum(sapply(1:ncol(df), function(z) return(coefs[z]*df[, z]))))。得到你想要的。
  • 我仍然有问题,我更新了 OP 以显示我迄今为止在您的帮助下所做的工作。
猜你喜欢
  • 2021-01-27
  • 2014-01-30
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多