从 sklearn 中的高斯混合模型获取 PDF

Getting the PDF from the Gausian Mixture Model in sklearn

我已将高斯混合模型 (GMM) 拟合到我拥有的数据系列。使用 GMM,我试图按元素获取另一个向量的概率。 Matlab 使用以下代码行实现此目的。

a = reshape(0:1:15, 14, 1);
gm = fitgmdist(a, 13);  % 13 specifies the number of components (means and covs for example) in the fit model

% Testing with new data
b = reshape(-5:1:5, 11, 1);
pdf(gm, b) 

    0.0000
    0.0000
    0.0000
    0.0000
    0.0018
    0.0643
    0.0658
    0.0671
    0.0666
    0.0662
    0.0672

这是预期的,因为负值 -50 不存在于拟合时提供的数据中,因此提供接近零的值。

我正在尝试使用 python 和 sklearn 来复制它。以下是我到目前为止所取得的成就。

from sklearn.mixture import GaussianMixture
import numpy as np

gm = GaussianMixture(n_components=13).fit(np.arange(16).reshape(-1, 1))

# Generate test data
b = np.arange(-5, 6)[:, None]
prob = gm.predict_proba(b).tolist()

"""
prob=
[[8.539939840944505e-152, 0.0, 1.9638856033086253e-68, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[2.238593143299414e-141, 0.0, 3.166463050557315e-63, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[5.868073258732079e-131, 0.0, 5.106947259415683e-58, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[1.5382109014584666e-120, 0.0, 8.239047963148164e-53, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[4.0321459413005606e-110, 0.0, 1.3296012030592655e-47, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[8.790691487706948e-139, 0.0, 1.7850932827696813e-81, 8.316994953954272e-40, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[6.040819196361928e-118, 0.0, 7.556403579572576e-66, 2.180313173877784e-29, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
[7.616317001277741e-99, 0.0, 5.870491452246584e-52, 1.0486913731065672e-20, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[1.761856615767359e-81, 0.9999999999999076, 8.370258307836422e-40, 9.254498458447064e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[7.477776611058069e-66, 0.0, 2.190323924113167e-29, 1.4984230843298664e-08, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9999999850157694, 0.0, 0.0], 
[5.823053603579932e-52, 0.0, 1.0519204995101235e-20, 4.4513567127132954e-05, 0.0, 0.0, 0.9999554864328727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
"""

数组 prob returns 一个矩阵,其中每一行表示属于 类 的 n_components 个之一的概率(暗示沿行求和 = 1).然而,这不是预期的结果。我想知道 b 每个元素从拟合 gm 模型生成的概率,就像 Matlab 那样。

如何通过 Python 实现此目的?谢谢。

predict_proba 找到将单个数据行分配给 GMM 所基于的每个组件的概率(在您的情况下,13 个组件)。有关更多信息,请参阅 Jake VanderPlas 的 excellent chapter.

要获取 pdf,您需要使用 score_samples 函数 - returns 从拟合的 GMM 中抽取每一行的加权对数概率:

b = np.arange(-5, 6)[:, None]
log_probs = gm.score_samples(b)
sum_of_scores = (np.exp(log_probs)).sum()
probs = np.exp(log_probs) / sum_of_scores
print('Probs sum: ', probs.sum()) # confirm sums to 1
print('pdf: ', probs.tolist())

请注意,在这个玩具示例中,由于 K-Means 聚类在 GMM 拟合算法初始部分的不确定性,您很可能不会从 matlab 中重现准确的结果,但是如果您确实有一个更现实、多样化、采样良好的数据集来交叉检查 MATLAB 实现,他们会同意得更好。