估计两个信号样本的互信息

机器算法验证 matlab 密度函数 互信息
2022-03-22 18:28:54

我有两个信号s1s2,每个采样 170 次。

x = 0.2:0.2:34;
s1 = rand(size(x));
s2 = randn(size(x));

计算两个离散变量之间的 MI(互信息)需要了解它们的边际概率分布函数及其联合概率分布。

我正在使用这个Kernel Density Estimator估计每个信号的边际分布。

[~,pdf1,xmesh1,~]=kde(s1);
[~,pdf2,xmesh2,~]=kde(s2);

我正在使用这个2D Kernel Density Estimator估计联合 pdf 。

[~,pdf_joint,X,Y]=kde2d(data);

我创建了一个函数,它将原始信号、它们的边缘 pdf 和它们的联合 pdf 作为输入,并计算互信息。

不幸的是,我似乎在这个功能中有一些拥抱错误,我无法弄清楚。MI 应该始终是正数,但我得到的是复数和/或负数!

我为计算 MI 编写的函数如下所示。

function mi = computeMI(s1, s2, pdf1, xmesh1, pdf2, xmesh2, pdf_joint, X, Y)

N = size(s1, 2);
p_i = zeros(1, N);
p_j = zeros(1, N);

for i=1:N
    p_i(i) = interp1(xmesh1, pdf1, s1(i));
    p_j(i) = interp1(xmesh2, pdf2, s2(i));
end;

mi = 0;

p_ij = zeros(N, N);

for j=1:N
    for i=1:N
        p_ij(i, j) = interp2(X, Y, pdf_joint, s1(i), s2(j));
        delta_mi = p_ij(i,j) * (log2(p_ij(i,j) / (p_i(i) * p_j(j))));
        mi = mi + delta_mi;
    end;
end;

非常感谢您的帮助。

1个回答

我无法立即在您的程序中看到错误。但是,我认为很少有事情可能会改变我们的结果。

首先,我会使用一世jp一世j(日志p一世j-日志p一世-日志pj)代替一世jp一世j日志p一世jp一世pj为了数值稳定性。作为一般规则,如果您必须乘以概率,最好在对数域中工作。

其次,由于您对边缘和联合分布使用不同的核密度估计器,因此它们可能不一致。p(X,是的)是你的共同估计和q(X)你的边际之一的估计。自从q是联合分布的边际,它必须持有p(X,是的)d是的=p(X)=q(X). 不一定是这种情况,因为您使用了两个不同的估算器。

另一件可能给你带来麻烦的事情是你插值。如果你插值密度,它肯定不会再集成到一个密度(当然,这取决于你使用的插值类型)。这意味着您甚至不再使用适当的密度。

您可以尝试的最简单的解决方案是使用二维直方图H一世j. H一世j=H一世j/一世jH一世j是归一化的直方图。然后你通过H一世=jH一世jHj=一世H一世j. 然后可以通过计算互信息

lh1 = log(sum(h,1));
lh2 = log(sum(h,2));
I = sum(sum(h .* bsxfun(@minus,bsxfun(@minus,log(h),lh1),lh2) ));

对于越来越多的数据点和较小的 bin,这应该收敛到正确的值。在我们的例子中,我会尝试使用不同的 bin 大小,计算 MI 并从 MI 值看起来稳定的区域获取 bin 大小。或者,您可以使用启发式方法

斯科特,DW(1979)。关于最优和基于数据的直方图。生物计量学,66(3),605-610。doi:10.1093/biomet/66.3.605

选择 bin 大小。

如果您真的想使用内核密度估计器,我会采用上面的方法并

  1. 从联合估计中计算边际
  2. 不使用插值。据我了解,KDE 无论如何都会为您提供任意基点的密度值。更好地使用那些。

最后一点,虽然 MI 通过直方图方法收敛到真正的 MI,但熵不会。因此,如果您想使用直方图方法估计差分熵,则必须校正 bin 大小。