В этом руководстве по Python вы узнаете, как использовать метод «Python Scipy Curve Fit» для сопоставления данных с различными функциями, включая экспоненциальные и гауссовские.
Метод Curve_fit() модуля scipy.optimize, который применяет нелинейный метод наименьших квадратов для подгонки данных к функции.
Синтаксис:
scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=True, bounds=(- inf, inf), method=None, jac=None, full_output=False, **kwargs)
Где параметры:
- f: функция модели f(x,…). Независимая переменная должна быть первым аргументом, а последующие аргументы должны быть параметрами подгонки отдельно.
- xdata (array_data): это независимая переменная, используемая для измерения данных. Может быть любым объектом, но обычно это должна быть последовательность длины M или массив в форме(k, M) для функций с k предикторами.
- ydata (array_data): массив длиной M с номинально зависимыми данными f(xdata, …).
- p0 (array_data): начальное наилучшее предположение параметров(длина N). Если установлено значение «Нет», все начальные значения будут равны 1.
- sigma: определяет уровень неопределенности данных.
- Absolute_sigma (boolean): если True, вычисленная ковариация параметра pcov представляет абсолютные значения сигмы в его приложении.
- check_finite (boolean): если True, убедитесь, что во входных массивах нет nans или infs, и если они есть, выдайте ValueError. Если входные массивы действительно содержат nans, установка для этого аргумента значения False может незаметно привести к бессмысленным результатам. По умолчанию True.
- bounds (два кортежа): нижняя и верхняя границы параметров. По умолчанию отсутствуют границы. Каждый элемент кортежа должен быть либо массивом с длиной, равной количеству параметров, либо одним элементом.
- bounds: метод оптимизации. Для задач без ограничений по умолчанию используется «lm», а если заданы границы, это «trf». Когда наблюдений меньше, чем переменных, метод «lm» не будет работать, в этой ситуации попробуйте «trf» или «dogbox».
- jac (string, callable): функция с сигнатурой jac(x,…), которая генерирует плотную структуру, подобную массиву, представляющую матрицу Якоби модельной функции относительно параметров. Он будет масштабироваться с использованием предоставленной вами сигмы. Якобиан будет рассчитан математически, если установлено значение «Нет»(по умолчанию). Строковые ключевые слова методов «trf» и «dogbox» можно использовать для выбора конечно-разностной схемы.
- full_output (boolean): эта функция возвращает дополнительные данные в форме infodict, mesg и ier, если True.
Метод Curve_fit() возвращает popt (параметры должны быть установлены на оптимальные значения, чтобы минимизировать сумму квадратов остатков «f(xdata, *popt) – ydata.»), pcov (оценочная ковариация popt. Отклонение оценки параметра предоставляется диагоналями.), infodict (дополнительный словарь вывода с ключами) и mesg (строковое сообщение, содержащее подробную информацию об ответе).
- Метод Curve_fit по Гауссу
- Кривая соответствует нескольким переменным
- Кривая соответствует первоначальному предположению
- Метод Curve_fit() Maxfev
- Экспоненциальная кривая
Метод Curve_fit по Гауссу
Форма диаграммы — это то, что мы называем распределением набора данных, когда рисуем набор данных, например гистограмму. Колоколообразная кривая, обычно называемая гауссовским или нормальным распределением, является наиболее часто встречающейся формой для непрерывных данных.
Давайте подгоним данные к распределению Гаусса, используя метод Curve_fit, выполнив следующие шаги:
- Импортируйте необходимые методы или библиотеки, используя приведенный ниже код Python.
from scipy.optimize import curve_fit import numpy as np import matplotlib.pyplot as plt
- Создайте данные x и y, используя приведенный ниже код.
x_data = [ -7.0, -6.0, -10.0, -9.0, -8.0, -1.0, 0.0, 1.0, 2.0, -5.0, -4.0, -3.0, -2.0, 7.0, 8.0, 3.0, 4.0, 5.0, 6.0, 9.0, 10.0] y_data = [ 8.3, 10.6,1.2, 4.2, 6.7, 15.7, 16.1, 16.6, 11.7, 13.5, 14.5, 16.0, 12.7, 10.3, 8.6, 15.4, 14.4, 14.2, 6.1, 3.9, 2.1]
- Чтобы использовать полезные возможности массивов NumPy, преобразуйте в них x_data и y_data.
x_data = np.asarray(x_data) y_data = np.asarray(y_data) plt.plot(x_data, y_data, 'o')
- Создайте функцию Гаусса, используя приведенный ниже код.
def Gaussian_fun(x, a, b): y_res = a*np.exp(-1*b*x**2) return y_res
- Теперь подгоните данные к функции Гаусса и извлеките необходимые значения параметров, используя приведенный ниже код.
params, cov = curve_fit(Gaussian_fun, x_data, y_data) fitA = params[0] fitB = params[1] fity = Gaussian_fun(x_data, fitA, fitB)
- Постройте подобранные данные, используя приведенный ниже код.
plt.plot(x_data, y_data, '*', label='data') plt.plot(x_data, fity, '-', label='fit') plt.legend()
Кривая соответствует нескольким переменным
Независимые переменные могут быть переданы для «подгонки кривой» как многомерный массив, но наша «функция» также должна позволять это. Давайте разберемся на примере, выполнив следующие шаги:
- Импортируйте необходимые библиотеки или методы, используя приведенный ниже код Python.
from scipy import optimize import numpy as np
- Создайте функцию, которая будет вызывать массив P и распаковывать его в p и q, используя приведенный ниже код.
def fun(P, x, y, z): p,q = P return np.log(x) + y*np.log(p) + z*np.log(q)
- Создайте несколько зашумленных данных, используя приведенный ниже код.
p = np.linspace(0.1,1.2,100) q = np.linspace(1.1,2.1, 100) x, y, z = 8., 5., 9. z = fun((p,q), x, y, z) * 1 + np.random.random(100) / 100
- Определите первоначальное предположение и подгоните данные к нескольким переменным, используя приведенный ниже код.
p0 = 7., 3., 6. print(optimize.curve_fit(fun,(p,q), z, p0))
Кривая соответствует первоначальному предположению
Параметры подгонки первоначально оцениваются с использованием процедуры «подбора кривой» со значениями 1,0. Однако бывают случаи, когда соответствие не сходится, и в этом случае мы должны предложить разумное предположение в качестве отправной точки.
Давайте посмотрим на примере, выполнив следующие шаги:
- Импортируйте необходимые библиотеки или методы, используя приведенный ниже код Python.
from scipy import optimize import numpy as np
Здесь мы укажем некоторые данные, которые одинаково разнесены во времени и диапазоне температур, в надежде, что они будут соответствовать экспоненте, напоминающей зарядный конденсатор. Помимо определения планок погрешностей значений температуры, мы берем этот массив температур и добавляем к нему случайный шум.
def capcitor(x, y, z): return y*(1-np.exp(z*x)) t = np.linspace(0.5,3.0, 9) tempretures = np.array([14.77, 18.47, 20.95, 22.62, 23.73, 24.48, 24.98, 25.32, 25.54]) tempretures = tempretures + 0.4*np.random.normal(size=len(tempretures)) dTempretures = np.array([1.3, 0.8, 1.1, 0.9, 0.8, 0.8, 0.7, 0.6, 0.6])
- Теперь подгоните данные, используя приведенный ниже код.
fit_Params, fit_Covariances = optimize.curve_fit(capcitor, t, tempretures) print(fit_Params) print(fit_Covariances)
- Код выше не будет работать, если мы его запустим. Взгляните на полученное сообщение об ошибке.
- Как только мы добавим несколько обоснованных предположений(p0) для a и b, мы увидим, что соответствие теперь идеально.
fit_Params, fit_Covariances = optimize.curve_fit(capcitor, t, tempretures, p0 = [30.0, -1.0]) print(fit_Params) print(fit_Covariances)
Метод Curve_fit() Maxfev
Метод Curve_fit() Python Scipy принимает параметр maxfev, который представляет собой максимальное количество вызовов функций.
В приведенном выше подразделе при запуске функции подгонки данных без первоначального предположения отображается ошибка. Оптимальные параметры не найдены: количество вызовов функции достигло maxfev = 600.
Это означает, что функция вызывается 600 раз и не находит оптимальных параметров. Давайте увеличим значение аргумента maxfev и посмотрим, найдет ли он оптимальные параметры.
fit_Params, fit_Covariances = optimize.curve_fit(capcitor, t, tempretures, maxfev=800) print(fit_Params) print(fit_Covariances)
Экспоненциальная кривая
Метод Curve_fit() в модуле scipy.optimize пакета SciPy Python подгоняет функцию к данным с использованием нелинейного метода наименьших квадратов. В результате в этом разделе мы разработаем экспоненциальную функцию и предоставим ее методу Curve Fit(), чтобы она могла соответствовать сгенерированным данным.
Давайте рассмотрим пример, выполнив следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
import numpy as np import matplotlib.pyplot as plt %matplotlib inline from scipy import optimize
- Создайте экспоненциальную функцию, используя приведенный ниже код.
def expfunc(x, y, z, s): return y * np.exp(-z * x) + s
- Используйте приведенный ниже код, чтобы определить данные, чтобы их можно было снабдить шумом, подогнать под параметры функции «expfunc», а также ограничить оптимизацию определенной областью.
x_data = np.linspace(0, 5, 60) y_data = expfunc(x_data, 3.1, 2.3, 1.0) random_numgen = np.random.default_rng() noise_y = 0.3 * random_numgen.normal(size=x_data.size) data_y = y_data + noise_y plt.plot(x_data, data_y, 'b-', label='data') p_opt, p_cov = optimize.curve_fit(expfunc, x_data, data_y) plt.plot(x_data, expfunc(x_data, *p_opt), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(p_opt))
Из приведенного выше вывода мы можем увидеть данные, подогнанные к экспоненциальной функции, используя метод Curve_fit(), это то, как подогнать данные к экспоненциальной функции.