在核二元密度估计图下计算体积

时间:2016-05-20 22:35:34

标签: r estimation entropy kernel-density

我需要计算一种称为互信息的度量。首先,我需要计算另一个称为熵的度量,例如x和y的联合熵:

-∬p(x,y)·log p(x,y)dxdy

因此,为了计算p(x,y),我使用了内核密度估算器(以这种方式,函数kde2d,它返回了Z值(x和y的概率)窗口)。

同样,到目前为止,我有一个Z[1x100] x [1x100]的矩阵,它等于我的p(x,y)。但我必须通过发现表面下的体积(doble积分)来整合它。但我没有找到办法做到这一点。用于计算双正交的函数quad2d没有用,因为我只集成了一个数值矩阵p(x,y),它给了我一个常数....

任何人都知道找到音量/计算双积分的东西吗?

persp3d

的情节图像

density estimate

谢谢大家!!!!

1 个答案:

答案 0 :(得分:4)

获得kde2d的结果后,非常直接来计算数值积分。下面的示例会话概述了如何执行此操作。

如您所知,数字双积分只是一个二维求和。默认情况下,kde2d会将range(x)range(y)作为2D域。我看到你有100 * 100矩阵,所以我认为你已经使用n = 100设置了kde2d。现在,kde$xkde$y定义了一个100 * 100网格,den$z为每个网格单元格提供了密度。很容易计算每个网格单元的大小(它们都相等),然后我们做三个步骤:

  1. 找到归一化常数;虽然我们知道理论上,密度总和(或积分)为1,但是在计算机离散化之后,它只接近1.所以我们首先计算这个归一化常数以便以后重新缩放;
  2. 熵的积分是z * log(z);由于z是100 * 100矩阵,因此这也是一个矩阵。你只需将它们相加,然后乘以单元格大小cell_size,就可得到非标准化的熵;
  3. 重新缩放标准化的非标准化熵。
  4. ## sample data: bivariate normal, with covariance/correlation 0
    set.seed(123); x <- rnorm(1000, 0, 2)  ## marginal variance: 4
    set.seed(456); y <- rnorm(1000, 0, 2)  ## marginal variance: 4
    
    ## load MASS
    library(MASS)
    
    ## domain:
    xlim <- range(x)
    ylim <- range(y)
    ## 2D Kernel Density Estimation
    den <- kde2d(x, y, n = 100, lims = c(xlim, ylim))
    ##persp(den$x,den$y,den$z)
    z <- den$z  ## extract density
    
    ## den$x, den$y expands a 2D grid, with den$z being density on each grid cell
    ## numerical integration is straighforward, by aggregation over all cells
    ## the size of each grid cell (a rectangular cell) is:
    cell_size <- (diff(xlim) / 100) * (diff(ylim) / 100)
    
    ## normalizing constant; ideally should be 1, but actually only close to 1 due to discretization
    norm <- sum(z) * cell_size
    
    ## your integrand: z * log(z) * (-1):
    integrand <- z * log(z) * (-1)
    
    ## get numerical integral by summation:
    entropy <- sum(integrand) * cell_size
    
    ## self-normalization:
    entropy <- entropy / norm
    

    <强>验证

    上面的代码给出了4.230938的熵。现在,Wikipedia - Multivariate normal distribution给出了熵公式:

    (k / 2) * (1 + log(2 * pi)) + (1 / 2) * log(det(Sigma))
    

    对于上述双变量正态分布,我们有k = 2。我们有Sigma(协方差矩阵):

    4  0
    0  4
    

    其行列式为16.因此,理论值为:

    (1 + log(2 * pi)) + (1 / 2) * log(16) = 4.224171
    

    很好的比赛!