Python2: подгонка многопараметрической суммы функций с помощью scipy.optimize.curve_fit

#python #curve-fitting #least-squares

#python #подгонка кривой #метод наименьших квадратов

Вопрос:

Это мой первый пост о переполнении стека, поэтому, пожалуйста, наберитесь терпения, если какая-либо информация отсутствует.

Я пытаюсь сопоставить функцию с данными, используя Python 2.7.15 (ubuntu 18.04) с помощью scipy.optimize.curve_fit(). Эта функция подгонки состоит из суммы переменного числа экспонент со связанными параметрами, которые передаются через параметр *args моей функции подгонки.

Я попытался передать векторы параметров в мою функцию подгонки. К сожалению, похоже, что сумма экспонент, которую я выполняю с помощью цикла ‘for’, на самом деле интерпретируется как numpy . ndarray, где это должно быть единственное значение, которое будет возвращено алгоритму подгонки. Ниже приведен (упрощенный) пример того, что я пробовал:

 import numpy as np
import scipy
import math
from scipy import optimize

# Fitting function:
def fitFuncTau(amplitude, nFit, t, *args):
    C0=args[0]
    C=list(args[1:(nFit 1)])
    tau=list(args[(nFit 1):(2*nFit 2)])
    sumFit=0
    for i in range(0, nFit):
        sumFit =C[i]*np.exp(-t/tau[i])
    print sumFit
    return C0 amplitude*sumFit

#Fitting Args: C0 parameter, then two lists C[] and tau[] (size Nfit)
fitArgs=[1, 0.01, 0.01, 0.1, 0.1]
nFit=2
amplitude=1

# Dummy fitting data
x=np.linspace(0, 4, 100)
np.random.seed(1729)
y=np.random.normal(size=x.size)

#Fit
wrapFunc=lambda t, *args: fitFuncTau(amplitude, nFit, t, *args)
fit_opt, fit_cov = scipy.optimize.curve_fit(wrapFunc, x, y, p0=fitArgs)
  

Любая помощь будет высоко оценена!

Комментарии:

1. На самом деле не имеет значения, чтобы дать вам ответ, но sum это встроенная функция python. Не используйте sum в качестве имени переменной.

2. Хорошая мысль, спасибо за это! Только что обновил его.

3. Но fit_opt правильно ли это? Имеет ли смысл результат?

Ответ №1:

Попробуйте использовать свою fitFuncTau функцию автономно. fitFuncTau(1, 2, 3, 4, 5, 6, 7, 8) (или любые другие значения, которые вы хотите указать для заполнения правильного количества параметров) выводит только число, а не список.

Я не могу найти какой-либо документ или ссылку, чтобы доказать это, но я думаю, это просто оптимизация печати, выполненная curve_fit() .
Все print вызовы, связанные с каждым элементом x , собираются в список, и список печатается. Если вы проверите, длина печатного списка совпадает с длиной вашего x массива (100 в вашем случае).

Это не должно влиять на результат подгонки. Проверьте, являются ли значения в fit_opt разумными.