Scipy Curve_fit 函数使用初始猜测值而不是实际拟合
Scipy Curve_fit function uses initial guess values instead of actually fitting
我是编程方面的菜鸟,尤其是曲线拟合方面。但是我尝试将模型曲线拟合到我使用 Python 和 Numpy 进行的一些测量中。
我成功地将 "fitted" 曲线绘制到一组数据中。好吧,看起来确实如此。事实证明,该函数只是使用初始猜测,并没有尝试实际拟合曲线。我通过对不同的数据集使用相同的初始猜测来测试这一点。这是结果:
和fitParams
的输出是fitCovariances
(这似乎是很奇怪的值):
[ 540. 2.5 2. ]
[[ inf inf inf]
[ inf inf inf]
[ inf inf inf]]
def fitFunc()
的输出只是重复的初始猜测值
我首先尝试了第 5 个数据集的脚本,这似乎还不错。但是你可以看到每个 "fitted curve" 都是完全一样的,它只是使用了初始猜测。
这是脚本:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import scipy
import math
import csv
import matplotlib as mpl
mpl.rcParams['text.usetex']=True
mpl.rcParams['text.latex.unicode']=True
#model
def fitFunc(P_max, x, x_0, w_z):
print P_max
print x_0
print w_z
return 0.5 * P_max * (1 - scipy.special.erf((scipy.sqrt(2) * (x - x_0)) / w_z))
fig = plt.figure()
#for-loop to read and curve fit for all data sets
for n in range (1,7):
x_model = np.linspace(-1,6,5000)
y_model = []
x = []
P = []
name = 'data_' + str(n)
with open(name + '.csv', 'rb') as f:
data = csv.reader(f, delimiter = ';')
for row in data:
x.append(float(row[1]))
P.append(float(row[2]))
fitParams, fitCovariances = curve_fit(fitFunc, np.array(x), np.array(P), [540, 2.5, 2])
print fitParams
print fitCovariances
for i in range(0, len(x_model)):
y_model.append(fitFunc(fitParams[0], x_model[i], fitParams[1], fitParams[2]))
ax = fig.add_subplot(2,3,n, axisbg='white')
ax.scatter(x,P)
ax.plot(x_model,y_model)
ax.set_xlim([0, 6])
ax.set_ylim([0, 600])
ax.set_xlabel(r'\Delta x')
ax.set_ylabel(r'P (\mu W)')
plt.tight_layout()
plt.show()
我真的找不到我做错了什么。我希望你们能帮助我。谢谢:)
注意:您可以下载数据文件here来尝试使用相同数据的脚本。
您唯一的问题是 fitFunc
的定义。来自 help(curve_fit)
:
Parameters
----------
f : callable
The model function, f(x, ...). It must take the independent
variable as the first argument and the parameters to fit as
separate remaining arguments.
这意味着您必须移动 x
输入以成为函数的第一个参数。这仅影响 2 行:您对 fitFunc
、
的定义
#def fitFunc(P_max, x, x_0, w_z): #original
def fitFunc(x, P_max, x_0, w_z):
print(P_max)
print(x_0)
print(w_z)
return 0.5 * P_max * (1 - scipy.special.erf((scipy.sqrt(2) * (x - x_0)) / w_z))
以及绘图时对 fitFunc
的显式调用:
for i in range(0, len(x_model)):
y_model.append(fitFunc(x_model[i], fitParams[0], fitParams[1], fitParams[2]))
结果:
我觉得你和 scipy 都做得很好:)
效率说明:
我不明白为什么您的 fitFunc
不能使用矢量值 x
输入(它确实可以)。这意味着您可以在绘制拟合模型时节省 i
的循环,您可以只说
y_model = fitFunc(x_model, fitParams[0], fitParams[1], fitParams[2])
我是编程方面的菜鸟,尤其是曲线拟合方面。但是我尝试将模型曲线拟合到我使用 Python 和 Numpy 进行的一些测量中。
我成功地将 "fitted" 曲线绘制到一组数据中。好吧,看起来确实如此。事实证明,该函数只是使用初始猜测,并没有尝试实际拟合曲线。我通过对不同的数据集使用相同的初始猜测来测试这一点。这是结果:
和fitParams
的输出是fitCovariances
(这似乎是很奇怪的值):
[ 540. 2.5 2. ]
[[ inf inf inf]
[ inf inf inf]
[ inf inf inf]]
def fitFunc()
的输出只是重复的初始猜测值
我首先尝试了第 5 个数据集的脚本,这似乎还不错。但是你可以看到每个 "fitted curve" 都是完全一样的,它只是使用了初始猜测。
这是脚本:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import scipy
import math
import csv
import matplotlib as mpl
mpl.rcParams['text.usetex']=True
mpl.rcParams['text.latex.unicode']=True
#model
def fitFunc(P_max, x, x_0, w_z):
print P_max
print x_0
print w_z
return 0.5 * P_max * (1 - scipy.special.erf((scipy.sqrt(2) * (x - x_0)) / w_z))
fig = plt.figure()
#for-loop to read and curve fit for all data sets
for n in range (1,7):
x_model = np.linspace(-1,6,5000)
y_model = []
x = []
P = []
name = 'data_' + str(n)
with open(name + '.csv', 'rb') as f:
data = csv.reader(f, delimiter = ';')
for row in data:
x.append(float(row[1]))
P.append(float(row[2]))
fitParams, fitCovariances = curve_fit(fitFunc, np.array(x), np.array(P), [540, 2.5, 2])
print fitParams
print fitCovariances
for i in range(0, len(x_model)):
y_model.append(fitFunc(fitParams[0], x_model[i], fitParams[1], fitParams[2]))
ax = fig.add_subplot(2,3,n, axisbg='white')
ax.scatter(x,P)
ax.plot(x_model,y_model)
ax.set_xlim([0, 6])
ax.set_ylim([0, 600])
ax.set_xlabel(r'\Delta x')
ax.set_ylabel(r'P (\mu W)')
plt.tight_layout()
plt.show()
我真的找不到我做错了什么。我希望你们能帮助我。谢谢:)
注意:您可以下载数据文件here来尝试使用相同数据的脚本。
您唯一的问题是 fitFunc
的定义。来自 help(curve_fit)
:
Parameters ---------- f : callable The model function, f(x, ...). It must take the independent variable as the first argument and the parameters to fit as separate remaining arguments.
这意味着您必须移动 x
输入以成为函数的第一个参数。这仅影响 2 行:您对 fitFunc
、
#def fitFunc(P_max, x, x_0, w_z): #original
def fitFunc(x, P_max, x_0, w_z):
print(P_max)
print(x_0)
print(w_z)
return 0.5 * P_max * (1 - scipy.special.erf((scipy.sqrt(2) * (x - x_0)) / w_z))
以及绘图时对 fitFunc
的显式调用:
for i in range(0, len(x_model)):
y_model.append(fitFunc(x_model[i], fitParams[0], fitParams[1], fitParams[2]))
结果:
我觉得你和 scipy 都做得很好:)
效率说明:
我不明白为什么您的 fitFunc
不能使用矢量值 x
输入(它确实可以)。这意味着您可以在绘制拟合模型时节省 i
的循环,您可以只说
y_model = fitFunc(x_model, fitParams[0], fitParams[1], fitParams[2])