带斜率约束的线性回归

机器算法验证 r 回归 约束回归
2022-02-15 04:40:55

我想在R. 公式就像一样简单。但是我希望斜率()在一个区间内,比如说在 1.4 和 1.6 之间。y=ax+ba

如何才能做到这一点?

4个回答

我想在R中执行......线性回归......我希望斜率在一个区间内,比方说在1.4和1.6之间。如何才能做到这一点?

(i) 简单方法:

  • 拟合回归。如果它在边界内,你就完成了。

  • 如果不在边界内,则将斜率设置为最近的边界,然后

  • 将截距估计为所有观测值(yax)

(ii) 更复杂的方法:在斜率上做带框约束的最小二乘;许多优化例程都实现了框约束,例如nlminb(R 附带)。

编辑:实际上(如下面的例子中提到的),在香草 R 中,nls可以做盒子约束;如示例所示,这真的很容易做到。

您可以更直接地使用约束回归;我认为pcls“mgcv”包中的nnls函数和“nnls”包中的函数都可以。

--

编辑以回答后续问题 -

我将向您展示如何使用它,nlminb因为它带有 R,但我意识到nls已经使用相同的例程(PORT 例程)来实现约束最小二乘,所以我下面的示例就是这种情况。

注意:在下面的示例中,是截距,是斜率(统计数据中更常见的约定)。在我把它放在这里之后,我意识到你是从相反的方向开始的;不过,相对于您的问题,我将把示例“向后”。ab

首先,在范围内设置一些具有“真实”斜率的数据:

 set.seed(seed=439812L)
 x=runif(35,10,30)
 y = 5.8 + 1.53*x + rnorm(35,s=5)  # population slope is in range
 plot(x,y)
 lm(y~x)

Call:
lm(formula = y ~ x)

Coefficients:
(Intercept)            x  
     12.681        1.217  

...但是 LS 估计远远超出了它,只是由随机变化引起的。因此,让我们在 中使用约束回归nls

 nls(y~a+b*x,algorithm="port",
   start=c(a=0,b=1.5),lower=c(a=-Inf,b=1.4),upper=c(a=Inf,b=1.6))

Nonlinear regression model
  model: y ~ a + b * x
   data: parent.frame()
    a     b 
9.019 1.400 
 residual sum-of-squares: 706.2

Algorithm "port", convergence message: both X-convergence and relative convergence (5)

如您所见,您会在边界上看到一个斜坡。如果您将拟合模型传递给summary它,它甚至会产生标准误差和 t 值,但我不确定它们的意义/可解释性。

那么我的建议(1)如何比较?(即将斜率设置为最接近的界限并平均残差以估计截距)ybx

 b=1.4
 c(a=mean(y-x*b),b=b)
       a        b 
9.019376 1.400000

估计是一样的。。。

在下图中,蓝线是最小二乘,红线是约束最小二乘:

约束和 LS 线

Glen_b 的第二种方法,使用带有框约束的最小二乘法,可以通过岭回归更容易地实现。岭回归的解决方案可以看作是回归的拉格朗日函数,该回归在权重向量的范数大小(以及其斜率)上具有界限。所以按照下面 whuber 的建议,方法是减去 (1.6+1.4)/2 = 1.5 的趋势,然后应用岭回归并逐渐增加岭参数,直到斜率的大小小于或等于 0.1。

这种方法的好处是不需要花哨的优化工具,只需要岭回归,它已经在 R(和许多其他包)中可用。

然而 Glen_b 的简单解决方案 (i) 对我来说似乎是明智的 (+1)

另一种方法是使用贝叶斯方法来拟合回归并选择仅在您想要的区域中具有支持的先验分布例如从 1.4 到 1.6 的均匀分布,或者转移并缩放到该域的 beta 分布。a

网络上和软件中有很多使用贝叶斯方法进行回归的示例,您可以按照其中一个示例. a

这个结果仍然会给出感兴趣的参数的可信区间(当然这些区间的意义将基于你之前关于斜率的信息的合理性)。

另一种方法可能是将您的回归重新表述为优化问题并使用优化器。我不确定它是否可以这样重新表述,但是当我阅读有关 R 优化器的这篇博客文章时,我想到了这个问题:

http://zoonek.free.fr/blosxom/R/2012-06-01_Optimization.html