在Python中使用Scipy约束样条拟合

时间:2013-07-29 23:11:42

标签: python numpy pandas scipy curve-fitting

我想知道UnivariateSpline是否允许你限制样条拟合?例如,请考虑以下数据:

 x         y
13    2.404070
12    1.588134
11    1.760112
10    1.771360
09    1.860087
08    1.955789
07    1.910408
06    1.655911
05    1.778952
04    2.624719
03    1.698099
02    3.022607
01    3.303135    

关于平滑函数的选择和作用的讨论可以在早期的帖子here中找到。但是,如果我们施加一个约束,即样条需要单调递减,那么我们应该如何设计拟合样条?

感谢您的帮助!

编辑: 样条曲线不需要完全适合所有点。然而,它应该满足约束(单调递减)。

3 个答案:

答案 0 :(得分:2)

通过使用积分样条作为基函数并将OLS系数约束为非负,可以施加单调性约束。非负性约束使计算解决方案比拟合普通平滑样条更困难。你的scipy软件包很可能没有必要的功能。

Mary Meyer建议在此问题中使用参数空间的一些有趣属性来促进计算。她在她的论文中提供了R代码。请参阅Meyer (2008, AoAS), Inference using shape-restricted regression splines, at 1031

答案 1 :(得分:1)

  • 阅读您关联的问题,我认为您只需要x是单调的。如果您的数据是以x为索引的系列,那么只需执行UnivariateSpline(s.sort())。如果您的数据是数据框架,请执行UnivariateSpline(df.set_index('x')['y'].sort())

  • 尽管y(x)似乎并不是单调的,但实际上你可能想要一个单调样条。我知道无法直接向UnivariateSpline引入约束,但我们可以在拟合样条之前约束数据。产生强迫单调减少"您的数据变体如下:

    pd.expanding_min(s.sort())
    

    每个元素将被到目前为止看到的最小元素替换,从而抑制任何增加。来自此类数据的任何样条曲线也应该是单调的。

  • 最后,通常,对于带约束的曲线拟合,结帐lmfit。它在非线性最小二乘曲线拟合器scipy.optimize上添加了一些功能,这给我带来了很多麻烦。

答案 2 :(得分:0)

pyGAM软件包可以适合形状受约束的样条,包括单调递增的样条,请参见https://pygam.readthedocs.io/en/latest/notebooks/tour_of_pygam.html。 UnivariateSpline无法做到这一点。在R中有很多可以做到这一点的软件包,例如scam软件包(使用平方误差损失)或cobs软件包(使用L1损失)。