从 sklearn 中的高斯混合模型中获取 PDF
Posted
技术标签:
【中文标题】从 sklearn 中的高斯混合模型中获取 PDF【英文标题】:Getting the PDF from the Gausian Mixture Model in sklearn 【发布时间】:2021-10-12 16:32:28 【问题描述】:我已将高斯混合模型 (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
这是意料之中的,因为在拟合时提供的数据中不存在负值 -5
到 0
,因此提供接近零的值。
我正在尝试使用带有sklearn
的python 来复制它。以下是我到目前为止所取得的成就。
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
返回一个矩阵,其中每一行表示属于n_components
数量类之一的概率(意味着沿行的总和 = 1)。然而,这不是预期的结果。我想知道b
的每个元素是从适合的gm
模型生成的概率,就像Matlab 一样。
如何通过 Python 实现这一点?谢谢。
【问题讨论】:
我认为(可能是错误的)您对数字 13 在这里所做的事情的理解,无论是在 matlab 代码中还是在 sklearns 代码中都有一点缺陷。浏览完文档后,您在此处使用的数字 13 实质上是在传达模型,以便在您提供给模型的 16 个一维数据样本中找到 13 个不同的高斯分布。 这不是OP描述的吗?我的意思是,我不明白您的理解与 OP 的不同。 @sai,这是真的。在这两种语言中安装 GMM 时我没有任何问题。例如,两种语言的均值是13x1
向量。我的问题与下一步有关。我想要一个在 Python 中来自 Matlab 提供的 fit gm
模型的元素 PDF。我希望这次我的意图很明确。
我现在明白了。谢谢你的解释。
【参考方案1】:
predict_proba
查找将单个数据行分配给 GMM 所基于的每个组件(在您的情况下为 13 个组件)的概率。有关更多信息,请参阅 Jake VanderPlas 的excellent chapter。
要获取 pdf,您需要使用 score_samples
函数 - 该函数返回从拟合的 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 实现进行交叉检查,他们会更好地达成一致。
【讨论】:
所以您建议使用softmax
对其进行规范化?
是的,softmax,因为它是一个对数似然以上是关于从 sklearn 中的高斯混合模型中获取 PDF的主要内容,如果未能解决你的问题,请参考以下文章