【问题标题】:KL divergence of continuous pdfs连续 pdf 的 KL 散度
【发布时间】:2014-02-28 14:08:21
【问题描述】:

假设我有两个 pdf,例如:

from scipy import stats
pdf_y = stats.beta(5, 9).pdf
pdf_x = stats.beta(9, 5).pdf

我想计算他们的KL divergence。在我重新发明轮子之前,PyData 生态系统中是否有任何内置函数可以做到这一点?

【问题讨论】:

    标签: python scipy statsmodels pymc


    【解决方案1】:

    KL 散度在 scipy.stats.entropy 中可用。来自文档字符串

    stats.entropy(pk, qk=None, base=None) 
    
    Calculate the entropy of a distribution for given probability values.           
    
    If only probabilities `pk` are given, the entropy is calculated as              
    ``S = -sum(pk * log(pk), axis=0)``.                                             
    
    If `qk` is not None, then compute a relative entropy (also known as             
    Kullback-Leibler divergence or Kullback-Leibler distance)                       
    ``S = sum(pk * log(pk / qk), axis=0)``.  
    

    【讨论】:

    • 你在哪里找到的?我无法使用documentation 上的功能
    • 我对来源很熟悉。现在有一个问题要将其添加到文档中。一定是疏忽。 github.com/scipy/scipy/pull/3420
    • 但是根据文档,这不适用于连续分布。你可以在那里用什么?
    • 缺乏降低这个答案的要点。无法将 stats.entropy 与 beta 分布一起使用,因为我们正在处理连续情况
    【解决方案2】:

    看起来包nimfa 有你要找的东西。 http://nimfa.biolab.si

    V = np.matrix([[1,2,3],[4,5,6],[6,7,8]])
    fctr = nimfa.mf(V, method = "lsnmf", max_iter = 10, rank = 3)
    fctr_res = nimfa.mf_run(fctr)
    # Print the loss function according to Kullback-Leibler divergence. By default Euclidean metric is used.
    print "Distance Kullback-Leibler: %5.3e" % fctr_res.distance(metric = "kl")
    

    这并不是您想要的,因为它似乎只需要一个输入,但它可能是一个开始的地方。

    此外,此链接可能很有用。似乎有一些代码(不是用 numpy)来计算相同的东西。 https://code.google.com/p/tackbp2011/source/browse/TAC-KBP2011/src/python-utils/LDA/kullback-leibler-divergence.py?r=100

    【讨论】:

      【解决方案3】:

      由于 KL-divergence 被定义为integral for the continuous case,恐怕您必须在两个分布的(超)空间上执行Monte Carlo integration

      在您的情况下,这意味着在区间 [0,1] 中均匀绘制随机数并计算两个 PDF 的值,以用于积分计算。

      【讨论】:

      • 如果我们知道使用了哪些发行版,那么可能会有一个封闭形式的解决方案。对于所讨论的 beta 分布,可以得出封闭形式的解决方案。不幸的是,它不适用于所有分布组合。
      【解决方案4】:

      在其他答案中,有经验的 KL 散度计算,而我们可以为所讨论的 Beta 分布提供封闭形式的解决方案。

      我无法在网络上找到带有 KL-div 的 sn-p 以进行 beta 分发。最后我自己编码。

      分享它可能对其他人有用:

      import numpy as np
      from scipy import special
      
      def kl(a1, b1, a2, b2):
        """https://en.wikipedia.org/wiki/Beta_distribution"""
        B = special.beta
        DG = special.digamma
        return np.log(B(a2, b2) / B(a1, b1)) + (a1 - a2) * DG(a1) + (b1 - b2) * DG(b1) + (
              a2 - a1 + b2 - b1) * DG(a1 + b1)
      

      【讨论】:

        猜你喜欢
        • 2018-08-10
        • 1970-01-01
        • 1970-01-01
        • 2017-11-02
        • 2018-09-27
        • 1970-01-01
        • 2017-10-03
        • 2015-08-24
        • 1970-01-01
        相关资源
        最近更新 更多