上述博文中所解決的核心問題是這樣的:假設我們是一組正在廣袤無垠的太空中進行研究的科學家。我們發現了一些太空蠕蟲,這些太空蠕蟲的牙齒數量各不相同。現在我們需要將這些資訊發回地球。但從太空向地球傳送資訊的成本很高,所以我們需要用盡量少的資料表達這些資訊。我們有個好方法:我們不傳送單個數值,而是繪製一張圖表,其中 X 軸表示所觀察到的不同牙齒數量(0,1,2…),Y 軸是看到的太空蠕蟲具有 x 顆牙齒的機率(即具有 x 顆牙齒的蠕蟲數量/蠕蟲總數量)。這樣,我們就將觀察結果轉換成了分佈。
你可能計算過拋硬幣正面或背面向上的機率,這就是一種二項分佈機率。我們可以將同樣的概念延展到我們的問題上。對於有兩個可能輸出的硬幣,我們假設硬幣正面向上的機率為 p,並且進行了 n 次嘗試,那麼其中成功 k 次的機率為:
公式解讀
這裡說明一下二項分佈中每一項的含義。第一項是 p^k。我們想成功 k 次,其中單次成功的機率為 p;那麼成功 k 次的機率為 p^k。另外要記得我們進行了 n 次嘗試。因此,其中失敗的次數為 n-k,對應失敗的機率為 (1-p)。所以成功 k 次的機率即為聯合機率。到此還未結束。在 n 次嘗試中,k 次成功會有不同的排列方式。在數量為 n 的空間中 k 個元素的不同排列數量為將所有這些項相乘就得到了成功 k 次的二項機率。
二項分佈的均值和方差
我們還可以定義二項分佈的均值和方差,如下:
均值= np
方差= np(1-p)
均值是什麼意思?均值是指你進行 n 次嘗試時的期望(平均)成功次數。如果每次嘗試成功的機率為 p,那麼可以說 n 次嘗試的成功次數為 np。
直觀而言,優先正確匹配近似分佈中真正高可能性的事件是有實際價值的。從數學上講,這能讓你自動忽略落在真實分佈的支集(支集(support)是指分佈使用的 X 軸的全長度)之外的分佈區域。另外,這還能避免計算 log(0) 的情況——如果你試圖計算落在真實分佈的支集之外的任意區域的這個對數項,就可能出現這種情況。
計算 KL 散度
我們計算一下上面兩個近似分佈與真實分佈之間的 KL 散度。首先來看均勻分佈:
再看看二項分佈:
玩一玩 KL 散度
現在,我們來玩一玩 KL 散度。首先我們會先看看當二元分佈的成功機率變化時 KL 散度的變化情況。不幸的是,我們不能使用均勻分佈做同樣的事,因為 n 固定時均勻分佈的機率不會變化。
近日,悉尼大學博士生 Thushan Ganegedara 開始撰寫一個系列部落格文章,旨在為機器學習初學者介紹一些基本概念。本文是該系列的第一篇文章,介紹了 KL 散度(KL divergence)的基本數學概念和初級應用。作者已將相關程式碼釋出在 GitHub 上。
程式碼:https://github.com/thushv89/nlp_examples_thushv_dot_com/blob/master/kl_divergence.ipynb
基礎概念首先讓我們確立一些基本規則。我們將會定義一些我們需要了解的概念。
分佈(distribution)
分佈可能指代不同的東西,比如資料分佈或機率分佈。我們這裡所涉及的是機率分佈。假設你在一張紙上畫了兩根軸(即 X 和 Y),我可以將一個分佈想成是落在這兩根軸之間的一條線。其中 X 表示你有興趣獲取機率的不同值。Y 表示觀察 X 軸上的值時所得到的機率。即 y=p(x)。下圖即是某個分佈的視覺化。
這是一個連續機率分佈。比如,我們可以將 X 軸看作是人的身高,Y 軸是找到對應身高的人的機率。
如果你想得到離散的機率分佈,你可以將這條線分成固定長度的片段並以某種方式將這些片段水平化。然後就能根據這條線的每個片段建立邊緣互相連線的矩形。這就能得到一個離散機率分佈。
事件(event)
對於離散機率分佈而言,事件是指觀察到 X 取某個值(比如 X=1)的情況。我們將事件 X=1 的機率記為 P(X=1)。在連續空間中,你可以將其看作是一個取值範圍(比如 0.95<X<1.05)。注意,事件的定義並不侷限於在 X 軸上取值。但是我們後面只會考慮這種情況。
回到 KL 散度從這裡開始,我將使用來自這篇博文的示例:https://www.countbayesie.com/blog/2017/5/9/kullback-leibler-divergence-explained。這是一篇很好的 KL 散度介紹文章,但我覺得其中某些複雜的解釋可以更詳細的闡述。好了,讓我們繼續吧。
我們想要解決的問題上述博文中所解決的核心問題是這樣的:假設我們是一組正在廣袤無垠的太空中進行研究的科學家。我們發現了一些太空蠕蟲,這些太空蠕蟲的牙齒數量各不相同。現在我們需要將這些資訊發回地球。但從太空向地球傳送資訊的成本很高,所以我們需要用盡量少的資料表達這些資訊。我們有個好方法:我們不傳送單個數值,而是繪製一張圖表,其中 X 軸表示所觀察到的不同牙齒數量(0,1,2…),Y 軸是看到的太空蠕蟲具有 x 顆牙齒的機率(即具有 x 顆牙齒的蠕蟲數量/蠕蟲總數量)。這樣,我們就將觀察結果轉換成了分佈。
傳送分佈比傳送每隻蠕蟲的資訊更高效。但我們還能進一步壓縮資料大小。我們可以用一個已知的分佈來表示這個分佈(比如均勻分佈、二項分佈、正態分佈)。舉個例子,假如我們用均勻分佈來表示真實分佈,我們只需要傳送兩段資料就能恢復真實資料;均勻機率和蠕蟲數量。但我們怎樣才能知道哪種分佈能更好地解釋真實分佈呢?這就是 KL 散度的用武之地。
直觀解釋:KL 散度是一種衡量兩個分佈(比如兩條線)之間的匹配程度的方法。
讓我們對示例進行一點修改為了能夠檢查數值的正確性,讓我們將機率值修改成對人類更友好的值(相比於上述博文中的值)。我們進行如下假設:假設有 100 只蠕蟲,各種牙齒數的蠕蟲的數量統計結果如下。
0 顆牙齒:2(機率:p_0 = 0.02)
1 顆牙齒:3(機率:p_1 = 0.03)
2 顆牙齒:5(機率:p_2 = 0.05)
3 顆牙齒:14(機率:p_3 = 0.14
4 顆牙齒:16(機率:p_4 = 0.16)
5 顆牙齒:15(機率:p_5 = 0.15)
6 顆牙齒:12(機率:p_6 = 0.12)
7 顆牙齒:8(機率:p_7 = 0.08)
8 顆牙齒:10(機率:p_8 = 0.1)
9 顆牙齒:8(機率:p_9 = 0.08)
10 顆牙齒:7(機率:p_10 = 0.07)
快速做一次完整性檢查!確保蠕蟲總數為 100,且機率總和為 1.0.
蠕蟲總數 = 2+3+5+14+16+15+12+8+10+8+7 = 100
機率總和 = 0.02+0.03+0.05+0.14+0.16+0.15+0.12+0.08+0.1+0.08+0.07 = 1.0
視覺化結果為:
嘗試 1:使用均勻分佈建模我們首先使用均勻分佈來建模該分佈。均勻分佈只有一個引數:均勻機率;即給定事件發生的機率。
均勻分佈和我們的真實分佈對比:
嘗試 2:使用二項分佈建模你可能計算過拋硬幣正面或背面向上的機率,這就是一種二項分佈機率。我們可以將同樣的概念延展到我們的問題上。對於有兩個可能輸出的硬幣,我們假設硬幣正面向上的機率為 p,並且進行了 n 次嘗試,那麼其中成功 k 次的機率為:
公式解讀
這裡說明一下二項分佈中每一項的含義。第一項是 p^k。我們想成功 k 次,其中單次成功的機率為 p;那麼成功 k 次的機率為 p^k。另外要記得我們進行了 n 次嘗試。因此,其中失敗的次數為 n-k,對應失敗的機率為 (1-p)。所以成功 k 次的機率即為聯合機率。到此還未結束。在 n 次嘗試中,k 次成功會有不同的排列方式。在數量為 n 的空間中 k 個元素的不同排列數量為將所有這些項相乘就得到了成功 k 次的二項機率。
二項分佈的均值和方差
我們還可以定義二項分佈的均值和方差,如下:
均值= np
方差= np(1-p)
均值是什麼意思?均值是指你進行 n 次嘗試時的期望(平均)成功次數。如果每次嘗試成功的機率為 p,那麼可以說 n 次嘗試的成功次數為 np。
方差又是什麼意思?它表示真實的成功嘗試次數偏離均值的程度。為了理解方差,讓我們假設 n=1,那麼等式就成了「方差= p(1-p)」。那麼當 p=0.5 時(正面和背面向上的機率一樣),方差最大;當 p=1 或 p=0 時(只能得到正面或背面中的一種),方差最小。
回來繼續建模
現在我們已經理解了二項分佈,接下來回到我們之前的問題。首先讓我們計算蠕蟲的牙齒的期望數量:
有了均值,我們可以計算 p 的值:
均值 = np
5.44 = 10p
p = 0.544
注意,這裡的 n 是指在蠕蟲中觀察到的最大牙齒數。你可能會問我們為什麼不把蠕蟲總數(即 100)或總事件數(即 11)設為 n。我們很快就將看到原因。有了這些資料,我們可以按如下方式定義任意牙齒數的機率。
鑑於牙齒數的取值最大為 10,那麼看見 k 顆牙齒的機率是多少(這裡看見一顆牙齒即為一次成功嘗試)?
從拋硬幣的角度看,這就類似於:
假設我拋 10 次硬幣,觀察到 k 次正面向上的機率是多少?
從形式上講,我們可以計算所有不同 k 值的機率。其中 k 是我們希望觀察到的牙齒數量。是第 k 個牙齒數量位置(即 0 顆牙齒、1 顆牙齒……)的二項機率。所以,計算結果如下:
我們的真實分佈和二項分佈的比較如下:
總結已有情況現在回頭看看我們已經完成的工作。首先,我們理解了我們想要解決的問題。我們的問題是將特定型別的太空蠕蟲的牙齒資料統計用盡量小的資料量發回地球。為此,我們想到用某個已知分佈來表示真實的蠕蟲統計資料,這樣我們就可以只發送該分佈的引數,而無需傳送真實統計資料。我們檢查了兩種型別的分佈,得到了以下結果。
均勻分佈——機率為 0.0909
二項分佈——n=10、p=0.544,k 取值在 0 到 10 之間。
讓我們在同一個地方視覺化這三個分佈:
我們如何定量地確定哪個分佈更好?經過這些計算之後,我們需要一種衡量每個近似分佈與真實分佈之間匹配程度的方法。這很重要,這樣當我們傳送資訊時,我們才無需擔憂「我是否選擇對了?」畢竟太空蠕蟲關乎我們每個人的生命。
這就是 KL 散度的用武之地。KL 散度在形式上定義如下:
其中 q(x) 是近似分佈,p(x) 是我們想要用 q(x) 匹配的真實分佈。直觀地說,這衡量的是給定任意分佈偏離真實分佈的程度。如果兩個分佈完全匹配,那麼,否則它的取值應該是在 0 到無窮大(inf)之間。KL 散度越小,真實分佈與近似分佈之間的匹配就越好。
KL 散度的直觀解釋
讓我們看看 KL 散度各個部分的含義。首先看看項。如果 q(x_i) 大於 p(x_i) 會怎樣呢?此時這個項的值為負,因為小於 1 的值的對數為負。另一方面,如果 q(x_i) 總是小於 p(x_i),那麼該項的值為正。如果 p(x_i)=q(x_i) 則該項的值為 0。然後,為了使這個值為期望值,你要用 p(x_i) 來給這個對數項加權。也就是說,p(x_i) 有更高機率的匹配區域比低 p(x_i) 機率的匹配區域更加重要。
直觀而言,優先正確匹配近似分佈中真正高可能性的事件是有實際價值的。從數學上講,這能讓你自動忽略落在真實分佈的支集(支集(support)是指分佈使用的 X 軸的全長度)之外的分佈區域。另外,這還能避免計算 log(0) 的情況——如果你試圖計算落在真實分佈的支集之外的任意區域的這個對數項,就可能出現這種情況。
計算 KL 散度我們計算一下上面兩個近似分佈與真實分佈之間的 KL 散度。首先來看均勻分佈:
再看看二項分佈:
玩一玩 KL 散度現在,我們來玩一玩 KL 散度。首先我們會先看看當二元分佈的成功機率變化時 KL 散度的變化情況。不幸的是,我們不能使用均勻分佈做同樣的事,因為 n 固定時均勻分佈的機率不會變化。
可以看到,當我們遠離我們的選擇(紅點)時,KL 散度會快速增大。實際上,如果你顯示輸出我們的選擇周圍小 Δ 數量的 KL 散度值,你會看到我們選擇的成功機率的 KL 散度最小。
現在讓我們看看和的行為方式。如下圖所示:
看起來有一個區域中的和之間有最小的距離。讓我們繪出兩條線之間的差異(虛線),並且放大我們的機率選擇所在的區域。
結論現在我們有些可靠的結果了。儘管均勻分佈看起來很簡單且資訊不多而二項分佈帶有更有差別的資訊,但實際上均勻分佈與真實分佈之間的匹配程度比二項分佈的匹配程度更高。說老實話,這個結果實際上讓我有點驚訝。因為我之前預計二項分佈能更好地建模這個真實分佈。因此,這個實驗也能告訴我們:不要只相信自己的直覺!