我有下面的数据集:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
## Given datapoints
xdata = np.array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26])
ydata = np.array([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.99330715, 0.98201379, 0.95257413, 0.88079708, 0.73105858, 0.5])
## Plot the data
plt.plot(xdata, ydata)
plt.xlabel('x')
plt.ylabel('sigmoid(x)')
plt.xlim([-1,31])
plt.ylim(0, 1.05)
plt.show()
上面的数据看起来是这样的:
需要使用python中的curve_fit对曲线进行校准和外推,以使y从1减小到0。
我试图使用sigmoid函数提供'y'是给定的,'x'需要找到。
因此,拟合'x'的sigmoid函数定义如下:
## Define sigmoid function to fit xdata
def sigmoid(y, x0, k):
x = x0 + ((1/k)*(np.log((1/y)-1)))
return x
## Initial guess
p0 = [np.median(xdata), # x0
0.1] # k
## Initialize curve fit
popt, pcov = curve_fit(sigmoid,
ydata,
xdata)
## Define values for y
y = np.arange(1,0,-0.001)
## Evaluate values for x
x = sigmoid(y, *popt)
## Plot tbe actual and fit data
plt.plot(xdata, ydata, 'o', label='data')
plt.plot(x,y, label='fit')
plt.xlim([-10,31])
plt.ylim(0, 1.05)
plt.legend(loc='best')
plt.show()
拟合数据如下所示:
很明显,合身度不好。
有人能告诉我如何拟合出接近实际数据的曲线吗?
2条答案
按热度按时间xuo3flqw1#
问题是在要拟合的方程中有ln((1/y)-1),当y=1时,ln((1/y)-1)是无穷大的,y=1的点不必考虑,这样拟合就很好:
当y趋于1(但小于1)时,则x趋于-无穷大,这与数据和曲线的形状一致。
guicsvcw2#
您可能会发现
lmfit
对此很有用(免责声明:我是第一作者),因为它内置了S形阶跃函数,可以很容易地进行拟合,并使用这些结果来插值或外推。它还提供了比curve_fit
更有用的结果报告,变量参数具有有意义的名称和不确定性以及正确计算,排序和分配的相关性。您的示例可能如下所示:
它会打印一份报告
画一个这样的图