Scipy Curve_Fit和局部极小值:尽可能快地获得全局极小值

2022-05-23 00:00:00 python scipy curve-fitting least-squares

问题描述

我手头的问题:我正在使用scipycurve_fit来拟合一条曲线(https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html),但在许多情况下,为此类曲线估计的参数引用了许多局部"局部"最小值之一,而不是"全局"最小值。考虑到curve_fit的设计方式,这是意料之中的。尽管如此,我真的需要我的全球最低工资。

为了找到它,我最初的预感是将初始起点相乘,运行多个curve_fit实例,并选择拟合误差最小的实例,但在我个人的初始猜测估计中,我会受到许多偏差的影响(潜在的组合数量可能会很多,这将损害性能)。

您是否碰巧知道如何进行的更好、更快和/或在方法上更合理的方法?(它们不需要传递为最小二乘,如果需要,我可以构建特别的东西)


解决方案

有两种可能的方法。一种方法是对参数空间进行"强力"搜索,为curve_fit中的局部求解器找到候选起点。另一种方法是使用诸如差异进化之类的全局解算器。可以肯定的是,这两种方法都可能比单个curve_fit慢得多,但它们的目标确实是寻找"全局极小值"。在scipy.optimize中,这些方法分别是brutedifferential_evolution。需要注意的是,它们都不是实际上的全局优化器,因为它们都需要所有参数的搜索空间的上下限。尽管如此,在这些范围内,他们确实会尝试找到最佳结果,而不仅仅是接近您的起始值的局部最小值。

一种常见的方法是对每个参数使用brute和中等大小的步长,然后从其中最好的十个步长开始,并从每个参数开始使用Levenberg-MarQuardt(来自leastsq,如curve_fit中所用)。同样,您可以使用differential_evolution,然后进行细化。

您可能会发现lmfit(https://lmfit.github.io/lmfit-py)很有帮助,因为它允许您一次设置模型并在求解器之间切换,包括 brutedifferential_evolutionleastsq。Lmfit还使确定某些参数或为某些参数设置上限/下限变得容易。它还为建模和曲线拟合提供了一个更高级别的界面,并提供了探索参数可信区间的方法。

相关文章