计算 KL距离 (相对熵)
KL距離,是Kullback-Leibler差異(Kullback-Leibler Divergence)的簡稱,也叫做相對熵(RelativeEntropy)。它衡量的是相同事件空間里的兩個(gè)概率分布的差異情況。其物理意義是:在相同事件空間里,概率分布P(x)的事件空間,若用概率分布Q(x)編碼時(shí),平均每個(gè)基本事件(符號)編碼長度增加了多少比特。
我們用D(P||Q)表示KL距離,計(jì)算公式如下:
當(dāng)兩個(gè)概率分布完全相同時(shí),即P(x)=Q(X),其相對熵為0 。我們知道,概率分布P(X)的信息熵為:
其表示,概率分布P(x)編碼時(shí),平均每個(gè)基本事件(符號)至少需要多少比特編碼。通過信息熵的學(xué)習(xí),我們知道不存在其他比按照本身概率分布更好的編碼方式了,所以D(P||Q)始終大于等于0的。雖然KL被稱為距離,但是其不滿足距離定義的三個(gè)條件:1)非負(fù)性;2)對稱性(不滿足);3)三角不等式(不滿足)。
我們以一個(gè)例子來說明,KL距離的含義。
假如一個(gè)字符發(fā)射器,隨機(jī)發(fā)出0和1兩種字符,真實(shí)發(fā)出概率分布為A,但實(shí)際不知道A的具體分布。現(xiàn)在通過觀察,得到概率分布B與C。各個(gè)分布的具體情況如下:
A(0)=1/2,A(1)=1/2
B(0)=1/4,B(1)=3/4
C(0)=1/8,C(1)=7/8
那么,我們可以計(jì)算出得到如下:
也即,這兩種方式來進(jìn)行編碼,其結(jié)果都使得平均編碼長度增加了。我們也可以看出,按照概率分布B進(jìn)行編碼,要比按照C進(jìn)行編碼,平均每個(gè)符號增加的比特?cái)?shù)目少。從分布上也可以看出,實(shí)際上B要比C更接近實(shí)際分布。
如果實(shí)際分布為C,而我們用A分布來編碼這個(gè)字符發(fā)射器的每個(gè)字符,那么同樣我們可以得到如下:
再次,我們進(jìn)一步驗(yàn)證了這樣的結(jié)論:對一個(gè)信息源編碼,按照其本身的概率分布進(jìn)行編碼,每個(gè)字符的平均比特?cái)?shù)目最少。這就是信息熵的概念,衡量了信息源本身的不確定性。另外,可以看出KL距離不滿足對稱性,即D(P||Q)不一定等于D(Q||P)。
當(dāng)然,我們也可以驗(yàn)證KL距離不滿足三角不等式條件。
上面的三個(gè)概率分布,D(B||C)=1/4log2+3/4log(6/7)。可以得到:D(A||C) - (D(A||B)+ D(B||C)) =1/2log2+1/4log(7/6)>0,這里驗(yàn)證了KL距離不滿足三角不等式條件。所以KL距離,并不是一種距離度量方式,雖然它有這樣的學(xué)名。
其實(shí),KL距離在信息檢索領(lǐng)域,以及統(tǒng)計(jì)自然語言方面有重要的運(yùn)用。
有個(gè)博主的理解
https://blog.csdn.net/qtlyx/article/details/51834684
KL散度又是一個(gè)從信息論、熵的角度考量距離的一個(gè)量。但是,這里說他是距離有點(diǎn)不妥,因?yàn)榫嚯x需要滿足4個(gè)條件:
但是,很遺憾,我們的KL散度至滿足前面兩條,后面介紹的對稱KL也只能滿足前面三條。所以,我們叫KL散度,而不是叫KL距離。
如何直觀的理解這樣的一個(gè)度量的量呢。我不說什么用A的概率去編碼B之類的,直觀的去看KL散度的公式,說白了,P(x)部分可以認(rèn)為是權(quán)重,其值就是P取該值的概率,后面的則是兩者出現(xiàn)該變量的概率之比,然后取對數(shù)。取對數(shù)當(dāng)然就是因?yàn)樾畔㈧乩病R簿褪钦f,如果某一個(gè)變量出現(xiàn)的概率在P中很小,那么權(quán)重很小,即使在Q中很大,使得后半部分值比較大,那么最后值也不會很大;反過來也一樣。所以,希望KL散度大,那么就需要有大的權(quán)重和大的概率差異,也就是,兩個(gè)分布要不一樣。
對稱KL就是KL(P,Q)與KL(Q,P)的值加起來之后取平均。
python代碼
import numpy as np from scipy import * def asymmetricKL(P,Q):return sum(P * log(P / Q)) #calculate the kl divergence between P and Qdef symmetricalKL(P,Q):return (asymmetricKL(P,Q)+asymmetricKL(Q,P))/2.00https://blog.csdn.net/hfut_jf/article/details/71403741?tdsourcetag=s_pcqq_aiomsg
轉(zhuǎn)載自hfut_jf
import numpy as np import scipy.stats# 隨機(jī)生成兩個(gè)離散型分布 x = [np.random.randint(1, 11) for i in range(10)] print(x) print(np.sum(x)) px = x / np.sum(x) print(px) y = [np.random.randint(1, 11) for i in range(10)] print(y) print(np.sum(y)) py = y / np.sum(y) print(py)# 利用scipy API進(jìn)行計(jì)算 # scipy計(jì)算函數(shù)可以處理非歸一化情況,因此這里使用 # scipy.stats.entropy(x, y)或scipy.stats.entropy(px, py)均可 KL = scipy.stats.entropy(x, y) print(KL)# 編程實(shí)現(xiàn) KL = 0.0 for i in range(10):KL += px[i] * np.log(px[i] / py[i])# print(str(px[i]) + ' ' + str(py[i]) + ' ' + str(px[i] * np.log(px[i] / py[i])))print(KL)總結(jié)
以上是生活随笔為你收集整理的计算 KL距离 (相对熵)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抽象工厂模块在开发中的应用
- 下一篇: IOS UITextView自适应高度