由于“找不到最佳参数”,无法使用 scipy 中的 curve_fit() 将曲线拟合到数据点错误[python]

发布于 2025-01-13 08:19:12 字数 3912 浏览 3 评论 0原文

我无法将对数和指数衰减曲线正确地拟合到我的实验数据点,就好像建议的曲线拟合与我的数据中的模式完全不相似。

我有以下示例数据:

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()

输出: 输入图片description here

然后,我尝试使用此代码将指数衰减和对数衰减曲线拟合到这些数据点,并输出每条曲线的均方根误差:

# 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()

This outputs:
enter image description here

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() 

And I receive this output:
enter image description here

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()

This shows:
enter image description here

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:
enter image description here

And then I receive this plotted output which looks very far off from my experimental data points:
enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深海蓝天 2025-01-20 08:19:12

正如评论中已经指出的,该模型似乎属于逻辑类型。

与常用软件拟合的主要困难是选择参数初始值来启动迭代演算。一种非常规方法,其一般原理在 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 :

enter image description here

With your second data :

enter image description here

With your first data :

enter image description here

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文