Нелинейные наименьшие квадраты: Воспроизведение Matlabs lsqnonlin с помощью Scipy.optimize.least_squares с использованием Levenberg-Marquardt - PullRequest
1 голос
/ 17 октября 2019

Я пытаюсь минимизировать функцию, которая принимает 1-мерный массив длины N и возвращает скаляр через Левенберга-Марквардта (: = 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, я получил ошибку значения:

ValueError: Метод '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:

Метод 'lm' (Левенберг-Марквардт) вызывает оболочку для алгоритмов наименьших квадратов, реализованных в MINPACK (lmder, lmdif). Он запускает алгоритм Левенберга-Марквардта, сформулированный как алгоритм типа области доверия. Реализация основана на бумаге [JJMore], она очень надежна и эффективна со множеством хитрых уловок. Это должен быть ваш первый выбор для неограниченных проблем. Обратите внимание, что он не поддерживает границы. Также это не работает, когда m .

Похоже, что нет реализации LM, которая работает, когда m> = n

Мой вопрос:

Как я могу получить нелинейную минимизацию наименьших квадратов, используя LM как Matlab в Python?

1 Ответ

1 голос
/ 19 октября 2019

Я нашел обходной путь, разделив свою функцию на две части:

  • Первая функция принимает массив и возвращает массив
  • Вторая функция берет обработанный массив изпервая функция и возвращает скалярный вывод

Затем я позволил оптимизатору запустить первую функцию.

В контексте минимального примера сверху:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...