如何在Python中拟合双高斯分布?

汤姆·库鲁辛格

我正在尝试使用Python获取数据(link的双高斯分布原始数据的格式为:

在此处输入图片说明

对于给定的数据,我想获得图中所示峰的两个高斯曲线。我尝试使用以下代码(source):

from sklearn import mixture
import matplotlib.pyplot
import matplotlib.mlab
import numpy as np
from pylab import *
data = np.genfromtxt('gaussian_fit.dat', skiprows = 1)
x = data[:, 0]
y = data[:, 1]
clf = mixture.GMM(n_components=2, covariance_type='full')
clf.fit((y, x))
m1, m2 = clf.means_
w1, w2 = clf.weights_
c1, c2 = clf.covars_
fig = plt.figure(figsize = (5, 5))
plt.subplot(111)
plotgauss1 = lambda x: plot(x,w1*matplotlib.mlab.normpdf(x,m1,np.sqrt(c1))[0], linewidth=3)
plotgauss2 = lambda x: plot(x,w2*matplotlib.mlab.normpdf(x,m2,np.sqrt(c2))[0], linewidth=3)
fig.savefig('gaussian_fit.pdf')

但是我无法获得所需的输出。那么,如何在Python中获得双高斯分布?

更新资料

我可以使用以下代码来拟合单个高斯分布:

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

data = np.genfromtxt('gaussian_fit.dat', skiprows = 1)
x = data[:, 0]
y = data[:, 1]
n = len(x)
mean = sum(x*y)/n
sigma = sum(y*(x-mean)**2)/n


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])


fig = plt.figure(figsize = (5, 5))
plt.subplot(111)
plt.plot(x, y, label='Raw')
plt.plot(x, gaus(x, *popt), 'o', markersize = 4, label='Gaussian fit')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
fig.savefig('gaussian_fit.pdf')

在此处输入图片说明

spfrnd

You can't use scikit-learn for this, because the you are not dealing with a set of samples whose distribution you want to estimate. You could of course transform your curve to a PDF, sample it and then try to fit it using a Gaussian mixture model, but that seems to be a bit of an overkill to me.

Here's a solution using simple least square curve fitting. To get it to work I had to remove the background, i.e. ignore all data points with y < 5, and also provide a good starting vector for leastsq, which can be estimated form a plot of the data.

Finding the Starting Vector

The parameter vector that that is found by the least squares method is the vector

params = [c1, mu1, sigma1, c2, mu2, sigma2]

在这里,c1c2是两个高斯的比例因子,即它们的高度,mu1并且mu2是平均值,即峰的水平位置sigma1sigma2确定高斯宽度的标准偏差。为了找到一个起始载体我只是看着数据的曲线和估计的两个峰(=的高度c1c2分别)和它们的水平位置(= mu1mu1,分别地)。sigma1sigma2设置为1.0

from sklearn import mixture
import matplotlib.pyplot
import matplotlib.mlab
import numpy as np
from pylab import *
from scipy.optimize import leastsq

data = np.genfromtxt('gaussian_fit.dat', skiprows = 1)
x = data[:, 0]
y = data[:, 1]

def double_gaussian( x, params ):
    (c1, mu1, sigma1, c2, mu2, sigma2) = params
    res =   c1 * np.exp( - (x - mu1)**2.0 / (2.0 * sigma1**2.0) ) \
          + c2 * np.exp( - (x - mu2)**2.0 / (2.0 * sigma2**2.0) )
    return res

def double_gaussian_fit( params ):
    fit = double_gaussian( x, params )
    return (fit - y_proc)

# Remove background.
y_proc = np.copy(y)
y_proc[y_proc < 5] = 0.0

# Least squares fit. Starting values found by inspection.
fit = leastsq( double_gaussian_fit, [13.0,-13.0,1.0,60.0,3.0,1.0] )
plot( x, y, c='b' )
plot( x, double_gaussian( x, fit[0] ), c='r' )

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在python中,如何将多元高斯分布除以单独的高斯?

如何在y轴上绘制高斯分布?

如何在 Python 中高效计算两个高斯分布的热图?

如何提取适合R中的高斯分布的值?

估计曲线与高斯分布的相似度(在Python中)

使用高斯分布Python的方差

R中累积高斯分布的逆

如何在R中的这两个场景中为高斯分布生成数据?

在Matlab中,如何将多元高斯分布除以高斯?

如何在Python中计算非高斯分布的中位数附近的中位数和68%置信区间?

多重高斯分布

如何在python中拟合三个高斯峰?

如何将反高斯分布拟合到我的数据,最好使用fitdist {fitdistrplus}

如何在一天内制作我的随机高斯分布

如何在高斯分布的两个值之间产生随机数

在3D图python中的平面上绘制一维高斯分布

如何为ROI生成高斯分布强度?

如何实现高斯分布的概率密度函数

如何估计噪声层后面的高斯分布?

Matlab如何生成高斯分布随机数?

在Python中生成3D高斯分布

积分两个边界之间的高斯分布[Python]

高斯分布中的参数 K ang u

如何在python中使用MLE拟合双指数分布?

如何在斯卡拉风中初始化特定的随机种子,例如针对高斯分布?

如何通过Python直接在频域中生成高斯分布的随机样本:NumPy / SciPy?

python中的高斯拟合失败

Python:为变量创建高斯分布,并使用高斯值在循环上运行程序

多元高斯分布公式的实现