非线性最小二乘:使用 Levenberg-Marquardt 用Scipy.optimize.least_squares



我正在尝试最小化一个函数,该函数采用长度为 N 的 1d数组并通过 Levenberg-Marquardt (:= LM( 返回标量。

它在 Matlab 中工作:

beta_initial = [-0.7823, -0.1441, -0.7669]; 
% substitution for my long, convoluted function
% but it also works with the proper function
F = @(beta) sum(exp(beta))+3; 
options = optimset('Algorithm','Levenberg-Marquardt');
beta_arma = lsqnonlin(F,beta_initial,[],[],options) % -21.7814  -15.9156  -21.5420
F(beta_arma) % 3

当我在 Python 中尝试时,我遇到了一个值错误:

值错误:当残差数小于变量数时,方法"lm"不起作用。

import numpy as np
from scipy.optimize import least_squares as lsq
# substitution for my long, convoluted function
F = lambda beta: np.sum(np.exp(beta))+3 
beta_initial = [-0.7823, -0.1441, -0.7669]
beta_arma = lsq(F, beta_initial,method='lm')['x']

我理解错误 scipy 的方式要求

out = F(in(,使得 len(out(>= len(in( ,但 matlab 没有

我已经查看了文档,scipy和matlab。

来自 scipy 文档:

方法'lm'(Levenberg-Marquardt(调用MINPACK(lmder,lmdif(中实现的最小二乘算法的包装器。它运行 Levenberg-Marquardt 算法,该算法被表述为信任区域类型算法。该实现基于纸张[JJMore],它非常健壮和高效,有很多聪明的技巧。它应该是您解决不受约束问题的首选。请注意,它不支持边界。当 m 。

看起来没有LM实现在m>=n时有效

我的问题是:

如何使用 LM 获得非线性最小二乘最小化,例如 Python 中的 Matlab?

我通过将函数一分为二找到了解决方法:

  • 第一个函数接受一个数组并返回一个数组
  • 第二个函数从第一个函数获取已处理的数组并返回标量输出

然后,我让优化器在第一个函数上运行。

在上面最小示例的上下文中:

import numpy as np
from scipy.optimize import least_squares as lsq
F1 = lambda beta: np.exp(beta)
F2 = lambda processed_beta: np.sum(np.exp(processed_beta))+3

beta_initial = [-0.7823, -0.1441, -0.7669]
# parameters that minimze F1
beta_arma = lsq(F1, beta_initial,method='lm')['x'] 
F2(beta_arma) # 3.0

最新更新