如何在python中拟合高斯曲线?

2024-05-16 09:45:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我得到了一个数组,当我绘制它的时候,我得到了一个带有噪声的高斯形状。我想拟合高斯分布。这是我已经得到的,但是当我画出来的时候,我没有得到一个拟合高斯函数,而是得到一条直线。我试过很多不同的方法,但我就是想不出来。

random_sample=norm.rvs(h)

parameters = norm.fit(h)

fitted_pdf = norm.pdf(f, loc = parameters[0], scale = parameters[1])

normal_pdf = norm.pdf(f)

plt.plot(f,fitted_pdf,"green")
plt.plot(f, normal_pdf, "red")
plt.plot(f,h)
plt.show()

click for image


Tags: 方法函数normpdfplot绘制pltrandom
3条回答

您可以使用^{}中的fit,如下所示:

import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt

data = np.random.normal(loc=5.0, scale=2.0, size=1000)
mean,std=norm.fit(data)

norm.fit试图根据数据拟合正态分布的参数。在上面的例子中,mean大约是2,std大约是5。

为了绘制它,可以执行以下操作:

plt.hist(data, bins=30, normed=True)
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
y = norm.pdf(x, mean, std)
plt.plot(x, y)
plt.show()

enter image description here

蓝框是数据的直方图,绿线是带有拟合参数的高斯分布。

您还可以使用scipy.optimize()中的curve_fit拟合高斯函数,在这里您可以定义自己的自定义函数。这里,我给出一个高斯曲线拟合的例子。例如,如果有两个数组xy

from scipy.optimize import curve_fit
from scipy import asarray as ar,exp

x = ar(range(10))
y = ar([0,1,2,3,4,5,4,3,2,1])

n = len(x)                          #the number of data
mean = sum(x*y)/n                   #note this correction
sigma = sum(y*(x-mean)**2)/n        #note this correction

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

popt,pcov = curve_fit(gaus,x,y,p0=[1,mean,sigma])

plt.plot(x,y,'b+:',label='data')
plt.plot(x,gaus(x,*popt),'ro:',label='fit')
plt.legend()

曲线拟合函数需要用三个参数调用:要拟合的函数(在本例中为gaus())、自变量的值(在本例中为x)和从属变量的值(在本例中为y)。curve_fit funtion than返回具有最佳参数的数组(在最小二乘意义上)和包含最佳参数协方差的第二个数组(稍后将详细介绍)。

下面是拟合的输出。

enter image description here

有很多方法可以将高斯函数拟合到数据集。我经常在拟合数据时使用astropy,这就是为什么我想添加这个作为额外的答案。

我使用的一些数据集应该模拟高斯噪声:

import numpy as np
from astropy import modeling

m = modeling.models.Gaussian1D(amplitude=10, mean=30, stddev=5)
x = np.linspace(0, 100, 2000)
data = m(x)
data = data + np.sqrt(data) * np.random.random(x.size) - 0.5
data -= data.min()
plt.plot(x, data)

enter image description here

然后拟合它实际上非常简单,您可以指定要拟合数据的模型和拟合者:

fitter = modeling.fitting.LevMarLSQFitter()
model = modeling.models.Gaussian1D()   # depending on the data you need to give some initial values
fitted_model = fitter(model, x, data)

并绘制:

plt.plot(x, data)
plt.plot(x, fitted_model(x))

enter image description here


不过,也可以只使用Scipy,但必须自己定义函数:

from scipy import optimize

def gaussian(x, amplitude, mean, stddev):
    return amplitude * np.exp(-((x - mean) / 4 / stddev)**2)

popt, _ = optimize.curve_fit(gaussian, x, data)

这将返回拟合的最佳参数,您可以这样绘制:

plt.plot(x, data)
plt.plot(x, gaussian(x, *popt))

enter image description here

相关问题 更多 >