Scipy.optimize не подходит к моим данным

Я не могу получить scipy.optimize.curve_fit чтобы правильно соответствовать моим данным, что наглядно. Я приблизительно знаю, какими должны быть значения параметров, и если я оцениваю функцию с заданными параметрами, то расчетные и экспериментальные данные хорошо согласуются:

расчетные и экспериментальные данные

Тем не менее, когда я использую scipy.optimize.curve_fit выходные параметры с наименьшей ошибкой подходят намного хуже (при визуальном осмотре). Если я использую "известные" параметры в качестве своего начального предположения и привязываю параметры к относительно узкому окну, как показано в примере вывода из функции подгонки:

пример вывода из функции соответствия

Я получаю значения ошибок примерно в 10^2 раза больше, но внешний вид прилегания кажется лучше. Единственный способ получить приличный внешний вид данных - это связать все параметры с ~ 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()

Массивы импортируются из файла (который я не могу включить), и нет никаких точек выброса, которые бы приводили к искажению соответствия. Любая помощь приветствуется.

Редактировать Я включил дополнительный код и входные данные, чтобы идти вместе с кодом, но вам придется повторно сохранить его как MS-Dos .CSV

1 ответ

Решение

@WarrenWeckesser имеет действительно хорошую точку, но обратите внимание, что ось y является логарифмической. Эта, очевидно, огромная ошибка на правом конце имеет величину порядка 1e-5, в то время как точки в верхнем левом углу имеют значения отражательной способности около 0,1. Квадратная ошибка, исходящая от хвоста, просто незначительна по сравнению с огромными членами слева.

Я уверен curve_fit работает отлично. Если вы хотите улучшить внешний вид, я советую попробовать log(y) с log() вашей модели (или это, или взвесить ваши очки во время примерки); тогда результат может быть более стабильным визуально (и с физической точки зрения). Поскольку вы, вероятно, пытаетесь дать общее описание вашей системы в широком спектре, это может быть ближе к тому, что вы ожидаете (но это неизбежно приведет к менее точному соответствию при высокой отражательной способности).

Другие вопросы по тегам