SciPy curve_fit отображает прямую линию и не соответствует данным

#python #scipy #curve-fitting

Вопрос:

Я пытаюсь подогнать набор данных к экспоненциальной функции CDF. Однако я не уверен, что происходит не так ни в моем коде, ни в предположении о начальном параметре, но это создает только прямую линию. Данные были импортированы из файла CSV.

 #Plot Data
plt.figure(1,dpi=120)
plt.title("Cell A3")
plt.xlabel(rawdata[0][0])
plt.ylabel(rawdata[0][1])
plt.scatter(xdata,ydata,label="A3 Cell 1")



#Define Function
def func(t,lam):
    return 1 - (np.exp(-lam * t))

funcdata = func(xdata,1.17)
plt.plot(xdata,funcdata,label="Model")
plt.legend() 

#CurveFit data to model
popt, pcov = curve_fit(func,xdata,ydata,p0=(-0.64))
perr = np.sqrt(np.diag(pcov)) 
 

Изображение графика, которое я получаю с исходными данными и прямой линией, которую дает curve_fit

Ответ №1:

Вы не можете правильно подогнать такую простую экспоненциальную функцию такого рода :

y=( 1 — (np.exp(-lam * t))) * масштаб

к данным, потому что форма этой функции далека от формы данных в диапазоне 0<t

Лучше рассмотрим функцию логистического типа, например :

введите описание изображения здесь

Ответ №2:

Подумайте о своих данных и своей функции. ydata-довольно большая величина. Каково максимальное значение

 def func(t,lam):
    return 1 - (np.exp(-lam * t))
 

Я думаю, вы обнаружите, что максимальное значение функции возникает, когда lam приближается к бесконечности, функция приближается к 1. Как функция с максимальным значением == 1 может соответствовать данным в 1000-х годах? Если вы хотите иметь возможность масштабироваться больше 1, вам нужно больше параметров в вашей функции. Попробуйте с

 def func(t,lam,scale):
    return ( 1 - (np.exp(-lam * t)) ) * scale 
 

и посмотрите, сможет ли scipy лучше соответствовать данным.

ПРАВКА: Я управлял, чтобы заставить это работать, однако вы даже не строите оптимальные параметры. Чтобы сделать это, посмотрите мой код с имитацией xdata и ydata:

 #Plot Data
import numpy as np
from scipy.optimize import curve_fit
from matplotlib import pyplot as plt

def func(t,lam,scale):
    return ( 1 - (np.exp(-lam * t)) ) * scale

xdata = np.arange(25.)
ydata = func(xdata, 1.12, 2000.)

plt.figure(1,dpi=120)
plt.title("Cell A3")
plt.xlabel(rawdata[0][0])
plt.ylabel(rawdata[0][1])
plt.scatter(xdata,ydata,label="A3 Cell 1")

#CurveFit data to model
popt, pcov = curve_fit(func,xdata,ydata,p0=[0.5, 1000.1])
plt.plot(np.arange(25),func(np.arange(25), *popt),label="Model")
plt.legend() 
 

выходы:
Оптимизированный curve_fit