【问题标题】:python - KL divergence on numpy arrays with different lengthspython - 具有不同长度的numpy数组的KL散度
【发布时间】:2015-08-24 21:40:58
【问题描述】:

我将 KL-divergence ([http://docs.scipy.org/doc/scipy-dev/reference/generated/scipy.stats.entropy.html]) 的 SciPy 实现用于两个不同的 numpy 数组。

第一个,假设 "base_freq" 的标准长度为 2000 第二个,"test_freq" 长度可以根据样本取不同的值。所以假设它的长度是8000。

当这两个长度不同时,我如何计算 KL 散度???

我的想法是将第二个数组 ("test_freq") 分解为多个长度为 2000 的数组。但是这是怎么做到的?? 当 "test_freq" 获得 250 长度的样本时会发生什么?

【问题讨论】:

标签: python arrays numpy scipy


【解决方案1】:

首先我应该说我不是信息论专家。对于我使用 KL-divergence 的一个应用程序,我按像素比较两个图像以计算丢失的位数。如果图像具有不同的大小,您提出的方法将要求对于较小图像中的每个像素,我选择较大图像中的 对应 像素,而不是任何旧像素。我的理解是,KL 散度只有在您比较以相同方式(即相同的时间或空间采样间隔)采样的两个信号时才有意义。

如果你想按照你的建议去做,你可以使用numpy.random.choice:

import numpy as np

def uneven_kl_divergence(pk,qk):
    if len(pk)>len(qk):
        pk = np.random.choice(pk,len(qk))
    elif len(qk)>len(pk):
        qk = np.random.choice(qk,len(pk))
    return np.sum(pk * np.log(pk/qk))

【讨论】:

  • np.random.choice 弄乱了我的数据,我不希望这样。因为如果我的 base_freq 较小,我不希望它随机选择应该是哪些数据保留。无论如何,我将 NaN 作为结果,但感谢您的回答!
  • @lolkos:你的意思是你用np.nan填充了向量[缺少元素的地方]?
【解决方案2】:

免责声明:我不是统计专家。

KL-Divergence 是概率分布之间的度量。这意味着您必须确保熵函数的输入是来自同一样本空间的两个有效概率分布。

在您的情况下,您有有限数量的可能值,因此您有一个离散随机变量。这也意味着变量的每个结果都可以通过多次试验的出现频率来衡量。

让我举一个简单的例子。假设您的随机变量代表一个不完美的骰子,它有 6 个可能的结果(6 个面)。你掷骰子 100 次。

假设你得到了以下绘图分布:

1: 10 times
2: 12 times
3: 08 times
4: 30 times
5: 20 times
6: 20 times

由于每个结果(一方)发生了多次,您只需将每个结果计数除以 100。这是您的频率,也是您的概率。

所以我们现在有:

P(side=1) = 10/100 = .10
P(side=2) = 12/100 = .12
P(side=3) = 08/100 = .08
P(side=4) = 30/100 = .30
P(side=5) = 20/100 = .20
P(side=6) = 20/100 = .20

最后,这是你的概率分布:

[.10, .12, .08, .30, .20, .20]

注意它总和为 1,因为它是概率分布的预期值。

如果您进行第二次实验并得出不同的概率分布,即使您这次的试验次数不是 100,它仍然有 6 个概率。

这就是说,比较来自不同样本空间的两个概率分布是没有意义的。如果您有办法将样本空间转换为另一个样本空间,那将是可能的。但是,请确保您的概率分布是来自同一样本空间的表示。比较 6 面骰子和 8 面骰子的概率是没有意义的,因为它们代表的不是同一件事。

【讨论】:

    【解决方案3】:

    在一些文章中,我看到人们在计算 KL 散度之前计算数组的直方图

    a = torch.tensor(np.histogram(np.array([0.1, 0.2, 0.3]))[-1])
    b = torch.tensor(np.histogram(np.array([0.2, 0.4]))[-1])
    loss = nn.KLDivLoss()
    dist = loss(a, b)
    

    【讨论】:

      猜你喜欢
      • 2018-08-10
      • 1970-01-01
      • 2021-06-10
      • 2015-05-02
      • 2016-10-13
      • 2022-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多