поиск начальных предположений для подбора экспоненциальной кривой

Поэтому я не знаю, как это сделать, и я не уверен, есть ли какая-то математика, которую я полностью забыл прямо сейчас, но я в растерянности. Короче говоря, у меня есть довольно простой исходный код с использованием scipy и numpy, и я хочу подогнать к нему экспоненциальную кривую:

from scipy.optimize import curve_fit
import numpy as np

# sample data
x = np.array([7620.,   7730.,   7901.,   8139.,   8370.,   8448.,   8737.,   8824., 9089.,   9233.,   9321.,   9509.,   9568.,   9642.,   9756.,   9915.,  10601., 10942.])
y = np.array([0.01228478,  0.01280466,  0.01363498,  0.01493918,  0.01530108, 0.01569484,  0.01628133,  0.01547824,  0.0171548,   0.01743745,  0.01776848, 0.01773898,  0.01839569,  0.01823377,  0.01843686,  0.01875542,  0.01881426, 0.01977975])

# define type of function to search
def model_func(x, a, k, b):
    return a * np.exp(-k*x) + b

# curve fit
p0 = (2.e-6,300,1)
opt, pcov = curve_fit(model_func, x, y, p0)
a, k, b = opt
# test result
x2 = np.linspace(7228, 11000, 3000)
y2 = model_func(x2, a, k, b)
fig, ax = plt.subplots()
ax.plot(x2, y2, color='r', label='Fit. func: $f(x) = %.3f e^{%.3f x} %+.3f$' % (a,k,b))
ax.plot(x, y, 'bo', label='data with noise')
ax.legend(loc='best')
plt.show()

Моя проблема в том, что я пытаюсь, как могу, я не могу определить начальные параметры для p0 - я пробовал диапазон значений, но, честно говоря, я понятия не имею, что я делаю, поэтому я не получаю решения здесь. Может ли кто-нибудь предложить, как это сделать? Благодарю вас!


person kb3hts    schedule 26.07.2017    source источник
comment
К вашему сведению: у @MNewville есть несколько полезных предложений по установке экспоненты здесь: « title = «новая ошибка в старом коде в numpy exp»> stackoverflow.com/questions/45312404/   -  person Warren Weckesser    schedule 27.07.2017
comment
Глядя на ваши данные, вы должны начать с отрицательного значения для a. И, вероятно, не такой большой для k, но я думаю, что Левенберг-Марквардт разберется с этим за вас.   -  person Sven Marnach    schedule 27.07.2017
comment
Имейте в виду, что работа в пространстве журнала невозможна для вашей модели из-за аддитивной константы b.   -  person Sven Marnach    schedule 27.07.2017
comment
Раньше я не использовал curve_fit, но эта точка, похоже, дает ожидаемый результат: p0 = (-2, 1,0/7000, 1)   -  person sbond    schedule 27.07.2017
comment
Авторы scipy добавили генетический алгоритм Differential Evolution в качестве модуля scipy.optimize. Differential_evolution с целью оценки начальных параметров для своих нелинейных решателей. Пример подгонки уравнения двойного пика Лоренца к данным рамановской спектроскопии углеродных нанотрубок с использованием этого модуля scipy для начальной оценки параметров находится здесь: github.com/zunzun/RamanSpectroscopyFit   -  person James Phillips    schedule 28.07.2017


Ответы (1)


Для меня эти данные больше похожи на прямую, чем на экспоненциальную кривую. Вы уверены, что ваша модель верна?

Что касается первоначальных предположений, я предполагаю, что у вас нет дополнительных знаний о функции, если да, используйте ее:

Для x->\inf функция приближается к b. Таким образом, я бы использовал предположение около 0,025 для b. Для двух других переменных возьмите подвыборку x и y и решите уравнение в явном виде:

a * np.exp(-k*x[0]) + 0.025 = y[0]
a * np.exp(-k*x[-1]) + 0.025 = y[-1]

Решение этого дает:

a = (y[0]-0.025)/np.exp(-k*x[0])
e^(-k*(x[-1]-x[0])=(y[-1]-0.025)/(y[0]-0.025) # and then take logarithm

k = -np.log((y[-1]-0.025)/(y[0]-0.025))/(x[-1]-x[0])
a = (y[0]-0.025)/np.exp(-k*x[0])

дает k=0.00026798747972760543 и a=-0.80114087848462689

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

person Jürg Merlin Spaak    schedule 27.07.2017
comment
Я думаю, что данные выглядят как функция насыщения, что и описывает модель, когда a имеет отрицательное значение. Линейная модель не подходит. (Конечно, у него только два параметра вместо трех, поэтому ожидается, что подгонка будет хуже, но дополнительный параметр уменьшает χ² достаточно, чтобы оправдать это.) - person Sven Marnach; 27.07.2017
comment
Полагаться исключительно на первую и последнюю точку данных для начальных предположений — не самый надежный подход, поскольку они могут быть выбросами. Было бы полезнее использовать линейную регрессию в пространстве журнала для определения параметров. - person Sven Marnach; 27.07.2017
comment
Я согласен с тем, что выбор первого и последнего не является надежным, но на самом деле это не обязательно, так как кривая решит проблему. В случае, если кривая не находит решения с этим предположением, вы все равно можете взять другие две выборки или использовать более сложные методы, такие как взятие всех пар выборок и получение среднего значения. Но взяв первое и последнее (или, по сути, любые два произвольных значения), скорее всего, вы сможете найти хорошие начальные догадки. - person Jürg Merlin Spaak; 27.07.2017