Scipy.optimize 不适合我的数据
Scipy.optimize not fiting to my data
我无法 scipy.optimize.curve_fit
正确拟合我的数据,这在视觉上很明显。我大致知道参数值应该是多少,如果我用给定的参数评估函数,计算数据和实验数据似乎很吻合:
然而,当我使用 scipy.optimize.curve_fit
时,误差最小的输出参数更不合适(通过目视检查)。如果我使用 "known" 参数作为我的初始猜测并将参数绑定到相对较窄的 window,如 fit 函数的输出示例所示:
我得到的误差值大 ~10^2 倍,但拟合的视觉外观似乎更好。使数据看起来像样的唯一方法是将所有参数与 "known" 参数的 ~ 0.3 个单位绑定。我计划使用此代码来拟合更复杂的数据,这些数据我事先不知道参数,所以我不能只使用计算出的图。
相关代码如下:
import matplotlib.pyplot as plt
import numpy as np
import scipy
from scipy.optimize import curve_fit
d_1= 2.72 #Anstroms
sig_cp_1= 0.44
sig_int_1= 1.03
d_1, sig_cp_1,sig_int_1=float(d_1),float(sig_cp_1),float(sig_int_1)
Ref=[]
Qz_F=[]
Ref_F=[]
g=open("Exp_Fresnal.csv",'rb')#"Test_Fresnal.csv", 'rb')
reader=csv.reader(g)
for row in reader:
Qz_F.append(row[0])
Ref.append(row[1])
Ref_F.append(row[2])
Ref=map(lambda a:float(a),Ref)
Ref_F=map(lambda a:float(a),Ref_F)
Qz_F=map(lambda a:float(a),Qz_F)
Ref_F_arr=np.array((Ref_F))
Qz_arr=np.array((Qz_F))
x=np.array((Qz_arr,Ref_F))
def func(x,d,sig_int,sig_cp):
return (x[1])*(abs(x[0]*d*(np.exp((-sig_int**2)*(x[0]**2)/2)/(1-np.exp(complex(0,1)*x[0]*d)*np.exp((-sig_cp**2)*(x[0]**2)/2)))))**2
DC_ref=func(x,d_1,sig_int_1,sig_cp_1)
Y=np.array((Ref))
popt, pcov=curve_fit(func,x,Y,)#p0=[2.72,1.0,0.44])
perr=np.sqrt(np.diag(pcov))
print "par=",popt;print"Var=",perr
Fit=func(x,*popt)
Fit=func(x,*popt)
Ref=np.transpose(np.array([Ref]))
Qz_F=np.transpose(Qz_F)
plt.plot(Qz_F, Ref, 'bs',label='Experimental')
plt.plot(Qz_F, Fit, 'r--',label='Fit w/ DCM model')
plt.axis([0,3,10**(-10),100])
plt.yscale('log')
plt.title('Reflectivity',fontweight='bold',fontsize=15)
plt.ylabel('Reflectivity',fontsize=15)
plt.xlabel('qz /A^-1',fontsize=15)
plt.legend(loc='upper right',numpoints=1)
plt.show()
数组是从一个文件(我不能包含)导入的,没有异常点会导致拟合变得如此扭曲。感谢任何帮助。
编辑
我包含了额外的代码和 input data 以与代码一起使用,但您必须将其重新保存为 MS-Dos .CSV
,但还要注意y轴是对数的。右端明显的巨大误差大约为 1e-5,而左上角的点的反射率值约为 0.1。来自尾部的平方误差与左边的巨大项相比简直微不足道。
我确定 curve_fit
效果很好。如果你想要更好的视觉拟合,我建议尝试用模型的 log()
拟合 log(y)
(或者在拟合过程中加权你的点);那么结果在视觉上可能更稳定(从物理角度来看)。由于您可能试图对您的系统进行全面的广谱描述,这可能更接近您的预期(但这将不可避免地导致反射率高的地方拟合不准确)。
我无法 scipy.optimize.curve_fit
正确拟合我的数据,这在视觉上很明显。我大致知道参数值应该是多少,如果我用给定的参数评估函数,计算数据和实验数据似乎很吻合:
然而,当我使用 scipy.optimize.curve_fit
时,误差最小的输出参数更不合适(通过目视检查)。如果我使用 "known" 参数作为我的初始猜测并将参数绑定到相对较窄的 window,如 fit 函数的输出示例所示:
我得到的误差值大 ~10^2 倍,但拟合的视觉外观似乎更好。使数据看起来像样的唯一方法是将所有参数与 "known" 参数的 ~ 0.3 个单位绑定。我计划使用此代码来拟合更复杂的数据,这些数据我事先不知道参数,所以我不能只使用计算出的图。
相关代码如下:
import matplotlib.pyplot as plt
import numpy as np
import scipy
from scipy.optimize import curve_fit
d_1= 2.72 #Anstroms
sig_cp_1= 0.44
sig_int_1= 1.03
d_1, sig_cp_1,sig_int_1=float(d_1),float(sig_cp_1),float(sig_int_1)
Ref=[]
Qz_F=[]
Ref_F=[]
g=open("Exp_Fresnal.csv",'rb')#"Test_Fresnal.csv", 'rb')
reader=csv.reader(g)
for row in reader:
Qz_F.append(row[0])
Ref.append(row[1])
Ref_F.append(row[2])
Ref=map(lambda a:float(a),Ref)
Ref_F=map(lambda a:float(a),Ref_F)
Qz_F=map(lambda a:float(a),Qz_F)
Ref_F_arr=np.array((Ref_F))
Qz_arr=np.array((Qz_F))
x=np.array((Qz_arr,Ref_F))
def func(x,d,sig_int,sig_cp):
return (x[1])*(abs(x[0]*d*(np.exp((-sig_int**2)*(x[0]**2)/2)/(1-np.exp(complex(0,1)*x[0]*d)*np.exp((-sig_cp**2)*(x[0]**2)/2)))))**2
DC_ref=func(x,d_1,sig_int_1,sig_cp_1)
Y=np.array((Ref))
popt, pcov=curve_fit(func,x,Y,)#p0=[2.72,1.0,0.44])
perr=np.sqrt(np.diag(pcov))
print "par=",popt;print"Var=",perr
Fit=func(x,*popt)
Fit=func(x,*popt)
Ref=np.transpose(np.array([Ref]))
Qz_F=np.transpose(Qz_F)
plt.plot(Qz_F, Ref, 'bs',label='Experimental')
plt.plot(Qz_F, Fit, 'r--',label='Fit w/ DCM model')
plt.axis([0,3,10**(-10),100])
plt.yscale('log')
plt.title('Reflectivity',fontweight='bold',fontsize=15)
plt.ylabel('Reflectivity',fontsize=15)
plt.xlabel('qz /A^-1',fontsize=15)
plt.legend(loc='upper right',numpoints=1)
plt.show()
数组是从一个文件(我不能包含)导入的,没有异常点会导致拟合变得如此扭曲。感谢任何帮助。
编辑 我包含了额外的代码和 input data 以与代码一起使用,但您必须将其重新保存为 MS-Dos .CSV
我确定 curve_fit
效果很好。如果你想要更好的视觉拟合,我建议尝试用模型的 log()
拟合 log(y)
(或者在拟合过程中加权你的点);那么结果在视觉上可能更稳定(从物理角度来看)。由于您可能试图对您的系统进行全面的广谱描述,这可能更接近您的预期(但这将不可避免地导致反射率高的地方拟合不准确)。