由于“找不到最佳参数”,无法使用 scipy 中的 curve_fit() 将曲线拟合到数据点错误[python]
我无法将对数和指数衰减曲线正确地拟合到我的实验数据点,就好像建议的曲线拟合与我的数据中的模式完全不相似。
我有以下示例数据:
data = {'X':[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
],
'Y':[55, 55, 55, 54, 54, 54, 54, 53, 53, 50, 45, 37, 27, 16, 0
]}
df = pd.DataFrame(data)
df = pd.DataFrame(data,columns=['X','Y'])
df.plot(x ='X', y='Y', kind = 'scatter')
plt.show()
然后,我尝试使用此代码将指数衰减和对数衰减曲线拟合到这些数据点,并输出每条曲线的均方根误差:
# load the dataset
data = df.values
# choose the input and output variables
x, y = data[:, 0], data[:, 1]
def func1(x, a, b, c):
return a*exp(b*x)+c
def func2(x, a, b):
return a * np.log(x) + b
params, _ = curve_fit(func1, x, y)
a, b, c = params[0], params[1], params[2]
yfit1 = a*exp(x*b)+c
rmse = np.sqrt(np.mean((yfit1 - y) ** 2))
print('Exponential decay fit:')
print('y = %.5f * exp(x*%.5f)+%.5f' % (a, b, c))
print('RMSE:')
print(rmse)
print('')
params, _ = curve_fit(func2, x, y)
a, b = params[0], params[1]
yfit2 = a * np.log(x) + b
rmse = np.sqrt(np.mean((yfit2 - y) ** 2))
print('Logarithmic decay fit:')
print('y = %.5f * ln(x)+ %.5f' % (a, b))
print('RMSE:')
print(rmse)
print('')
plt.plot(x, y, 'bo', label="y-original")
plt.plot(x, yfit1, label="y=a*exp(x*b)+c")
plt.plot(x, yfit2, label="y=a * np.log(x) + b")
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid(True)
plt.show()
然后我尝试使用我的实验数据,尝试这些新数据点:
data = {'X':[0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360, 390, 420, 450, 480
],
'Y':[2.011399983,1.994139959,1.932761226,1.866343728,1.709889128,1.442674671,1.380548494,1.145193671,0.820646118,
0.582299012, 0.488162766, 0.264390575, 0.139457758, 0, 0, 0, 0
]}
df = pd.DataFrame(data)
df = pd.DataFrame(data,columns=['X','Y'])
df.plot(x ='X', y='Y', kind = 'scatter')
plt.show()
,我尝试使用以前的代码将指数衰减曲线和对数衰减曲线拟合到这些新数据点:
import pandas as pd
import numpy as np
from numpy import array, exp
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
# load the dataset
data = df.values
# choose the input and output variables
x, y = data[:, 0], data[:, 1]
def func1(x, a, b, c):
return a*exp(b*x)+c
def func2(x, a, b):
return a * np.log(x) + b
params, _ = curve_fit(func1, x, y)
a, b, c = params[0], params[1], params[2]
yfit1 = a*exp(x*b)+c
rmse = np.sqrt(np.mean((yfit1 - y) ** 2))
print('Exponential decay fit:')
print('y = %.5f * exp(x*%.5f)+%.5f' % (a, b, c))
print('RMSE:')
print(rmse)
print('')
params, _ = curve_fit(func2, x, y)
a, b = params[0], params[1]
yfit2 = a * np.log(x) + b
rmse = np.sqrt(np.mean((yfit2 - y) ** 2))
print('Logarithmic decay fit:')
print('y = %.5f * ln(x)+ %.5f' % (a, b))
print('RMSE:')
print(rmse)
print('')
plt.plot(x, y, 'bo', label="y-original")
plt.plot(x, yfit1, label="y=a*exp(x*b)+c")
plt.plot(x, yfit2, label="y=a * np.log(x) + b")
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid(True)
plt.show()
然后我收到这个绘制的输出,它看起来与我的实验数据点相去甚远:
我不明白为什么我的第一次曲线拟合尝试工作得如此顺利和顺利,而我的第二次尝试似乎变成了一个巨大的不连贯的混乱,刚刚破坏了 curve_fit 函数。我不明白为什么如果我的实验数据中没有任何负 y 轴值,我会看到图表进入负 y 轴。我很困惑,因为我可以清楚地看到我的实验数据被精细地绘制为点,所以我不确定它有什么问题,以至于我不能简单地将我的曲线拟合到这些点。如何处理我的代码,以便我可以正确使用 curve_fit() 将指数衰减曲线和对数衰减曲线拟合到我的实验数据点?
I am unable to properly fit a logarithmic and exponential decay curve to my experimental data points, where it is as if the suggested curve fits do not resemble the pattern in my data not even remotely.
I have the following example data:
data = {'X':[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
],
'Y':[55, 55, 55, 54, 54, 54, 54, 53, 53, 50, 45, 37, 27, 16, 0
]}
df = pd.DataFrame(data)
df = pd.DataFrame(data,columns=['X','Y'])
df.plot(x ='X', y='Y', kind = 'scatter')
plt.show()
I then try fitting an exponential decay and logarithmic decay curve to these data points using this code and outputting the root mean square error for each curve:
# load the dataset
data = df.values
# choose the input and output variables
x, y = data[:, 0], data[:, 1]
def func1(x, a, b, c):
return a*exp(b*x)+c
def func2(x, a, b):
return a * np.log(x) + b
params, _ = curve_fit(func1, x, y)
a, b, c = params[0], params[1], params[2]
yfit1 = a*exp(x*b)+c
rmse = np.sqrt(np.mean((yfit1 - y) ** 2))
print('Exponential decay fit:')
print('y = %.5f * exp(x*%.5f)+%.5f' % (a, b, c))
print('RMSE:')
print(rmse)
print('')
params, _ = curve_fit(func2, x, y)
a, b = params[0], params[1]
yfit2 = a * np.log(x) + b
rmse = np.sqrt(np.mean((yfit2 - y) ** 2))
print('Logarithmic decay fit:')
print('y = %.5f * ln(x)+ %.5f' % (a, b))
print('RMSE:')
print(rmse)
print('')
plt.plot(x, y, 'bo', label="y-original")
plt.plot(x, yfit1, label="y=a*exp(x*b)+c")
plt.plot(x, yfit2, label="y=a * np.log(x) + b")
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid(True)
plt.show()
I then try to using my experimental data, trying these new data points:
data = {'X':[0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360, 390, 420, 450, 480
],
'Y':[2.011399983,1.994139959,1.932761226,1.866343728,1.709889128,1.442674671,1.380548494,1.145193671,0.820646118,
0.582299012, 0.488162766, 0.264390575, 0.139457758, 0, 0, 0, 0
]}
df = pd.DataFrame(data)
df = pd.DataFrame(data,columns=['X','Y'])
df.plot(x ='X', y='Y', kind = 'scatter')
plt.show()
I then try using the previous code to fit an exponential decay curve and a logarithmic decay curve to these new data points with this:
import pandas as pd
import numpy as np
from numpy import array, exp
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
# load the dataset
data = df.values
# choose the input and output variables
x, y = data[:, 0], data[:, 1]
def func1(x, a, b, c):
return a*exp(b*x)+c
def func2(x, a, b):
return a * np.log(x) + b
params, _ = curve_fit(func1, x, y)
a, b, c = params[0], params[1], params[2]
yfit1 = a*exp(x*b)+c
rmse = np.sqrt(np.mean((yfit1 - y) ** 2))
print('Exponential decay fit:')
print('y = %.5f * exp(x*%.5f)+%.5f' % (a, b, c))
print('RMSE:')
print(rmse)
print('')
params, _ = curve_fit(func2, x, y)
a, b = params[0], params[1]
yfit2 = a * np.log(x) + b
rmse = np.sqrt(np.mean((yfit2 - y) ** 2))
print('Logarithmic decay fit:')
print('y = %.5f * ln(x)+ %.5f' % (a, b))
print('RMSE:')
print(rmse)
print('')
plt.plot(x, y, 'bo', label="y-original")
plt.plot(x, yfit1, label="y=a*exp(x*b)+c")
plt.plot(x, yfit2, label="y=a * np.log(x) + b")
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid(True)
plt.show()
And I receive this output which looks totally wrong:
And then I receive this plotted output which looks very far off from my experimental data points:
I do not understand why my first curve fitting attempt worked so well and smoothly, while my second attempt seems to have turned into a huge incoherent mess that just broke the curve_fit function. I do not understand why I see the graph going into the negative y-axis if I do not have any negative y-axis values in my experimental data. I am confused because I can clearly see my experimental data plotted fine as just points, so I am not sure what is so wrong about it that I cannot simply fit my curves to the points. How can I address my code so that I can properly use curve_fit() to fit an exponential decay curve and a logarithmic decay curve to my experimental data points?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如评论中已经指出的,该模型似乎属于逻辑类型。
与常用软件拟合的主要困难是选择参数初始值来启动迭代演算。一种非常规方法,其一般原理在 https://fr. scribd.com/doc/14674814/Regressions-et-equations-integrales 不需要初始值。例如,数值演算如下所示:
使用您的第二个数据:
使用您的第一个数据:
如果您想要更准确的根据某些指定的拟合标准(MSE、MSRE、MAE 或其他)进行拟合,您可以将上述参数值作为非线性回归软件中的起始值。
As already pointed out in comments the model seems on the logistic kind.
The main difficulty for fitting with the usual softwares is the choice of the initial values of the parameters to start the iterative calculus. A non conventional method which general principle is explained in https://fr.scribd.com/doc/14674814/Regressions-et-equations-integrales doesn't need initial values. For example the numerical calculus is shown below :
With your second data :
With your first data :
If you want a more accurate fit according to some specified criteria of fitting (MSE, MSRE, MAE, or other) you could take the above values of parameters as starting values in a non-linear regression software.