【问题标题】:KL-Divergence of two GMMs两个 GMM 的 KL-Divergence
【发布时间】:2014-11-22 15:56:41
【问题描述】:

我有两个 GMM,用于在同一空间中拟合两组不同的数据,我想计算它们之间的 KL 散度。

目前我正在使用 sklearn (http://scikit-learn.org/stable/modules/generated/sklearn.mixture.GMM.html) 中定义的 GMM 和 KL-divergence (http://docs.scipy.org/doc/scipy-dev/reference/generated/scipy.stats.entropy.html) 的 SciPy 实现

我该怎么做呢?我是否只想创建大量随机点,在两个模型中的每一个上获取它们的概率(称为 P 和 Q),然后使用这些概率作为我的输入?或者在 SciPy/SKLearn 环境中是否有一些更规范的方法可以做到这一点?

【问题讨论】:

标签: python numpy statistics scipy scikit-learn


【解决方案1】:

GMM 之间的 KL 散度没有封闭形式。不过,您可以轻松地进行蒙特卡罗。回想一下KL(p||q) = \int p(x) log(p(x) / q(x)) dx = E_p[ log(p(x) / q(x))。所以:

def gmm_kl(gmm_p, gmm_q, n_samples=10**5):
    X = gmm_p.sample(n_samples)
    log_p_X, _ = gmm_p.score_samples(X)
    log_q_X, _ = gmm_q.score_samples(X)
    return log_p_X.mean() - log_q_X.mean()

mean(log(p(x) / q(x))) = mean(log(p(x)) - log(q(x))) = mean(log(p(x))) - mean(log(q(x))) 在计算上要便宜一些。)

你不想使用scipy.stats.entropy;这是离散分布。

如果您想要对称和平滑的 Jensen-Shannon divergence KL(p||(p+q)/2) + KL(q||(p+q)/2),则非常相似:

def gmm_js(gmm_p, gmm_q, n_samples=10**5):
    X = gmm_p.sample(n_samples)
    log_p_X, _ = gmm_p.score_samples(X)
    log_q_X, _ = gmm_q.score_samples(X)
    log_mix_X = np.logaddexp(log_p_X, log_q_X)

    Y = gmm_q.sample(n_samples)
    log_p_Y, _ = gmm_p.score_samples(Y)
    log_q_Y, _ = gmm_q.score_samples(Y)
    log_mix_Y = np.logaddexp(log_p_Y, log_q_Y)

    return (log_p_X.mean() - (log_mix_X.mean() - np.log(2))
            + log_q_Y.mean() - (log_mix_Y.mean() - np.log(2))) / 2

log_mix_X/log_mix_Y 实际上是两倍混合密度的对数;将其从平均操作中剔除可以节省一些失败。)

【讨论】:

  • 您好 Dougal,我正在尝试使用您定义的 gym_js 函数来确定我的模型的稳健性,但不确定 n_samples 在这里做什么以及如何解释返回值?如果我使用所有数据集,我必须制作具有相同数量集群的模型 gmm_p 和 gmm_q 并输入到这个函数中,我可以根据此处的 js 指标确认我的模型的稳健性吗?谢谢。
  • 我来这里看看我是否可以计算两个分布之间的 js 散度,看起来我可以(改编自这个答案的代码在这里作为答案:stats.stackexchange.com/questions/345915/…
猜你喜欢
  • 2019-12-12
  • 2020-08-19
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
相关资源
最近更新 更多