Python 两个gmm的KL散度

Python 两个gmm的KL散度,python,numpy,statistics,scipy,scikit-learn,Python,Numpy,Statistics,Scipy,Scikit Learn,我有两个GMM,用于在同一空间中拟合两组不同的数据,我想计算它们之间的KL散度 目前,我正在使用sklearn()中定义的GMMs和KL disference()的SciPy实现 我该怎么做呢?我是否只想创建成吨的随机点,在两个模型(称它们为P和Q)上获得它们的概率,然后使用这些概率作为我的输入?或者在SciPy/SKLearn环境中是否有更规范的方法来实现这一点?GMM之间的KL差异没有封闭的形式。不过,你可以很容易地完成蒙特卡洛。回想一下KL(p | | q)=\int p(x)log(p(

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

目前,我正在使用sklearn()中定义的GMMs和KL disference()的SciPy实现


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

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
;这是用于离散分布的

如果您想要对称和平滑的
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
实际上是混合物密度的两倍;将其从平均操作中取出可以避免一些失败。)

封闭形式不存在。看看这篇文章,得到它的近似值。嗨,道格尔,我正试图使用你定义的gym_js函数来计算我的模型的健壮性,但不确定n_样本在这里做什么,以及如何解释返回值?如果我使用所有数据集,我必须用它们来建立模型gmm_p和gmm_q相同数量的集群并输入到这个函数中,我可以基于js度量在这里确认我的模型的健壮性吗?谢谢。我来这里是想看看我是否可以计算两个分布之间的js差异,看起来我可以(根据这个答案改编的代码在这里作为答案:)