【问题标题】:Calculate the volume under a plot of kernel bivariate density estimation计算核双变量密度估计图下的体积
【发布时间】:2016-09-18 07:36:55
【问题描述】:

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

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

因此,为了计算 p(x,y),我使用了核密度估计器(这样,函数 kde2d,它返回了 Z 值(在该窗口中具有 x 和 y 的概率)。

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

任何人都知道找到体积/计算二重积分的东西吗?

剧情图片来自persp3d

谢谢大家!!!!

【问题讨论】:

    标签: r estimation entropy kernel-density


    【解决方案1】:

    kde2d 获得结果后,计算数值积分就非常简单了。下面的示例会话概述了如何做到这一点。

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

    1. 找到归一化常数;虽然我们知道理论上密度总和(或积分)为 1,但经过计算机离散化后,它仅接近 1。所以我们首先计算这个归一化常数,以便以后重新缩放;
    2. 熵的被积函数是z * log(z);因为z 是一个 100 * 100 的矩阵,所以这也是一个矩阵。您只需将它们相加,然后将其乘以单元格大小cell_size,即可得到非归一化熵;
    3. 为标准化熵重新缩放非标准化熵。

    ## 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
    

    好匹配!

    【讨论】:

    • 如果我离散化 a priori 并以 bin 宽度计算频率会更容易吗?它会产生更多的误差估计吗?谢谢。
    • 我一直在根据直方图测试您的方法,可能发生了错误。当我在 1000 个随机样本上测试你的方法时(正如你在上面解释的那样),熵给了我接近零的值。但是,与理论相比,它是不正确的,因为它应该给我 log(n)。我使用了其他一些熵包,它给了我正确的结果〜log(n)。你知道发生了什么事吗?谢谢!
    • 谢谢!这对于高斯正态内核是正确的,但是对于未定义的密度呢?对正态密度的测试应该会产生很好的结果,但是在我的例子中,当对金融时间序列(不是随机的)进行测试时,这些结果发生了很大的变化,特别是因为带宽(默认为高斯)。我认为我在分布的尾部遇到了一些问题。考虑错误的问题是我有一个广泛的矩阵要成对计算(时间序列),所以我会更多地考虑可视化。再次感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 2014-03-22
    • 2020-04-18
    • 2011-08-07
    • 2011-04-22
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多