我已经有一段时间没有处理过任何非线性函数拟合(优化)问题了。以前我在C++或C库中熟悉它们。我最熟悉的算法是Levenberg马夸特算法,这是一种阻尼梯度下降算法。它通常提供解析指定函数导数或数值计算函数导数的能力。
我现在正在使用Python处理一个优化问题。看起来Python通过scipy包optimize.least_squares
提供了对使用Levenberg马夸特算法进行优化的支持。接口的形式是,这个函数期望接收一个残差数组。残差是(data - model)。它似乎是 * 最小化 * 残差的平方和,乘以1/2的因子。
除非我误解了什么,否则这使得API非常特定于最小二乘拟合问题,并且它不能以更一般的方式使用,例如查找 * 最大 * 值而不是最小值。(这是由于残差是平方的事实。因此,即使残差由单个标量值组成,我们也不能通过优化乘以-1的函数的最小值来找到最大值,这是通常的做法)。
这让我想到了两种可能的思路:
1.我误解了文档,或者更有可能,没有找到我正在寻找的函数/API。
- Levenberg马夸特算法并不完全适合这项工作。我认为LM被认为是一个通用的、鲁棒的梯度下降优化器。可能有更合适的东西可以使用,我忽略了为什么其他梯度下降算法更适合在这里使用的原因。
对于上下文,我试图优化(最大化)一个Likestival或Log-Likestival函数。我有一些统计数据,我试图用非线性曲线/模型拟合优化方法建模。
我的问题是,Python/Scipy是否提供了Levenberg马夸特算法实现的接口,可以用于此类目的?如果没有,那么为什么没有,我应该使用什么作为替代方案?
1条答案
按热度按时间kqlmhetl1#
对于这个问题,我有一个部分的答案,尽管从我不能完全肯定的意义上说,这不是一个具体的答案。
这些信息大部分来自 Numerical Recipies in C++。
关于函数最小化问题的信息包含在两章中。有一章是关于函数最小化的,还有一章是关于统计建模的,其中包括一节关于LM算法的。
第一点要注意:
LM算法使用远离最小值的梯度下降来接近最小值所在的区域,然后逐渐过渡到表现为二次求解器,这在最小值的粘性中是合适的,因为导数(通过泰勒)近似线性,并且函数在最小值的区域中近似二次。
此外,最小二乘问题总是有一个全局最小值,因此不存在意外收敛到局部最小值的风险。
总结如下:LM非常适合于最小二乘问题。这并不能解释为什么它不适合于更一般的最小化问题。
Numerical Recipies在一般函数优化部分不包括LMA。
然而,在本节中,我们注意到贪婪算法,如梯度下降,在这方面有缺点。对于具有局部最小值或最大值的函数,梯度下降有很大的机会收敛到局部最小值或最大值,而不是全局最小值或最大值。
梯度下降的另一个缺点是这种方法倾向于采取正交步骤走向最小值,这不是最有效的路线。这是因为每一步都找到假设线性梯度的最小点,如果全局最小值不沿任何矢量基方向,(任何轴),那么它将不一定有效地收敛。(它采取锯齿形或阶梯形路径朝向最小点。)
鉴于上述信息,这是不完整的,我们可能会得出结论,有其他算法,除了LMA,在实践中发现,以提供更好的性能一般的非线性函数优化问题。
应该注意的是,在高度非线性优化问题的上下文中,确定“最佳”算法在一定程度上是一门艺术,因为它是一门科学。它涉及评估不同的算法以及调整各种算法参数。