Python Scipy Curve_fit:为什么我的拟合效果如此差,如何改进?
我正在尝试使用python的曲线拟合库拟合数据。虽然我可以捕捉到数据的模式,但实际拟合度相当差。有什么方法可以提高合身的质量吗 这是我的密码:Python Scipy Curve_fit:为什么我的拟合效果如此差,如何改进?,python,scipy,curve-fitting,Python,Scipy,Curve Fitting,我正在尝试使用python的曲线拟合库拟合数据。虽然我可以捕捉到数据的模式,但实际拟合度相当差。有什么方法可以提高合身的质量吗 这是我的密码: import numpy as np from scipy.optimize import curve_fit from matplotlib import pyplot as plt x=np.array([ 4.29977288, 4.18759576, 3.937875 , 3.68784896, 3.43711213, 3.
import numpy as np
from scipy.optimize import curve_fit
from matplotlib import pyplot as plt
x=np.array([ 4.29977288, 4.18759576, 3.937875 , 3.68784896, 3.43711213,
3.19099287, 2.94166468, 2.68543877, 2.4289324 , 2.19035861,
1.93962193, 1.69285434, 1.44271633, 1.18869615, 0.94761142,
0.69828307, 0.44606364, 0.19355101, -0.05367106, -0.30303661,
-0.55272018, -0.79877747, -1.04806864, -1.29706657, -1.54567223,
-1.79685098, -2.05011095, -2.29874144, -2.54813208, -2.80178461,
-3.04828379, -3.29893363, -3.54727073, -3.79908534, -4.04661293]);
y=np.array([ 20.8744534 , 20.89824536, 20.3763843 , 19.79924837,
19.19485964, 18.57716717, 17.93772371, 17.28834168,
16.62367817, 15.94336213, 15.24389099, 14.52471466,
13.7787734 , 13.00299723, 12.18721413, 11.31510566,
10.36672642, 9.32224105, 8.14237084, 6.78034367,
5.19700447, 3.32945537, 1.10437136, -1.48805508,
-4.25695201, -6.94906329, -9.41648974, -11.54747381,
-13.33444597, -14.90663076, -16.36783375, -17.72241553,
-18.9592222 , -20.06703821, -21.07669491])
def func(x,A,B,C):
a=1+B/A
b=1-B/A
k=C/np.log(a/b)
y=A*np.tanh((x-C)/(2*k))
return y
A_0=25
B_0=10
C_0=1.2
popt,pcov = curve_fit(func,x,y,p0=[A_0,B_0,C_0])
print(pcov)
plt.plot(x,y,label='Data')
plt.plot(x,func(x, *popt),'.',label='Fit')
plt.legend()
plt.show()
这不是曲线拟合的问题,而是您正在使用的函数的问题。找到一个能完成这项工作的函数并不总是那么容易,但例如,一个错误函数会做得更好:
将numpy导入为np
来自scipy进口特价商品
从scipy.optimize导入曲线\u拟合
从matplotlib导入pyplot作为plt
x=np.数组([4.29977288,4.18759576,3.937875,3.68784896,3.43711213,
3.19099287, 2.94166468, 2.68543877, 2.4289324 , 2.19035861,
1.93962193, 1.69285434, 1.44271633, 1.18869615, 0.94761142,
0.69828307, 0.44606364, 0.19355101, -0.05367106, -0.30303661,
-0.55272018, -0.79877747, -1.04806864, -1.29706657, -1.54567223,
-1.79685098, -2.05011095, -2.29874144, -2.54813208, -2.80178461,
-3.04828379, -3.29893363, -3.54727073, -3.79908534, -4.04661293]);
y=np.数组([20.8744534,20.89824536,20.3763843,19.79924837,
19.19485964, 18.57716717, 17.93772371, 17.28834168,
16.62367817, 15.94336213, 15.24389099, 14.52471466,
13.7787734 , 13.00299723, 12.18721413, 11.31510566,
10.36672642, 9.32224105, 8.14237084, 6.78034367,
5.19700447, 3.32945537, 1.10437136, -1.48805508,
-4.25695201, -6.94906329, -9.41648974, -11.54747381,
-13.33444597, -14.90663076, -16.36783375, -17.72241553,
-18.9592222 , -20.06703821, -21.07669491])
def func(x、A、B、C):
a=1+B/a
b=1-b/A
k=C/np.log(a/b)
y=A*np.tanh((x-C)/(2*k))
返回y
def erf(x、a、b、c、d):
返回d+0.5*c*(1+special.erf(a*(x-b)))
A_0=25
B_0=10
C_0=1.2
popt,pcov=曲线拟合(func,x,y,p0=[A_0,B_0,C_0])
perf,pecov=曲线拟合(erf,x,y,p0=(0.5,0,40,-20))
plt.plt(x,y,'o',label='Data')
plt.plot(x,func(x,*popt),'-',label='Fit')
plt.plot(x,erf(x,*perf),'--',label='erf-fit')
plt.legend()
plt.show()
这不是曲线拟合的问题,而是您正在使用的函数的问题。找到一个能完成这项工作的函数并不总是那么容易,但例如,一个错误函数会做得更好:
将numpy导入为np
来自scipy进口特价商品
从scipy.optimize导入曲线\u拟合
从matplotlib导入pyplot作为plt
x=np.数组([4.29977288,4.18759576,3.937875,3.68784896,3.43711213,
3.19099287, 2.94166468, 2.68543877, 2.4289324 , 2.19035861,
1.93962193, 1.69285434, 1.44271633, 1.18869615, 0.94761142,
0.69828307, 0.44606364, 0.19355101, -0.05367106, -0.30303661,
-0.55272018, -0.79877747, -1.04806864, -1.29706657, -1.54567223,
-1.79685098, -2.05011095, -2.29874144, -2.54813208, -2.80178461,
-3.04828379, -3.29893363, -3.54727073, -3.79908534, -4.04661293]);
y=np.数组([20.8744534,20.89824536,20.3763843,19.79924837,
19.19485964, 18.57716717, 17.93772371, 17.28834168,
16.62367817, 15.94336213, 15.24389099, 14.52471466,
13.7787734 , 13.00299723, 12.18721413, 11.31510566,
10.36672642, 9.32224105, 8.14237084, 6.78034367,
5.19700447, 3.32945537, 1.10437136, -1.48805508,
-4.25695201, -6.94906329, -9.41648974, -11.54747381,
-13.33444597, -14.90663076, -16.36783375, -17.72241553,
-18.9592222 , -20.06703821, -21.07669491])
def func(x、A、B、C):
a=1+B/a
b=1-b/A
k=C/np.log(a/b)
y=A*np.tanh((x-C)/(2*k))
返回y
def erf(x、a、b、c、d):
返回d+0.5*c*(1+special.erf(a*(x-b)))
A_0=25
B_0=10
C_0=1.2
popt,pcov=曲线拟合(func,x,y,p0=[A_0,B_0,C_0])
perf,pecov=曲线拟合(erf,x,y,p0=(0.5,0,40,-20))
plt.plt(x,y,'o',label='Data')
plt.plot(x,func(x,*popt),'-',label='Fit')
plt.plot(x,erf(x,*perf),'--',label='erf-fit')
plt.legend()
plt.show()
我不确定您是否一定要使用您正在使用的函数,或者您也可以使用多项式。在后一种情况下,可以使用
polyfit
记住,不能只使用任何高阶多项式,否则最终会过度拟合数据。您可以查看拟合的均方根误差,以衡量其精度
fit = np.poly1d(np.polyfit(x, y, 5))
plt.plot(x, y, '.', label='Data')
plt.plot(x, fit(x), label='Fit')
plt.legend()
我不确定您是否一定要使用您正在使用的函数,或者您也可以使用多项式。在后一种情况下,可以使用
polyfit
记住,不能只使用任何高阶多项式,否则最终会过度拟合数据。您可以查看拟合的均方根误差,以衡量其精度
fit = np.poly1d(np.polyfit(x, y, 5))
plt.plot(x, y, '.', label='Data')
plt.plot(x, fit(x), label='Fit')
plt.legend()
我认为可能是一个S形或峰值方程可以对数据进行建模,下面是峰值方程和建模误差的示例图:
这就好像有两个组合信号,其中一个是低振幅周期信号。第二个信号不是简单的正弦波。我的想法是,您可能需要一个复杂的模型,它是两个不同方程的总和,以在单个模型中捕获这两个分量。我认为可能是一个S形或峰值方程可以对数据进行建模,下面是峰值方程和建模错误的示例图:
这就好像有两个组合信号,其中一个是低振幅周期信号。第二个信号不是简单的正弦波。我的想法是,你可能需要一个复杂的模型,它是两个不同方程的总和,以便在一个模型中捕获这两个分量。做得很好,所以我投了赞成票。请看我对这些问题的回答,以获得关于数据形状的更多评论。做得很好,所以我投了更高的票。关于数据形状的其他注释,请参见我对这些问题的回答。拟合得很好,我注意到在你的曲线图中,我在进行方程搜索时也发现了一些东西:曲线图上最左侧的点的曲线高于最左侧的数据点。如果需要,给出该p