由于 "Optimal parameters not found" 错误 [python],无法使用 scipy 中的 curve_fit() 将曲线拟合到数据点
Unable to fit curves to data points using curve_fit() from scipy because of "Optimal parameters not found" error [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() 来将指数衰减曲线和对数衰减曲线拟合到我的实验数据点?
正如评论中已经指出的那样,该模型似乎属于后勤类型。
用常用软件进行拟合的主要难点在于参数初始值的选择,以启动迭代演算。 https://fr.scribd.com/doc/14674814/Regressions-et-equations-integrales中解释了一般原理的非常规方法不需要初始值。例如,数值演算如下所示:
有了你的第二个数据:
有了你的第一个数据:
如果您想根据某些指定的拟合标准(MSE、MSRE、MAE 或其他)进行更准确的拟合,您可以将上述参数值作为 non-linear 回归软件中的起始值。
我无法将对数和指数衰减曲线正确地拟合到我的实验数据点,就好像建议的曲线拟合与我的数据中的模式一点都不相似。
我有以下示例数据:
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() 来将指数衰减曲线和对数衰减曲线拟合到我的实验数据点?
正如评论中已经指出的那样,该模型似乎属于后勤类型。
用常用软件进行拟合的主要难点在于参数初始值的选择,以启动迭代演算。 https://fr.scribd.com/doc/14674814/Regressions-et-equations-integrales中解释了一般原理的非常规方法不需要初始值。例如,数值演算如下所示:
有了你的第二个数据:
有了你的第一个数据:
如果您想根据某些指定的拟合标准(MSE、MSRE、MAE 或其他)进行更准确的拟合,您可以将上述参数值作为 non-linear 回归软件中的起始值。