1. 程式人生 > >python: 貝葉斯實現例項

python: 貝葉斯實現例項

資料的重要性毋庸置疑,但是如何讓資料產生價值呢?

對一個全棧老碼農而言,經常在開發或者研發管理的時候遇到各種預測、決策、推斷、分類、檢測、排序等諸多問題。面對“你的程式碼還有 bug 麼?”這樣的挑戰,一種理智的回答是,我們已經執行了若干測試用例,程式碼中存在bug的可能性是百分之零點幾。也就是說,我們對當前程式中沒有bug的信心是百分之九十九點幾。這實際上就是一直貝葉斯思維,或者說使用了貝葉斯方法。不論我們看到,還是沒有看到,它都在那裡,熠熠生輝。

如果預測當前軟體有沒有bug呢?還是要從貝葉斯定理看起。

貝葉斯定理的淺解

對老碼農來說,貝葉斯定理的概率表達相對清晰,理解起來會相對容易。回憶一下我們學過的概率論,聯合概率是滿足交換律的,即:

P(A and B) = P (B and A)

對聯合概率以條件概率展開:

P(AandB) = P(A)P(B|A)

P(BandA) = P(B)P(A|B)

從而得到:

P(A) P(B|A) = P(B) P(A|B)

簡單的變換一下,得到:

大功告成,這就是神奇的貝葉斯定理。其中:

  • P(B) 為先驗概率,即在得到新資料前某一假設的概率;

  • P(B|A) 為後驗概率,即在觀察到新資料後計算該假設的概率;

  • P(A|B)為似然度,即在該假設下得到這一資料的概率;

  • P(A)為標準化常量,即在任何假設下得到這一資料的概率。

還可以加點料,在計算P(A)的時候,可以用加法定理表示:

PA = P(A and B) + P(A and B_) = P

A|BPB+ P(A|B_) P(B_)

從而有:

其中B_ 是與B相反的事件。就測試與bug 之間的估算而言,《貝葉斯推斷的思想》一文給出了貝葉斯推斷的結果,其中就使用了這樣的方法。

貝葉斯方法

貝葉斯方法是一個非常通用的推理框架,用客觀的新資訊更新我們最初關於某個事物的信念後,就會得到一個新的改進了的信念。通過引入先驗的不確定性,允許了初始推斷的錯誤,獲得了更新的證據後,也沒有放棄初始的推斷,而是調整為更符合目前的證據。

但是,P(A|B) 和 P(B|A) 之類的經常讓人混淆,@待字閨中的陳老師給出了理解的一個關鍵點,區分出規律和現象,就是將A看成“規律”,B看成“現象”,那麼貝葉斯公式看成:

陳老師在《這的理解貝葉斯公式嗎》和《又一個生活中的貝葉斯應用》給出了幾個通俗易懂的例子,這裡不再贅述。

迴歸到碼農生活,我們在改善系統功能的時候,通常的一個手段是AB測試。AB測試是用來檢測兩種不同處理方式的差異化程度的一種統計設計模式,例如兩個網站誰會帶來更高的轉化率,這裡的轉化可以是使用者的購買、註冊、或其他的行為。AB測試的關鍵點在於組別之間只能容許一個不同點。實驗後的分析一般都是用假設檢驗完成的,例如均值差異檢驗或者比例差異檢驗,往往涉及Z分數或令人困惑的p值,而用貝葉斯方法則會自然的多。

對A,B兩個網站的轉化概率進行建模。轉化率在0~1之間,可採用Beta分佈。如果先驗是Beta(a1,b1),且 觀測到N次訪問裡有X次轉化,那麼此時的後驗分佈是Beta(a1+X,b1+N-X). 假設先驗是Beta(1,1),等價於【0,1】上的均勻分佈,則示例程式碼如下:

from spicy.stats import beta

a1_prior = 1

b1_prior =1

visitors_A = 12345// 網站A的訪問人數

visitors_B = 1616// 網站B的訪問人數

conversions_from_A = 1200// 網站A的轉化人數

conversions_from_B = 150// 網站B的轉化人數

posterior_A = beta(a1_priorconversions_from_A,b1_prior + visitors_A -conversions_from_A)

posterior_B = Beta(a1_prior+converiosns_from_B,b1_prior + visitors_B-conversions_from_B)

// 對後驗概率進行取樣,用rvs方法生成樣本

samples = 20000

samples_posterior_A = posterior_A.rvs(samples)

samples_posterior_B = posterior_B.rvs(samples)

// 對後驗概率進行比較

print(samples_posterior_A > samples_posterior_B).mean()

使用貝葉斯方法,是從思考資料是如何產生的開始。
1)什麼隨機變數能過描述這些統計資料
2)確實概率分佈的所需引數
3)引數對應早期行為,或後期行為,定義各種變化點
4)定義引數的概率分佈
5)引數概率分佈的變數選擇,直到一個可以假設的均勻分佈

