Использование класса Model в lmfit в сочетании с классом Parameter - PullRequest
1 голос
/ 10 июля 2019

Я пытаюсь уместить некоторые данные, используя lmfit.Первоначально я использовал класс Model, который хорошо работал на основе этого примера / учебника: https://lmfit.github.io/lmfit-py/model.html Но затем я хотел добавить некоторые ограничения параметров в модель, поэтому я посмотрел на этот учебник: https://lmfit.github.io/lmfit-py/parameters.html

Тем не менее, у меня есть некоторые проблемы при объединении двух классов, так что они прекрасно работают вместе.Либо он жалуется на то, что функция подгонки пропускает параметры, либо получает недопустимые параметры (это имеет место в примере, который я опубликую), либо я получаю модель, которая фактически не принимает указанные мной параметры.На самом деле я могу решить проблему, используя один из следующих подходов: 1. Передать параметры, используя model.make_params (...), но я бы хотел разделить их по отдельности. 2. Я мог бы использовать Minimizer вместо Model, но яХотелось бы понять, почему они так по-разному реализованы, хотя я ожидал бы, что они будут очень похожи (за исключением того, что они работают с различными типами ввода)

Любая помощь / объяснения будут очень признательны.:)

Этот код основан на примере на странице учебника по параметрам.Здесь я изменил пример так, чтобы вместо класса Minimizer использовался класс Model, который в принципе должен работать, но я почему-то делаю это неправильно.Для сравнения, здесь приведен оригинальный пример (прокрутите вниз): https://lmfit.github.io/lmfit-py/parameters.html

# <examples/doc_parameters_basic.py>
import numpy as np

from lmfit import Model, Parameters

# create data to be fitted
x = np.linspace(0, 15, 301)
data = (5. * np.sin(2*x - 0.1) * np.exp(-x*x*0.025) +
        np.random.normal(size=len(x), scale=0.2))


# define objective function: returns the array to be minimized
def fcn2min(params, x):
    """Model a decaying sine wave and subtract data."""
    amp = params['amp']
    shift = params['shift']
    omega = params['omega']
    decay = params['decay']
    model = amp * np.sin(x*omega + shift) * np.exp(-x*x*decay)
    return model


# create a set of Parameters
params = Parameters()
params.add('amp', value=10, min=0)
params.add('decay', value=0.1)
params.add('shift', value=0.0, min=-np.pi/2., max=np.pi/2)
params.add('omega', value=3.0)

# do fit, here with leastsq model
fitmodel = Model(fcn2min)
result = fitmodel.fit(data, params, x=x)

# calculate final result
final = result.fit_report()

# try to plot results
try:
    import matplotlib.pyplot as plt
    plt.plot(x, data, 'k+')
    plt.plot(x, final, 'r')
    plt.show()
except ImportError:
    pass
# <end of examples/doc_parameters_basic.py>

Но, используя его таким образом, я получаю ошибку

ValueError: Invalid independent variable name ('params') for function fcn2min

Я пытался: указатьвсе параметры в качестве аргументов функции, например

def fcn2min(x, amp, shift, omega, decay):

Но в этом случае у меня не получается подключить параметры модели / функции, и я получаю «подбор», который ничего не делает.

СейчасЯ пробовал что-то вроде указания:

fitmodel = Model(fcn2min, independent_vars=['x'], param_names=params)

Но в этом случае я получаю

Invalid parameter name ('amp') for function fcn2min

Также пробовал что-то вроде этого:

params = fitmodel.make_params()
params.add('amp', value=10, min=0)
...

Но в этом случае ятакже не получают параметры, которые связаны с моделью, что видно из вывода

fitmodel.param_names

, который возвращает пустой список.

1 Ответ

0 голосов
/ 11 июля 2019

Вы путаете функцию модели с классом Model для подгонки кривой с целевой функцией для минимизации общего назначения с помощью minimize или leastsq.Целевая функция будет иметь сигнатуру, например:

 def objective(params, *args): 

, где params - это экземпляр lmfit.Parameters, который необходимо распаковать внутри функции, а *args - необязательные аргументы.Эта функция вернет массив - цель, которая будет минимизирована в смысле наименьших квадратов.

Напротив, функция модели, используемая для создания аппроксимируемой модели, будет иметь сигнатуру типа

 def modelfunc(x, par1, par2, par3, ..., **kws):

, где x - независимая переменная, а par1 ... будетсодержат значения для параметров модели.Функция модели вернет массив, который моделирует данные.

Существует множество примеров использования целевых функций и функций модели в https://github.com/lmfit/lmfit-py/tree/master/examples.. Для моделирования ваших данных вы должны сделать

* 1024.*
...