Zol*_*ern 15 python numpy curve-fitting scipy
我正在尝试使用直方图来包含一些数据scipy.optimize.curve_fit.如果我想添加一个错误y,我可以通过应用一个weight适合来做到这一点.但是如何应用错误x(即直方图中由于分箱引起的错误)?
我的问题也适用于x用curve_fit或进行线性回归时的错误polyfit; 我知道如何添加错误y,但不是x.
这里有一个例子(部分来自matplotlib文档):
import numpy as np
import pylab as P
from scipy.optimize import curve_fit
# create the data histogram
mu, sigma = 200, 25
x = mu + sigma*P.randn(10000)
# define fit function
def gauss(x, *p):
A, mu, sigma = p
return A*np.exp(-(x-mu)**2/(2*sigma**2))
# the histogram of the data
n, bins, patches = P.hist(x, 50, histtype='step')
sigma_n = np.sqrt(n) # Adding Poisson errors in y
bin_centres = (bins[:-1] + bins[1:])/2
sigma_x = (bins[1] - bins[0])/np.sqrt(12) # Binning error in x
P.setp(patches, 'facecolor', 'g', 'alpha', 0.75)
# fitting and plotting
p0 = [700, 200, 25]
popt, pcov = curve_fit(gauss, bin_centres, n, p0=p0, sigma=sigma_n, absolute_sigma=True)
x = np.arange(100, 300, 0.5)
fit = gauss(x, *popt)
P.plot(x, fit, 'r--')
Run Code Online (Sandbox Code Playgroud)
现在,这个适合(当它没有失败时)确实考虑了y错误sigma_n,但我还没有找到一种方法来考虑它sigma_x.我在scipy邮件列表上扫描了几个线程,并找到了如何使用absolute_sigma值和Stackoverflow上关于不对称错误的帖子,但没有关于两个方向的错误.有可能实现吗?
Chr*_* K. 22
scipy.optmize.curve_fit使用标准的非线性最小二乘优化,因此只能最小化响应变量的偏差.如果您想要考虑自变量中的错误,可以尝试scipy.odr使用正交距离回归.顾名思义,它最大限度地减少了独立变量和因变量.
看看下面的示例.该fit_type参数确定是否scipy.odr执行完整的ODR(fit_type=0)或最小二乘优化(fit_type=2).
编辑
虽然这个例子起作用但没有多大意义,因为y数据是在噪声x数据上计算的,这只会导致不等间距的独立变量.我更新了现在还显示如何使用的示例,该示例RealData允许指定数据的标准错误而不是权重.
from scipy.odr import ODR, Model, Data, RealData
import numpy as np
from pylab import *
def func(beta, x):
y = beta[0]+beta[1]*x+beta[2]*x**3
return y
#generate data
x = np.linspace(-3,2,100)
y = func([-2.3,7.0,-4.0], x)
# add some noise
x += np.random.normal(scale=0.3, size=100)
y += np.random.normal(scale=0.1, size=100)
data = RealData(x, y, 0.3, 0.1)
model = Model(func)
odr = ODR(data, model, [1,0,0])
odr.set_job(fit_type=2)
output = odr.run()
xn = np.linspace(-3,2,50)
yn = func(output.beta, xn)
hold(True)
plot(x,y,'ro')
plot(xn,yn,'k-',label='leastsq')
odr.set_job(fit_type=0)
output = odr.run()
yn = func(output.beta, xn)
plot(xn,yn,'g-',label='odr')
legend(loc=0)
Run Code Online (Sandbox Code Playgroud)
