Создание модели Python lmfit с произвольным количеством параметров

Есть ли способ построить модель lmfit на основе функции с произвольным количеством зависимых переменных? Например:

from lmfit import Model

def my_poly(x, *params):
  func = 0
  for i in range(len(params)):
    func+= params[i]*z**i
  return func

#note: below does not work
my_model = Model(my_poly, independent_vars = ['x'], param_names = ['A','B','C'])

Что-то подобное приведенному выше было бы замечательно, если бы меня интересовала серия полиномов и я хотел бы проверить производительность при увеличении или уменьшении серии.


person Brian Pollack    schedule 03.09.2015    source источник


Ответы (1)


Поскольку Model() использует имена аргументов функций для построения имен параметров, использование *params не будет работать легко (как можно узнать, чтобы называть их A, B, C, а не coeff0, coeff1, coeff2 или что-то еще?).

Я не знаю, может ли поддерживаться действительно произвольное число, но должно быть возможно сделать очень большое число. Полиномиальная модель (см. http://lmfit.github.io/lmfit-py/builtin_models.html#polynomialmodel и https://github.com/lmfit/lmfit-py/blob/master/lmfit/models.py#L126 для реализации) поддерживает до 7 коэффициентов. Не должно быть проблем расширить это число до гораздо большего числа. Это может легко привести к вычислительным проблемам, но я думаю, что это то, что вы ожидаете исследовать.

Если вы хотите внести небольшое изменение, можно сделать что-то похожее на то, что вы ищете. Это использует аргументы ключевого слова вместо позиционных аргументов и полагается на порядок имен параметров (то есть с sort), чтобы указать, какой коэффициент соответствует какой степени, а не порядок позиционных аргументов. Это может быть похоже на то, что вы ищете:

import numpy as np

from lmfit import Model, Parameters

def my_poly(x, **params):
    val= 0.0
    parnames = sorted(params.keys())
    for i, pname in enumerate(parnames):
        val += params[pname]*x**i
    return val

my_model = Model(my_poly)

# Parameter names and starting values
params = Parameters()
params.add('C00', value=-10)
params.add('C01', value=  5)
params.add('C02', value=  1)
params.add('C03', value=  0)
params.add('C04', value=  0)

x = np.linspace(-20, 20, 101)
y = -30.4 + 7.8*x - 0.5*x*x + 0.03 * x**3 + 0.009*x**4
y = y + np.random.normal(size=len(y), scale=0.2)

out = my_model.fit(y, params, x=x)
print(out.fit_report())

Надеюсь, это поможет.

person M Newville    schedule 06.09.2015
comment
Превосходно! Я исследовал встроенную полиномиальную модель, но ее трудно использовать в моем реальном анализе. Однако ваше предложение рассматривать kwargs вместо args идеально. Спасибо. - person Brian Pollack; 08.09.2015
comment
Если бы по этой теме было произвольное количество параметров, можно ли было бы сказать, что подходит произвольное количество гауссианцев? т.е. где количество гауссовских моделей варьируется? конечно с пределами скажем от 2 до 10 макс? Заранее спасибо. - person user1301295; 30.06.2016