scipy.optimize.curve_fit 无法拟合曲线
scipy.optimize.curve_fit failing to fit curve
我正在尝试使用以下代码拟合一些数据:
xdata = [0.03447378, 0.06894757, 0.10342136, 0.13789514, 0.17236893,
0.20684271, 0.24131649, 0.27579028, 0.31026407, 0.34473785,
0.37921163, 0.41368542, 0.44815921, 0.48263299]
ydata = [ 2.5844 , 2.87449, 3.01929, 3.10584, 3.18305, 3.24166,
3.28897, 3.32979, 3.35957, 3.39193, 3.41662, 3.43956,
3.45644, 3.47135]
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b, c, d):
return a + b*x - c*np.exp(-d*x)
popt, pcov = curve_fit(func, xdata, ydata))
plt.figure()
plt.plot(xdata, ydata, 'ko', label="Original Noised Data")
plt.plot(xdata, func(xdata, *popt), 'r-', label="Fitted Curve")
plt.legend()
plt.show()
未拟合曲线:
Data fit with straight line - should be curve
我应该怎么做才能正确拟合数据?
请尝试更具体地说明您遇到的问题。
我注意到有两件事会阻止您的代码按原样运行:
- 第 15 行(
curve_fit()
调用),在行尾有一个额外的右括号
xdata
是一个 python 列表,所以一旦您尝试将它与 func
中的参数相乘,这将不起作用,即将它变成一个 numpy 数组
xdata = np.array(xdata)
如果您解决了这两个问题,则适合。
编辑:沃伦当然是对的 - 解决上述问题仍然会让你从错误的最低限度开始。
看起来优化器陷入了局部最小值,或者可能只是 objective 函数的一个非常平坦的区域。通过调整 curve_fit
使用的参数的初始猜测,可以找到更好的拟合。例如,我使用 p0=[1, 1, 1, 2.0]
(默认值为 [1, 1, 1, 1]):
这是我使用的脚本的修改版本:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b, c, d):
return a + b*x - c*np.exp(-d*x)
xdata = np.array([0.03447378, 0.06894757, 0.10342136, 0.13789514, 0.17236893,
0.20684271, 0.24131649, 0.27579028, 0.31026407, 0.34473785,
0.37921163, 0.41368542, 0.44815921, 0.48263299])
ydata = np.array([ 2.5844 , 2.87449, 3.01929, 3.10584, 3.18305, 3.24166,
3.28897, 3.32979, 3.35957, 3.39193, 3.41662, 3.43956,
3.45644, 3.47135])
p0 = [1, 1, 1, 2.0]
popt, pcov = curve_fit(func, xdata, ydata, p0=p0)
print(popt)
plt.figure()
plt.plot(xdata, ydata, 'ko', label="Original Noised Data")
plt.plot(xdata, func(xdata, *popt), 'r-', label="Fitted Curve")
plt.legend(loc='best')
plt.show()
打印输出为:
[ 3.13903988 0.71827903 0.97047248 15.40936232]
我正在尝试使用以下代码拟合一些数据:
xdata = [0.03447378, 0.06894757, 0.10342136, 0.13789514, 0.17236893,
0.20684271, 0.24131649, 0.27579028, 0.31026407, 0.34473785,
0.37921163, 0.41368542, 0.44815921, 0.48263299]
ydata = [ 2.5844 , 2.87449, 3.01929, 3.10584, 3.18305, 3.24166,
3.28897, 3.32979, 3.35957, 3.39193, 3.41662, 3.43956,
3.45644, 3.47135]
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b, c, d):
return a + b*x - c*np.exp(-d*x)
popt, pcov = curve_fit(func, xdata, ydata))
plt.figure()
plt.plot(xdata, ydata, 'ko', label="Original Noised Data")
plt.plot(xdata, func(xdata, *popt), 'r-', label="Fitted Curve")
plt.legend()
plt.show()
未拟合曲线:
Data fit with straight line - should be curve
我应该怎么做才能正确拟合数据?
请尝试更具体地说明您遇到的问题。
我注意到有两件事会阻止您的代码按原样运行:
- 第 15 行(
curve_fit()
调用),在行尾有一个额外的右括号 xdata
是一个 python 列表,所以一旦您尝试将它与func
中的参数相乘,这将不起作用,即将它变成一个 numpy 数组xdata = np.array(xdata)
如果您解决了这两个问题,则适合。
编辑:沃伦当然是对的 - 解决上述问题仍然会让你从错误的最低限度开始。
看起来优化器陷入了局部最小值,或者可能只是 objective 函数的一个非常平坦的区域。通过调整 curve_fit
使用的参数的初始猜测,可以找到更好的拟合。例如,我使用 p0=[1, 1, 1, 2.0]
(默认值为 [1, 1, 1, 1]):
这是我使用的脚本的修改版本:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b, c, d):
return a + b*x - c*np.exp(-d*x)
xdata = np.array([0.03447378, 0.06894757, 0.10342136, 0.13789514, 0.17236893,
0.20684271, 0.24131649, 0.27579028, 0.31026407, 0.34473785,
0.37921163, 0.41368542, 0.44815921, 0.48263299])
ydata = np.array([ 2.5844 , 2.87449, 3.01929, 3.10584, 3.18305, 3.24166,
3.28897, 3.32979, 3.35957, 3.39193, 3.41662, 3.43956,
3.45644, 3.47135])
p0 = [1, 1, 1, 2.0]
popt, pcov = curve_fit(func, xdata, ydata, p0=p0)
print(popt)
plt.figure()
plt.plot(xdata, ydata, 'ko', label="Original Noised Data")
plt.plot(xdata, func(xdata, *popt), 'r-', label="Fitted Curve")
plt.legend(loc='best')
plt.show()
打印输出为:
[ 3.13903988 0.71827903 0.97047248 15.40936232]