使更好的高斯拟合数据点? [英] Fitting a better gaussian to data points?

查看:237
本文介绍了使更好的高斯拟合数据点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使高斯适合一组似乎遵循高斯分布的数据点.我已经检查了很多可行的方法,但是我不太了解其中的大多数方法.但是,我发现了一个似乎可行的解决方案,但是我得到的实际拟合看起来比我的数据点看起来更像是高斯.

I am trying to fit a gaussian to a set of data points that seem to follow a gaussian distribution. I have already checked a lot of possible ways to do that, but I don't really understand most of them. However, I found one solution that seems to work, but the actual fit I get does not look much more like a gaussian than my data points.

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy import asarray as ar, exp, sqrt
from scipy.optimize import curve_fit


angles = [-8, -6, -4, -2, 0, 2, 4, 6, 8]
data = [99, 610, 1271, 1804, 1823, 1346, 635, 125, 24]
angles = ar(angles)
data = ar(data)

n = len(x)
mean = sum(data*angles)/n
sigma = sqrt(sum(data*(angles-mean)**2)/n)

def gaus(x,a,mu,sigma):
    return a*exp(-(x-mu)**2/(2*sigma**2))

popt,pcov = curve_fit(gaus,angles,data,p0=[0.18,mean,sigma])


fig = plt.figure()
plt.plot(angles, data, "ob", label = "Measured")
plt.plot(angles,gaus(angles,*popt),'r',label='Fit')
plt.xlim(-10, 10)
plt.ylim(0, 2000)
plt.xticks(angles)
plt.title("$^{137}$Cs Zero Point")
plt.xlabel("Angle [$^\circ$]")
plt.ylabel("662 keV-Photon Count")
plt.grid()
plt.legend()
plt.show()

这是它生成的输出:

如您所见,该拟合并不能描述一个漂亮且对称的真实"高斯. 有什么方法可以使我获得一个更好的"高斯,或者它是否尽善尽美?

As you can see, the fit does not describe a nice and symmetrical "real" gaussian. Is there any way I can get a "better" gaussian or is this as good as it gets?

非常感谢!

推荐答案

我认为这里有两件事:

似乎遵循高斯分布

seem to follow a gaussian distribution

→如果您认为数据是正态分布的,那么您就处于统计和概率分布领域,并且可能希望进行测试,以查看它们是否与特定分布(正态分布或其他分布)一致.

→ If you think that the data are normally distributed, you are in the realms of statistics and probability distributions, and may want to make a test to see if they agree with a particular distribution (normal or other).

并使用您的:

获得更好"的高斯

在您的代码中,您可以省略curve_fit中的第一个估计值,并针对连续的自变量绘制拟合曲线:

In your code, you can leave out the first estimation in curve_fit and plot the fitted curve against a continuous independent variable:

import numpy as np
import matplotlib.pyplot as plt
from scipy import asarray as ar, exp, sqrt
from scipy.optimize import curve_fit


angles = [-8, -6, -4, -2, 0, 2, 4, 6, 8]
data = [99, 610, 1271, 1804, 1823, 1346, 635, 125, 24]
angles = ar(angles)
data = ar(data)

n = len(data)  ## <---
mean = sum(data*angles)/n
sigma = sqrt(sum(data*(angles-mean)**2)/n)

def gaus(x,a,mu,sigma):
    return a*exp(-(x-mu)**2/(2*sigma**2))

popt,pcov = curve_fit(gaus,angles,data)#,p0=[0.18,mean,sigma])  ## <--- leave out the first estimation of the parameters
xx = np.linspace( -10, 10, 100 )  ## <--- calculate against a continuous variable

fig = plt.figure()
plt.plot(angles, data, "ob", label = "Measured")
plt.plot(xx,gaus(xx,*popt),'r',label='Fit')  ## <--- plot against the contious variable
plt.xlim(-10, 10)
plt.ylim(0, 2000)
plt.xticks(angles)
plt.title("$^{137}$Cs Zero Point")
plt.xlabel("Angle [$^\circ$]")
plt.ylabel("662 keV-Photon Count")
plt.grid()
plt.legend()
plt.savefig('normal.png')
plt.show()

在此示例中:

print( popt )

[  1.93154077e+03  -9.21486804e-01   3.26251063e+00]

请注意,参数的第一个估计值与结果相差几个数量级:0.18对1931.15.

Note that the first estimation of the parameter is orders of magnitude away from the result: 0.18 vs. 1931.15.

这篇关于使更好的高斯拟合数据点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