【发布时间】:2016-01-15 16:43:57
【问题描述】:
我正在尝试使用 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 的回答所暗示的那样,您应该首先问自己为什么要将高斯拟合到数据中,因为 PDF 几乎总是被定义为在其范围内具有 0 的下限(即在这里您'正在考虑拟合'负'概率)。您可以通过例如转换数据减去最小值,然后 GMM 可能会更好。如果您向我们展示您尝试的输出和相关数据,您更有可能获得拟合 GMM 的帮助。
标签: python numpy scipy scikit-learn gaussian