Scikit 学习,将高斯拟合到直方图

Scikit learn, fitting a gaussian to a histogram

在 scikit-learn 中,使用 GMM 拟合高斯峰似乎适用于离散数据数据点。 有没有一种方法可以将 GMM 与已经分箱或聚合成直方图的数据一起使用?

例如,以下代码是一种变通方法,它在拟合之前将分箱数据转换为离散数据点:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import mixture

def fit_one_peak(x, linspace):
    gmm = mixture.GMM(n_components=1) # gmm for one components
    gmm.fit(x) # train it!
    m1 = gmm.means_
    w1 = gmm.weights_
    return np.exp(gmm.score_samples(linspace)[0]), m1[0][0], w1[0]

def convert_to_signal(d, s):
    c = []
    count = 0
    for i in s:
        for j in range(int(d[count])):  # No floats!
            c.append(i)
        count += 1
    return c

d = [0.5, 2, 5, 3, 1, 0.5]  # y data, which is already binned
s = [0, 1, 2, 3, 4, 5]  # x data

signal = convert_to_signal(d, s)
linspace = np.linspace(s[0], s[-1], len(s))
l, mean, weight = fit_one_peak(signal, linspace)
l = l*(np.max(d)/ np.max(l))  # Normalize the fitted y

fig = plt.figure()
plt.plot(s, d, label='Original')
plt.plot(linspace, l, label='Fitted')
plt.hist(signal, label='Re-binned')
plt.legend()

也许您混淆了从一组数据点优化统计模型和通过一组数据点拟合曲线的概念。

上面引用的一些 scikit-learn 代码试图从一组数据点优化统计模型。换句话说,在那种情况下,您正在尝试估计可能生成数据点集的源的概率分布参数。有关这方面的更多信息,您可能需要阅读 this article. The way that this information is then presented to a viewer is a totally independent subject. For example, you can recover the parameters of your gaussian (i.e. mean and standard deviation) from the data points and then overlay a gaussian CURVE on top of your data histogram. For more information on this, please see this link.

中的 "Principles" 部分

当你只有直方图数据时,即数据集中每个数据项的出现频率,那么你就有了 [(x0,y0), (x1,y1) 形式的数据点对, (x2,y2), ..., (xn,yn)]。在这种情况下,您正在尝试通过这些特定数据点来拟合曲线,您可以使用最小二乘之类的方法来做到这一点。有关此的更多信息,请参阅 this, this and this link。

因此,要从数据集中优化您的高斯概率密度函数,您可以使用 sklearn 的 GMM 模型并直接将您的数据集提供给它(即,将您的直方图所基于的原始数据提供给它)

如果您已经有了直方图的数据,那么您将会查看诸如 curve_fit 之类的函数。此处请注意:由于您正在尝试拟合概率分布函数,因此您的数据(即 HISTOGRAM 数据的 Y 分量)必须进行归一化才能获得 1.0 的总和。为此,只需将每个频率计数除以所有频率计数的总和即可。

有关更多信息,您可能需要查看 this, this and this link。

希望对您有所帮助。