scipy.optimize.curve_fit перестал работать после нескольких итераций

Вопрос или проблема

—– обновления 2:

Когда я застрял здесь, я также обновил свои коды на использование optuna – и, похоже, optuna работает лучше, чем curve_fit.

—– обновления 1:

Проблема была связана с “maxfev”, и она была решена после того, как я увеличил значение “maxfev”. По какой-то причине, которую я не знаю, на моей машине scipy не выдал мне никаких исключений – я переустановлю scipy.

Спасибо всем, кто помог мне диагностировать эту проблему.

—– оригинальный пост:

Я хотел использовать scipy.optimize.curve_fit, чтобы подогнать данные, и у меня есть более 10000 наборов данных для подгонки, поэтому я использовал цикл for, чтобы запустить curve_fit 10000 раз. Однако curve_fit успешно работал только для первых 49 итераций, а после этого curve_fit перестал работать – если быть более точным, функция curve_fit ничего не возвращала, и никаких исключений или предупреждений также не возникало. В чем может быть причина и как это исправить?

Я включил свой код ниже. Когда я его запускаю, он печатает i до 48, а затем выходит из цикла for. Ошибок, предупреждений, возвращаемых значений или чего-либо нет.

def irt(x, alpha, beta):
    return 1 / (1 + np.exp(0 - alpha * (x - beta)))

for i in range(10000):
    """ Я сделал что-то здесь, чтобы обработать данные, и эти строки пропущены для простоты """
    popt, pcov = scipy.optimize.curve_fit(irt, xdata[i], ydata[i], p0=[1.0, 0.5], full_output=False)
    print(i)

Пожалуйста, посмотрите на следующий пример, я выполняю следующие строки в консоли после выполнения curve_fit 49 итераций. “ress” – это возвращаемое значение, но ничего не было возвращено. (независимо от того, какие значения были введены, я не получил ничего от функции curve_fit)

theta = np.array([0.80748663, 0.86585366, 0.8245614 , 0.79310345, 0.63513514, 0.82926829, 0.73684211, 0.91358025, 0.79310345, 0.81818182])
correct = np.array([0., 1., 1., 1., 1., 1., 1., 0., 1., 1.])
ress = scipy.optimize.curve_fit(irt, theta, correct, p0=[1.0, 0.8181818181818182])
ress

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2022.3.3\plugins\python-ce\helpers\pydev\pydevconsole.py", line 364, in runcode
    coro = func()
           ^^^^^^
  File "<input>", line 1, in <module>
NameError: name 'ress' is not defined.

Если я просто запущу функцию curve_fit в консоливведите описание изображения здесь, она ничего не вернет:

Ответ или решение

Проблема, которую вы описали с использованием функции scipy.optimize.curve_fit, имеет несколько возможных причин, и как вы уже сами определили, это связано с параметром maxfev, который определяет максимальное количество вызовов функции, разрешенных для одной итерации. Если функция curve_fit достигает этого лимита без сходимости, она может просто перестать возвращать значения, не выбрасывая никаких исключений, что создаёт трудности в диагностике проблемы.

Решение проблемы

  1. Увеличение maxfev: Вы уже упомянули, что увеличение значения maxfev решило вашу проблему. Это правильный подход, так как увеличение этого параметра позволяет функции выполнять больше итераций, что может быть необходимо для достижения сходимости для сложных данных.

    Например, вы можете задать maxfev следующим образом:

    popt, pcov = scipy.optimize.curve_fit(irt, xdata[i], ydata[i], p0=[1.0, 0.5], maxfev=10000)
  2. Проверка выходных данных функции: Вы можете также добавлять обработку исключений, чтобы отслеживать, если curve_fit не может полностью завершить процесс:

    try:
       popt, pcov = scipy.optimize.curve_fit(irt, xdata[i], ydata[i], p0=[1.0, 0.5], maxfev=10000)
    except (RuntimeError, ValueError) as e:
       print(f"Ошибка при fitting для набора данных {i}: {e}")
       continue
  3. Обработка данных: Убедитесь, что ваши данные корректны на всех итерациях. Проверьте, имеют ли ваши xdata и ydata адекватные и ненулевые размеры. Визуализация данных также может помочь понять, может ли ваша функция в общем случае подойти к данным.

  4. Мониторинг параметров: В процессе изменения параметров начальных условий p0 и других параметров можно проводить эксперименты, чтобы определить, какие значения работают наилучшим образом для вашей задачи. Обратите внимание на изменение функции, добавление более подходящих стартовых параметров может существенно повлиять на сходимость.

  5. Оптимизация кода: Если вы обрабатываете большое количество наборов данных, можно рассмотреть параллелизацию вычислений. Библиотеки, такие как multiprocessing, могут сократить время вычислений на больших объемах данных.

  6. Использование альтернативных методов оптимизации: Как вы уже заметили, Optuna может работать лучше для вашей задачи. Это открывает возможность использовать другие библиотеки для оптимизации, которые могут быть более эффективными для ваших спецификаций.

Заключение

Вы уже провели тщательную диагностику своей проблемы и пришли к частичному решению, увеличив значение maxfev. Рекомендую продолжить следовать предложенным выше советам для улучшения вашего кода. Если вы столкнетесь с другими проблемами, не стесняйтесь обращаться за помощью. Удачи в ваших вычислениях!

Оцените материал
Добавить комментарий

Капча загружается...