Я пытаюсь подогнать функцию с двумя независимыми переменными a и k к экспоненциальной кривой, используя scipy curve_fit. Я определил функцию и попытался вычислить ее следующим образом:
print(np.min(x_data))
1
print(np.max(x_data))
44098
print(x_data.dtype)
int64
print(np.size(x_data))
44098
print(np.min(y_data))
-0.44383433
print(np.max(y_data))
1.0
print(y_data.dtype)
float32
print(np.size(y_data))
44098
def exponential(x, a, k, b):
return a*np.exp(x*k) + b
popt, pcov = scipy.optimize.curve_fit(exponential, x_data, y_data, p0=[1, -0.5, 1])
print(popt)
[ 1.28765636e+00 -3.27620187e-04 -8.91012481e-02]
/software/repo/python/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6: RuntimeWarning: overflow encountered in exp
/software/repo/python/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6: RuntimeWarning: overflow encountered in multiply
Это приводит к предупреждению, поскольку мои данные слишком велики. Изменение типа данных вплоть до complex256 все еще недостаточно велико. Поэтому я попытался обновить границы; создание достаточно больших границ устраняет ошибку, но я не знаю, правильно ли я это делаю, поскольку подходящие переменные становятся зависимыми от выбранных мной границ.
popt, pcov = scipy.optimize.curve_fit(exponential, x_data, y_data, bounds=([1, -1e100, 1], [1e100, 1, 1e100]))
print(popt)
[ 5.e+99 -5.e+99 5.e+99]
popt, pcov = scipy.optimize.curve_fit(exponential, x_data, y_data, bounds=([1, -1e1000, 1], [1e1000, 1, 1e1000]))
print(popt)
[ 1.00448191 -5.15058477 1. ]
Что здесь происходит? Что мне нужно сделать, чтобы правильно соответствовать этой функции? Я также безуспешно возился с модулем Decimal. Спасибо!
np.exp(-.5*(-1e4)) выдает предупреждение о переполнении вместе со значением inf. Это не проблема недополнения или точности.
хорошее замечание @hpaulj; Я добавил минимальное и максимальное значения и тип данных
сколько точек данных у вас есть? как выглядит сюжет? качественно выглядит как экспонента? Кроме того, np.exp(kx) вернет inf с такими большими значениями x или 0, если k < 0
да, @DrBwts, это действительно похоже на экспоненту (при необходимости я могу показать цифры). Есть 44k точек данных
Вы знаете цену b? Если вам нужно настроить два параметра, то ваш p0 должен состоять из двух элементов. Вам нужно переопределить функцию на exponential(x, a, k) и присвоить значение b.
Подходит к журналу значений y; это удаляет экспоненту и делает подгонку намного более осуществимой.






exp(a) со значениями float64 (которые используются по умолчанию для numpy) переполняется со значений ~ 1.e308 до numpy.Inf для a> 709,75 или около того.
В вашем случае это означает, что ваше значение k должно удовлетворять
x*k <=709. Поскольку ваши значения x приближаются к значениям 44098, максимально допустимое значение для k должно быть около 0,016. Если вы ожидаете, что k всегда будет отрицательным, вы можете указать максимальное значение 0.
FWIW, exp будет занижаться для значений a ниже -709,75. В этом случае результат становится равным 0, что не вызывает исключения, но может затруднить подгонку.
Вы можете указать свою проблему, чтобы использовать float128, который повысит порог для переполнения, но я считаю, что это не будет работать с большинством процедур подбора кривой - они работают со значениями float64, и довольно сомнительно, что это действительно необходимо в вашем случай.
Расскажите нам о данных — размере массива и dtype, но, что более важно, о диапазоне значений (max и min). Вы тестировали
exponential(x_data, 1, -.5, 1). Или со значениямиpopt. Все, что делает curve_fit, — это сравниваетy_dataс функцией, запущенной сx_data. Вы можете выполнить эти примеры расчетов, не проходя черезcurve_fit.