«Ошибка значения: функция модели сгенерировала значения NaN» при подгонке кюве с помощью lmfit

#python #curve-fitting #curve #model-fitting #lmfit

Вопрос:

Я столкнулся с проблемой, когда попытался подогнать некоторые данные под кривую. У меня возникли некоторые ошибки, поэтому я вернулся к основам библиотеки lmfit. Я попытался подогнать кривую под простой пример, и у меня возникла та же проблема.

 import numpy
from lmfit import Model, Parameters

x = numpy.arange(1,20)
y = numpy.arange(1,20)*2

def funTE(x, coeff0, coeff1):
    return x * coeff0   coeff1

model = Model(funTE, independent_vars=['x'], param_names=["coeff0", "coeff1"])  
params = Parameters()
params.add("coeff0", vary=True)
params.add("coeff1", vary=True)
result = model.fit(data=y[:], param=params, x=x[:])
 

Произошла эта ошибка:

 ValueError: The model function generated NaN values and the fit aborted! Please check your model function and/or set boundaries on parameters where applicable. In cases like this, using "nan_policy='omit'" will probably not work.
 

Если кто-нибудь из вас может знать, как я могу это исправить, я был бы очень признателен (уже потерял на это довольно много времени).

Ответ №1:

Во-первых, во-первых, у вас опечатка в последней строке. Фактически вызывается аргумент parameters params . Опечатка появляется в качестве предупреждения, которое в данном случае легко пропустить, учитывая остальную часть обратной связи.

К вашей реальной проблеме. Не назначая начальное значение для ваших параметров, они по умолчанию принимают значение-inf, что и вызывает NaN. Если вы не зададите начальное значение, по умолчанию будет установлена нижняя граница, которую может получить параметр, которая, если также не определена, по умолчанию будет-inf. Я удивлен, что документация не обращает вашего внимания на этот факт огромными красными стрелками и кружками. Или, по крайней мере, выдавать предупреждение, когда создается параметр с начальным значением бесконечности.

Исправление

 params = Parameters()
params.add("coeff0", value=0)
params.add("coeff1", value=0)
# Typo fixed!
result = model.fit(data=y, params=params, x=x)
 

Вы также можете позволить модели автоматически генерировать параметры, но вы должны указать начальное значение, как указано выше, чтобы избежать той же проблемы бесконечности.

 params = model.make_params(coeff0=0, coeff1=0)
 

Кстати, если params аргумент не определен, скрипт будет внутренне генерировать параметры с model.make_params() , что приведет к тому, что все начальные значения будут-inf, как упоминалось выше.


В более общем сценарии, где определены начальные значения, и они все еще получают NaN, вероятно, существует проблема с моделью, которую необходимо решить, например, деление на 0, корни/логарифмы отрицательных чисел, большие значения, которые вызывают переполнение и т. Д.

Ответ №2:

Вы обязательно должны указать начальные значения параметров. Никаких исключений, никогда.

Не указывать начальные значения бессмысленно и должно привести к сообщению об ошибке.