Scipy curvefit RuntimeError: Оптимальные параметры не найдены: количество вызовов функции достигло maxfev = 1000

Я хочу сделать логарифмическую подгонку. Но я продолжаю получать ошибку времени выполнения:

Оптимальные параметры не найдены: количество вызовов функции достигло maxfev = 1000

Я использую следующий script. Может ли кто-нибудь сказать мне, где я ошибаюсь? Я использую Spyder и еще новичок.

import math
import matplotlib as mpl
from scipy.optimize import curve_fit
import numpy as np

#data
F1=[735.0,696.0,690.0,683.0,680.0,678.0,679.0,675.0,671.0,669.0,668.0,664.0,664.0]
t1=[1,90000.0,178200.0,421200.0,505800.0,592200.0,768600.0,1036800.0,1371600.0,1630800.0,1715400.0,2345400.0,2409012.0]

F1n=np.array(F1)
t1n=np.array(t1)

plt.plot(t1,F1,'ro',label="original data")

# curvefit
def func(t,a,b):
    return a+b*np.log(t)

t=np.linspace(0,3600*24*28,13)

popt, pcov = curve_fit(func, t, F1n, maxfev=1000)    

plt.plot(t, func(t, *popt), label="Fitted Curve")

plt.legend(loc='upper left')
plt.show()

Ответ 1

Ваши исходные данные t1 и F1. Поэтому curve_fit следует указать t1 как свой второй аргумент, не t.

popt, pcov = curve_fit(func, t1, F1, maxfev=1000)

Теперь, когда вы получите параметры, popt, вы можете оценить func в точках в t, чтобы получить установленную кривую:

t = np.linspace(1, 3600 * 24 * 28, 13)
plt.plot(t, func(t, *popt), label="Fitted Curve")

(я удалил нуль из t (для ответа StuGrey), чтобы избежать Warning: divide by zero encountered in log.)


import matplotlib.pyplot as plt
import scipy.optimize as optimize
import numpy as np

# data
F1 = np.array([
    735.0, 696.0, 690.0, 683.0, 680.0, 678.0, 679.0, 675.0, 671.0, 669.0, 668.0,
    664.0, 664.0])
t1 = np.array([
    1, 90000.0, 178200.0, 421200.0, 505800.0, 592200.0, 768600.0, 1036800.0,
    1371600.0, 1630800.0, 1715400.0, 2345400.0, 2409012.0])

plt.plot(t1, F1, 'ro', label="original data")

# curvefit

def func(t, a, b):
    return a + b * np.log(t)

popt, pcov = optimize.curve_fit(func, t1, F1, maxfev=1000)
t = np.linspace(1, 3600 * 24 * 28, 13)
plt.plot(t, func(t, *popt), label="Fitted Curve")
plt.legend(loc='upper left')
plt.show()

enter image description here

Ответ 2

После фиксации ваших операторов импорта:

#import matplotlib as mpl
import matplotlib.pyplot as plt

ваш код вызвал следующую ошибку:

RuntimeWarning: divide by zero encountered in log

изменение:

#t=np.linspace(0,3600*24*28,13)
t=np.linspace(1,3600*24*28,13)

появился следующий результат:

enter image description here

Ответ 3

Curve_fit() использует итерации для поиска оптимальных параметров. Если число итераций превышает установленное число 1000, но оптимальные параметры все еще недоступны, то эта ошибка будет повышена. Вы можете предоставить некоторые начальные параметры предположения для curve_fit(), а затем повторите попытку.

Ответ 4

SciPy-х

     curve_fit() 

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

    Optimal parameters not found: Number of calls to function has reached maxfev = 800

Вы можете предоставить некоторые начальные параметры предположения для curve_fit(), а затем повторите попытку. Или вы можете увеличить допустимые итерации. Или сделать оба!

Вот пример:

    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], maxfev=5000)

р0 это предположение

maxfev - максимальное количество итераций

Вы также можете попробовать установить границы, которые помогут функции найти решение. Однако вы не можете установить границы и max_nfev одновременно.

    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], bounds=(1,3))

Источник1: https://github.com/scipy/scipy/issues/6340

Source2: мое собственное тестирование и обнаружение, что about github не на 100% точен

Кроме того, другие рекомендации о том, чтобы не использовать 0 в качестве значения 'x', являются отличными рекомендациями. Начните свой массив 'x' с 1, чтобы избежать деления на ноль ошибок.