對先驗及後驗概率的選擇,針對應用場景而定。就先驗分佈而言,除了常見的分佈外,還有:
* Gamma分佈,指數隨機變數的推廣
* 威沙特分佈 ,是所有半正定矩陣的分佈,是一個協方差矩陣的適當的先驗。
* Beta分佈,隨機變數定義在0到1之間,使其成為概率和比例的熱門選擇。
* 冪律分佈,滿足公司規模和公司數量之間的關係

在AB測試中使用了Beta分佈, 應用了一個Beta先驗分佈連同二項式生成的觀測資料形成一個Beta後驗分佈這一原理。

當面對多種物件之間的因果關係的時候,貝葉斯方法演變成為了貝葉斯網路。

貝葉斯網路

貝葉斯網路是為了解決不定性和不完整性問題而提出的,在多個領域中獲得了廣泛應用。貝葉斯網路是基於概率推理的圖形化網路,而貝葉斯公式則是這個概率網路的基礎。貝葉斯網路中的每個點代表一個隨機變數,都是具有實際含義、需要人為設計的,點和點之間的邊代表不確定的因果關係,例如 節點E直接影響到節點H,即E→H,則用從E指向H的箭頭建立結點E到結點H的有向弧(E,H),權值(即連線強度)用條件概率P(H|E)來表示。

實際上,如果事物之間的關係能夠用一條鏈串起來,形成了貝葉斯網路的一個特例——馬爾可夫鏈,換個角度看, 貝葉斯網路是馬爾可夫鏈的非線性擴充套件。貝葉斯網路中當某點的一個證據出現後,整個網路中事件的概率都會變化。

簡單地,由於多個變數間存在著可能的依賴性,貝葉斯網路說明了其中的聯合條件概率分佈,允許在變數的子集間定義條件獨立性。使用貝葉斯網路的過程與使用貝葉斯方法的過程是類似的:

  1. 通過多個離散變數建立網路,是一個有向無環圖

  2. 引數的設定或學習,即對DAG進行遍歷,計算各節點的概率表

  3. 網路推理,對因果關係得到置信概率

  4. 推理結果

例如, 社交網路中不真實賬戶的檢測問題。首先確定網路中的隨機變數:

* 賬戶的真實性 A
* 頭像的真實性 H
* 發帖即日誌的密度 L
* 好友的密度 F

使用觀測值示例化H,L,F,把隨機值賦給A,得到

P(A|H,L,F) = P(H|A)P(L|A)P(F|A,H)

然後就可以在社交網路中嘗試使用該推理結果了。在《演算法雜貨鋪——分類演算法之貝葉斯網路》一文中對這一例子給出了相對詳細的說明。

可以說,貝葉斯方法席捲了整個概率論,並將應用延伸到各個問題領域,所有需要作出概率預測的地方都可以見到貝葉斯方法的影子,特別地,貝葉斯方法對機器學習能夠有什麼幫助呢?

貝葉斯與機器學習

機器學習在業界炙手可熱,但我們在機器學習裡同樣會遇到預測、決策、分類、檢測等問題,貝葉斯方法同樣大有用武之地。

機器學習中有大量的模型,如線性模型、非線性模型,可以採用貝葉斯方法來做模型的預測。也就是說,某一場景可能採用的模型是無限多的,可以用概率分佈去描述它。對於假設的先驗,對新來的樣本做預測如計算它的似然,然後用前面推出來的後驗分佈做積分,這個給定模型下樣本的似然,就是所有可能模型的分佈。

機器學習中模型的選擇和比較也是一個常見的問題。例如,在分類問題時,我們使用線性模型還是深度學習的非線性模型呢?貝葉斯方法是這樣考慮的: 用A 表示一個模型類別,可能是線性模型,B 表示另一個模型類別,可能是非線性模型。在同樣的資料集X下,計算在A,B 情況下觀察到訓練集的似然Ma,Mb,然後比較Ma和Mb,這是貝葉斯方法做模型選擇的一個基本規則。

實際上, 貝葉斯定理是資訊處理的一種準則, 輸入是一個先驗分佈和一個似然函式,輸出是一個後驗分佈。對機器學習中的模型本身,也可以通過貝葉斯方法嘗試改進,例如貝葉斯SVM, 高斯過程的貝葉斯等等。

另外,貝葉斯方法對深度學習而言,至少在調參的這一環節還是很有用的。在神經網路中,每一層引數如卷積核的大小和數量等,都不會在深度學習中被模型自動優化的,需要手工指定,這或許就是貝葉斯優化。

感慨一下,碼農不識貝葉斯,雖知資料也枉然呀!