Scipy curve_fit RuntimeWarning: в exp обнаружено переполнение

Я пытаюсь подогнать функцию с двумя независимыми переменными 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. Спасибо!

Расскажите нам о данных — размере массива и dtype, но, что более важно, о диапазоне значений (max и min). Вы тестировали exponential(x_data, 1, -.5, 1). Или со значениями popt. Все, что делает curve_fit, — это сравнивает y_data с функцией, запущенной с x_data. Вы можете выполнить эти примеры расчетов, не проходя через curve_fit.

hpaulj 25.04.2023 02:39
np.exp(-.5*(-1e4)) выдает предупреждение о переполнении вместе со значением inf. Это не проблема недополнения или точности.
hpaulj 25.04.2023 02:42

хорошее замечание @hpaulj; Я добавил минимальное и максимальное значения и тип данных

Christian Seitz 25.04.2023 02:49

сколько точек данных у вас есть? как выглядит сюжет? качественно выглядит как экспонента? Кроме того, np.exp(kx) вернет inf с такими большими значениями x или 0, если k < 0

DrBwts 25.04.2023 14:59

да, @DrBwts, это действительно похоже на экспоненту (при необходимости я могу показать цифры). Есть 44k точек данных

Christian Seitz 25.04.2023 20:38

Вы знаете цену b? Если вам нужно настроить два параметра, то ваш p0 должен состоять из двух элементов. Вам нужно переопределить функцию на exponential(x, a, k) и присвоить значение b.

Joao_PS 26.04.2023 15:07

Подходит к журналу значений y; это удаляет экспоненту и делает подгонку намного более осуществимой.

9769953 26.04.2023 16:44
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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, и довольно сомнительно, что это действительно необходимо в вашем случай.

Другие вопросы по теме