KL散度与JS散度

KL散度(Kullback-Leibler divergence)

又称KL距离,相对熵。KL散度是描述两个概率分布P和Q之间差异的一种方法。直观地说,可以用来衡量给定任意分布偏离真实分布的程度,如果两个分布完全匹配,那么KL(p||q)=0,否则它的取值应该是0~∞(inf)之间。KL散度越小,真实分布与近视分布之间的匹配程度就越好。

KL散度的计算公式

离散概率分布的KL散度计算公式:
K L ( p ∣ ∣ q ) = ∑ p ( x ) log ⁡ p ( x ) q ( x ) KL(p||q)=\sum p(x)\log \frac{p(x)}{q(x)} KL(pq)=p(x)logq(x)p(x)
连续概率分布的KL散度计算公式:
K L ( p ∣ ∣ q ) = ∫ p ( x ) log ⁡ p ( x ) q ( x ) d x KL(p||q)=\int p(x)\log \frac{p(x)}{q(x)}dx KL(pq)=p(x)logq(x)p(x)dx

KL散度的基本性质

  • 非负性
    KL散度的结果是非负的,简单证明如下:
    K L ( p ∣ ∣ q ) = ∑ x p ( x ) log ⁡ p ( x ) q ( x ) = − ∑ x p ( x )   l o g q ( x ) p ( x ) KL(p||q)=\sum _xp(x) \log \frac {p(x)}{q(x)}=-\sum _xp(x)\ log \frac{q(x)}{p(x)} KL(pq)=xp(x)logq(x)p(x)=xp(x) logp(x)q(x)
    由于对数函数是一个上凸函数,所以有:
    ≥ − log ⁡ [ ∑ x p ( x ) q ( x ) p ( x ) ] = − log ⁡ [ ∑ x q ( x ) ] = − log ⁡ 1 = 0 \ge-\log[\sum_xp(x)\frac{q(x)}{p(x)}]=-\log[\sum_xq(x)]=-\log 1=0 log[xp(x)p(x)q(x)]=log[xq(x)]=log1=0
  • 不对称性
    K L ( p ∣ ∣ q ) ̸ = K L ( q ∣ ∣ p ) KL(p||q)\not=KL(q||p) KL(pq)̸=KL(qp)

关于KL散度的数学概念,可移步[link] https://www.jiqizhixin.com/articles/2018-05-29-2?from=synced&keyword=直观解读kl散度的数学概念

JS散度(Jensen-Shannon divergence)

JS散度也称JS距离,是KL散度的一种变形。

JS散度的数学公式

J S ( p ∣ ∣ q ) = 1 2 K L ( p ∣ ∣ p + q 2 ) + 1 2 K L ( q ∣ ∣ p + q 2 ) JS(p||q)=\frac12KL(p||\frac{p+q}2)+\frac12KL(q||\frac{p+q}{2}) JS(pq)=21KL(p2p+q)+21KL(q2p+q)

不同于KL的主要两方面

  • 值域范围
    JS散度的值域范围是[0,1],相同为0,相反则为1。相比较于KL,对相似度的判别更准确了。
  • 对称性
    J S ( p ∣ ∣ q ) = J S ( q ∣ ∣ p ) JS(p||q)=JS(q||p) JS(pq)=JS(qp),而对称能让散度度量更准确。下面用一段代码展示这其中的道理:
import numpy as np
import math
# 离散随机变量的KL散度和JS散度的计算方法
def KL(p,q):
    #p,q为两个list,里面存着对应的取值的概率,整个list相加为1
    if 0 in q:
        raise ValueError
    return sum(_p * math.log(_p/_q) for (_p,_q) in zip(p,q) if _p != 0)

def JS(p,q):
    M = [0.5 * (_p + _q) for (_p,_q) in zip(p,q)]
    return 0.5 * (KL(p,M) + KL(q,M))

def exp(a,b):
    a = np.array(a,dtype=np.float32)
    b = np.array(b,dtype=np.float32)
    a /= a.sum()
    b /= b.sum()
    print(a)
    print(b)
    print(KL(a,b))
    print(JS(a,b))
# exp 1
exp([1,2,3,4,5],[5,4,3,2,1])

[0.06666667 0.13333334 0.2        0.26666668 0.33333334]
[0.33333334 0.26666668 0.2        0.13333334 0.06666667]
0.5216030835963031
0.11968758856917597

# exp 2
#把公式中的第二个分布做修改,假设这个分布中有某个值的取值非常小,就有可能增加两个分布的散度值
exp([1,2,3,4,5],[1e-12,4,3,2,1])
exp([1,2,3,4,5],[5,4,3,2,1e-12])

[0.06666667 0.13333334 0.2        0.26666668 0.33333334]
[1.e-13 4.e-01 3.e-01 2.e-01 1.e-01]
2.065502018456509
0.0985487692550548
[0.06666667 0.13333334 0.2        0.26666668 0.33333334]
[3.5714287e-01 2.8571430e-01 2.1428572e-01 1.4285715e-01 7.1428574e-14]
9.662950847122168
0.19399530008415986

# exp 3
exp([1e-12,2,3,4,5],[5,4,3,2,1])
exp([1,2,3,4,1e-12],[5,4,3,2,1])

[7.1428574e-14 1.4285715e-01 2.1428572e-01 2.8571430e-01 3.5714287e-01]
[0.33333334 0.26666668 0.2        0.13333334 0.06666667]
0.7428131560123377
0.19399530008415986
[1.e-01 2.e-01 3.e-01 4.e-01 1.e-13]
[0.33333334 0.26666668 0.2        0.13333334 0.06666667]
0.38315075574389773
0.0985487692550548

将第一个实验与第二个实验做对比,可以看出KL散度的波动比较大,而JS的波动相对小。
如果将第二个实验和第三个实验做对比,可以发现KL散度在衡量两个分布的差异时具有很大的不对称性。如果后面的分布在某一个值上缺失,就回得到很大的散度值;但是如果前面的分布在某一个值上缺失,最终的KL散度并没有太大的波动。这个demo可以清楚地看出KL不对称性带来的一些小问题,而JS具有对称性,所以第二个实验和第三个实验的JS散度实际上是距离相等的分布组。

  • 10
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值