從全機率公式與貝葉斯公式原理討論,引出貝葉斯估計理論及其具體應用

1. 隨機事件及其運算

0x1:隨機試驗

在天然界和人類活動中,發生的現象多種多言,有肯定性現象(例如偶數可以被2整除),也有不肯定的隨機現象(例如新生嬰兒是男孩仍是女孩)。機率論即是一門研究隨機現象的統計規律性的數學學科。html

隨機現象在一次試驗中呈現不肯定的結果,而在大量重複試驗中結果將呈現某種規律性,例如相對比較穩定的全國性別比例,這種規律性稱爲統計規律性git

爲了研究隨機現象的統計規律性,就要對客觀事物進行觀察,觀察的過程叫隨機試驗github

隨機試驗有如下三個特色:web

  • 在相同的條件下試驗能夠重複進行
  • 每次試驗的結果不僅一種,可是試驗以前必須明確試驗的全部可能結果
  • 每次試驗將會出現什麼樣的結果是事先沒法預知的

0x2:樣本空間

隨機試驗的一切可能結果組成的集合稱爲樣本空間,記爲,其中w表示試驗的每個可能的結果,又稱爲樣本點。即樣本空間爲全體樣本點的集合。算法

0x3:隨機事件

當咱們經過隨機試驗來研究隨機現象時,每一次試驗都只能出現中的某一個結果w,各個可能結果w是否在一次試驗中出現是隨機的。安全

在隨機試驗中,經常會關心其中某一些結果是否出現,例如拋一枚色子的結果是不是奇數。這些在一次試驗中可能出現,也可能不出現的一類結果稱爲隨機事件app

筆者認爲,在小數據下,隨機事件是一類呈現出無規律結果的事件,可是在大數據下,隨機事件每每會呈現出明顯的統計規律,這也是大數據時代人工智能發展迅猛的緣由之一。框架

0x4:隨機事件的集合性質

1. 集合論視角下的隨機事件

隨機事件是一個抽象概念,經過引入集合論的理論框架,使得咱們能夠經過集合的方式來考量隨機事件間的關係以及對隨機事件進行運算。函數

例如拋擲一枚均勻的色子,關心擲出的點數是不是偶數,定義,很顯然,它是全體樣本空間的一個子集。學習

因此,從集合的角度來看,樣本空間的部分樣本點組成的集合稱爲隨機事件

2. 用集合論的方式來度量隨機事件之間的關係 

因爲隨機事件是一個集合,所以,事件之間的關係與事件之間的運算應該按照集合論中集合之間的關係與集合之間的運算來規定。
給定一個隨機試驗,Ω是它的樣本空間,事件A,B,C與Ai(i = 1 ,2 , ... )都是Ω的子集。則隨機事件間的關係有如下幾種:

1)包含

若是,那麼,稱事件B包含事件A。它的含義是:事件A發生一定致使事件B發生。

例如,事件A表示「燈泡壽命不超過200h」,事件B表示「燈泡壽命不超過 300h 」。因而

2)相等

若是,即A = B,那麼稱事件A與事件B相等。 

3)互斥

若是A與B沒有相同的樣本點,則稱事件A與事件B互補相容,或稱爲互斥。

3. 隨機事件之間的運算

1)隨機事件的並運算

事件A ∪ B = {ω:ω ∈ A 或 ω ∈ B},稱爲事件A與事件B的和事件(或並事件),它的含義是:當且僅當事件A與事件B中至少有1個發生時,事件A ∪ B發生。

2)隨機事件的交運算

事件A ∩ B = {ω:ω ∈ A 且 ω ∈ B},稱爲事件A與事件B的積事件(或交事件),它的含義是:當且僅當事件A與事件B同時發生時,事件A ∩ B發生,積事件也能夠記做AB。

3)隨機事件的差運算

事件稱爲事件A與事件B的差事件,它的含義是 : 當且僅當事件A發生且事件B不發生時,事件A - B發生。

4)隨機事件的逆運算

事件Ω-A稱爲事件A的對立事件(或逆事件,或餘事件),記做,它的含義是:當且僅當事件A不發生時,事件發生。因而

因爲A也是的對立事件,所以稱事件A與互逆(或互餘)。

4. 隨機事件之間的運算定律

1)交 換 律

A ∪ B = B ∪ A ,A ∩ B = B ∩ A

2)結 合 律

A ∪ (B ∪ C ) = (A ∪ B ) ∪ C ,
A ∩ (B ∩ C ) = (A ∩ B ) ∩ C ;

3)分 配 律

A ∪ (B ∩ C ) = (A ∪ B ) ∩ (A ∪ C ),

A ∩ (B ∪ C ) = (A ∩ B ) ∪ (A ∩ C );

4)對偶律

Relevant Link:

《機率論與數理統計》同濟大學數學系 第一章 - 第一節

 

2. 機率的定義及其性質 

0x1:頻數和頻率的定義

機率是從頻率學派發展而來的,咱們這裏先定義頻數和頻率的概念。

在n次試驗中若是事件A出現了na次,則稱na爲事件A的頻數,稱比值 na / n 爲這n次試驗中事件A出現的頻率。

0x2:機率的統計定義 - 大數定律

隨着試驗次數n的增大,頻率值逐步」穩定「到一個實數,這個實數稱爲事件A發生的機率。

仔細看這個定義能夠發現,機率的統計定義並非一個精確的數學定義,而更傾向於一個實驗概括總結定理(Induction)。這裏存在兩個問題:

  • n須要多大?
  • 怎麼定義穩定?

實際上,就像量子力學中的測不許原理同樣,機率論並非一門研究肯定性的學科。在小數據下,隨機事件呈現的是隨機不肯定的結果,可是在大數據下,隨機事件總體上處於一個特定統計規律的機率場中。關於大數定律的相關討論,讀者朋友能夠參閱另外一篇文章

0x2:機率的公理化定義 - 柯爾莫哥洛夫定律

1933年,柯爾莫哥洛夫(蘇聯)首次提出了機率的公理化定理。

設任一隨機試驗E,Ω爲相應的樣本空間,若對任意事件A,有惟一實數P(A)與之對應,且知足下面條件,則數P(A)稱爲事件A的機率:

  • 非負性:對於任意事件A,總有
  • 規範性
  • 可列可加性:若A1,A2,....,An爲兩兩互不相容的事件,則有,即

Relevant Link:

《機率論與數理統計》同濟大學數學系 第一章 - 第二節

 

3. 等可能模型

在機率論發展的歷史上,最早研究的,也最多見的的一類隨機現象是等可能隨機事件,在這類隨機事件中,樣本空間中的每一個基本事件發生的可能性都相等,這樣的數學模型咱們稱之爲等可能摡型。

等可能摡型又能夠主要分爲兩個主要方面:

  • 古典概型:樣本空間只包含有限個不一樣的可能結果(即樣本點) ,例如拋擲一枚均勻的硬幣。
  • 幾何概型:樣本空間是某個區域,多是一維區間、二維區間、三維區間。

0x1:古典摡型

通常地,稱具備下列2個特徵的隨機試驗的數學模型爲古典概型:

  • 試驗的樣本空間Ω是個離散有限集,不妨記做Ω = {ω1,...,ωn}
  • 每一個基本事件發生的可能性相等,即

在古典概型中,若是事件A中包含 na 個樣本點,則事件A的機率爲

用這種方法肯定的機率被稱爲古典機率。

值得特別注意的是,這裏的 na 指的是樣本點個數,樣本點是機率論中的概念,不能直接等價於頻率中的頻數。咱們經過一批隨機試驗獲得了事件A的統計頻數,只有當隨機試驗的次數n很大時,大數定律才能起做用,這時候隨機試驗A的採樣頻數才能近似等於隨機事件A的樣本數(機率同分布假設),也即咱們才能用隨機試驗的統計結果近似做爲機率統計的結果。

0x2:幾何概型

幾何摡型是古典摡型的推廣,保留每一個樣本點發生的等可能性,但去掉了Ω中包含離散有限個樣本點的限制,即容許試驗可能的結果有連續無窮個。

通常地,幾何概型的基本思路以下:

  • 隨機試驗的樣本空間Ω是某個區域(能夠是一維的、也能夠是二維、三維的)
  • 每一個樣本點等可能地出現

在幾何概型中,咱們規定事件A的機率爲:

其中,在一維情形下表示長度,在二維情形下表示面積,在三維情形下表示體積。

求幾何概型的關鍵在於用圖形正確地描述樣本空間Ω和所求事件A,而後計算出相關圖形的度量。

Relevant Link:

《機率論與數理統計》同濟大學數學系 第一章 - 第三節

  

4. 條件機率與事件的相互獨立性

前三章咱們討論了機率性的基本概念,隨機事件,機率定義基本定義等內容,這章開始咱們來討論機率論中一個很是重要的理論,條件機率以及事件的相互獨立性。

能夠這麼說,正是由於這兩個理論的發展,纔有了後來的貝葉斯理論以及貝葉斯估計方法,以及再後來的樸素貝葉斯方法,甚至馬爾科夫假設的發展也和它們有關係。

0x1:條件機率

在大千世界中,事物是互相聯繫、互相影響的,這對隨機事件也不例外。在同一試驗中,一個事件發生與否對其餘事件發生的可能性的大小到底是如何影響的?這即是條件機率理論要闡述和定義的內容。

筆者認爲,條件機率是整個機率論體系基礎中的基礎,全部的隨機事件間關係都可在條件機率的理論體系下解釋,包括獨立同分布事件,本質上也是條件機率的一個特例,即零依賴條件。

1. 條件機率基本定義

設E是隨機試驗,Ω是樣本空間,A,B是隨機試驗E上的兩個隨機事件且P(B)>0,稱

爲在事件B發生的條件下,事件A發生的機率,稱爲條件機率。

能夠驗證,條件機率也知足機率的公理化定義的三條基本性質:

  • 非負性公理:對於任意一個事件A,P(A | B) ≥ 0
  • 規範性公理:P (Ω | B) = 1
  • 可列可加性公理:當可列無限個事件A1,A2,... 兩兩互不相容時,則有

2. 條件機率的延伸定理

若是對條件機率定義式兩端同乘P(A),可得以下定理:

機率的乘法公式:

設A,B爲隨機試驗E上兩個事件,且P(A)<0,則有

0x2:事件的相互獨立性

在一個隨機試驗中,A,B是兩個事件。若是它們之間是否發生是相互不影響的,這表現爲 P(B | A) = P (B) 或 P(A | B) = P(A) 成立。

由條件機率延伸定理可得,這時,P(AB) = P(A)P(B)。

這說明無論事件A發生仍是不發生,都對事件B的發生的機率沒有影響。咱們能夠說事件A和事件B沒有」關係「,或者稱事件A與事件B相互獨立。

1. 事件相互獨立性的定義

設A,B爲試驗E的兩個事件,若是知足等式,則稱事件A,B相互獨立,簡稱A,B獨立。

同時,若事件A與事件B相互獨立,則下列4個命題是等價的:

  • 事件 A 與 B 相互獨立 ;
  • 事件 A 與 相互獨立 ;
  • 事件 與 B 相互獨立; 
  • 事件相互獨立;

2. 三個事件下事件獨立性的定義 - 三元及多元關係

咱們將相互獨立性推廣到三個事件的狀況,三個事件以上和三個本質上是相同的。

1)兩兩相互獨立性質

設A,B,C是試驗E的三個事件,若是知足等式:

  • P (A B) = P (A)P (B)
  • P (B C) = P (B)P (C)
  • P (C A) = P (C)P (A) 

則稱事件A,B,C兩兩相互獨立。

2)相互獨立

設A,B,C是試驗E的三個事件,若是知足等式:

  • P (A B) = P (A)P (B)
  • P (B C) = P (B)P (C)
  • P (C A) = P (C)P (A) 
  • P (A B C) = P (A)P (B)P (C) 

則稱事件A,B,C相互獨立。

能夠看到,在三元關係中,相互獨立定義的要求比兩兩相互獨立更加嚴格,知足兩兩相互獨立的事件集合,未必必定就知足相互獨立的定義。

3. 事件獨立性的一個例子

舉一個例子說明兩兩互相獨立和相互獨立的區別。

把一枚硬幣相互獨立的投擲2次,事件 Ai 表示」投擲第 i 次時出現正面「,i=1,2。事件 A3 表示」正、反面各出現一次「,因此有:

P(A1) = P(A2) = P(A3) = 1/2,P(A1 A2) = P(A1 A3) = P(A2 A3) = 1/4,因此 A1,A2,A3兩兩互相獨立。

可是P(A1 A2 A3) = 0,因此 A1,A2,A3 不相互獨立。

Relevant Link:

《機率論與數理統計》同濟大學數學系 第一章 - 第四節

 

5. 全機率公式與貝葉斯公式

0x1:關於貝葉斯公式的一些歷史

貝葉斯公式是機率論中最重要的知識點之一,該公式的意義在於開創了統計學的一個學派 - 貝葉斯學派,它和經典統計學派並列爲現代統計學的兩大分支。

貝葉斯公式是由英國學者貝葉斯(Thomas Bayes,1701-1761)爲了解決二項分佈的機率估計問題所提出的一種」逆機率「思想發展而來的。

」求機率這個問題的逆機率「和」求某問題的機率「是兩個互爲相反的過程:

  • 」求某問題的機率「:已知事件的機率爲p,可計算某種結果出現的機率問題,即緣由推結果;
  • 」求機率這個問題的逆機率「:給定了觀察結果,則可對機率p做出試驗後的推斷,即結果推緣由;

貝葉斯的思想,之後後續學者對其思想的發展和理論的應用,最終發展成了貝葉斯統計理論,從而開闢了統計學發展中的一個新領域,對統計決策函數、統計推斷、統計的估算等做出了巨大貢獻。

貝葉斯學派與經典統計學派的差異在因而否使用先驗信息,先驗信息是指人們對一個事物的歷史認知或主觀判斷。咱們知道,任何事物都是發展變化的,都會經過樣本數據信息不斷挖掘和發現新變化。經典統計學只使用樣本數據信息,而貝葉斯分析則是把先驗信息與樣本數據結合起來進行推斷。 

0x2:全機率公式與貝葉斯公式定義

全機率公式是機率論中一個很是重要的公式,一般咱們會遇到一些較爲複雜的隨機事件的機率計算問題,這時,若是將它分解成一些較爲容易計算的狀況分別進行考慮,能夠化繁爲簡。

1. 完備事件組

設E是隨機試驗,Ω是相應的樣本空間,A1,A2,....,An爲Ω的一個事件組,若知足條件:

  • A1,...,An 兩兩互不相容 
  • A1 ∪...∪ An = Ω

則稱事件組A1,A2,....,An爲樣本空間Ω的一個完備事件組,完備事件組完成了對樣本空間的一個分割。

2. 全機率公式

設A1,A2,....,An爲樣本空間Ω的一個完備事件組,且P(Ai) > 0(i=1,2,....,n),B爲任一事件,則:

下面給出證實上述公式的一個幾何表示:

因爲,且是兩兩互不相容的事件(即B與A1,A2,....,An中的任1個事件有且只有1個事件同時發生),所以

筆者認爲,全機率公式能夠這麼理解:全機率公式表達了一個思想,致使某個結果B的緣由A能夠分解爲若干子狀況,全部子狀況累加起來共同致使告終果B,這是從緣由推結果的機率計算問題

3. 貝葉斯公式

設A1,A2,....,An爲樣本空間Ω的一個完備事件組,且P(Ai) > 0(i=1,2,....,n),B爲任一事件,當P(B) > 0時,有:

,i = 1,2,...,n

上面公式看着複雜,其實並不複雜,咱們將其和全機率公式進行對比。會發現如下幾點:

  • 貝葉斯公式的分子和全機率公式的分解子項是相同的
  • 貝葉斯公式的分母等於全機率公式的累加和

筆者認爲,貝葉斯公式能夠這麼理解:貝葉斯公式表達了一個思想,根據某個出現的結果B能夠反推全部可能致使該結果的子緣由Ai,而具體根據結果B逆推出每一個子緣由的條件機率比重,則取決於這個子緣由和結果B的聯合機率 ,這是從結果推緣由的逆機率計算問題

4. 同一個硬幣的正反兩面 - 貝葉斯和全機率公式

從數學公式上來說,貝葉斯公式是全機率公式的逆運算,全機率公式和貝葉斯公式實際上表明瞭同一個事物的正反兩面,有因就有果,有果就有因。

從映射的角度來看,貝葉斯和全機率公式能夠理解爲一個將」緣由「映射爲」結果「的映射函數,也能夠反過來解,將」結果「映射爲」緣由「。

同時,這個因果的互相推導關係(映射)又不是固定不變的,它是隨着隨機試驗的不斷重複,不斷調整」緣由-結果的映射比重「,這個所謂的比重就是先驗機率,經過調整先驗機率,因果之間的映射關係也隨之改變,當達到大數統計的時候,這個映射關係會收斂到一個均值區間附近。

接下來最重要也最美妙的幾個問題來了,那這個收斂均值區間和咱們先驗是什麼關係呢?咱們處於大數據的數據驅動時代,是應該相信數據仍是相信先驗經驗呢?筆者這裏就本身在平常中的一些工做實踐和思考給出個人一些觀點:

  • 收斂區間和咱們的先驗並無明確的關係,它們表明了對事物的不一樣認知視角。
  • 是該相信先驗仍是相信數據,這個問題貝葉斯學派已經給出了明確的回答,即」綜合起來綜合判斷呀!不偏執一端,而是讓先天先驗和後天數據共同決定結果「。筆者這裏給出另外一個視角的回答,具體偏重哪一端,取決於你的數據體量,數據體量越多,越能夠依賴數據驅動,相反,若是數據體量越小,先驗的比重就要適當提升。
  • 當數據量較小時,採樣數據對真值機率分佈的表明性相對較差,這時候應該加大先驗機率的比重,避免估計出現誤差;當數據量較大時(海量大數據),這時候採樣數據近似(甚至無限逼近)真值機率分佈,這時候能夠採起最大熵原理(均等先驗分佈)來設置先驗,經過數據驅動的方式來進行機率估計。

0x3:先驗機率對貝葉斯後驗估計結果的影響

這個小節,咱們用一個例子來討論下,先驗機率對最終貝葉斯後驗估計結果的影響,先驗使得咱們不單隻看單次試驗的結果,而同時還要結合對應事件是否發生的先驗機率。

以醫院檢查某種疾病爲例,某種疾病在全部人羣中的感染率是0.1%(即在歷史經驗中這種病是一個很是罕見的病),醫院現有的技術對於該疾病檢測準確率爲 99%(已知患病狀況下, 99% 的可能性能夠檢查出陽性(患病);已知不患病下 99% 的可能性檢查爲陰性(正常)) 

設隨機事件A爲是否患病,隨機事件B爲是否被檢測爲陽性,則有:

  • [公式],被檢測者患病的機率
  • [公式],被檢測未者患病的機率
  • [公式],已知患病的狀況下檢測爲陽性的機率,即確診
  • [公式],已知未患病的狀況下檢測爲陽性的機率,即誤診

經過貝葉斯公式,咱們可得」某我的被醫院檢測爲陽性,同時又實際又真的患病(即真陽性)「的條件機率:

同理可得假陽性的條件機率爲0.91。

能夠看到,即便被醫院檢測爲陽性,實際患病的機率其實還不到10%,有很大多是假陽性,須要確診最終的結果,每每須要複檢來肯定是否真的患病。

讓咱們再來計算初檢和複檢結果都爲陽性時(2次隨機試驗),患病的可能性。

假設兩次檢查的準確率相同,都是99%,這裏令 B 爲第一次檢測結果爲陽性,C 爲第二次檢測結果爲陽性,A 爲被檢測者患病,則有:

  • [公式],被檢測者患病的機率
  • [公式],被檢測者未患病的機率
  • [公式],已知患病狀況下連續兩次檢測結果爲陽性的機率,即兩次都確診
  • [公式],已知未患病狀況下連續兩次檢測結果爲陽性的機率,即兩次都誤診

計算」兩次醫院檢測都是真陽性的機率「貝葉斯公式有:

可見覆檢結果大大提升了檢測的可信度,可見覆檢的意義在於大幅減小假陽性的可能(0.91 -> 0.1),從而大大提升陽性檢測的準確性。

這也必定程度上印證了上個小節的一個觀點,當數據量足夠大的時候,先驗的做用會逐漸減弱,數據驅動的做用會佔上峯,可是若是是小數據,先驗對最終結果的影響就比較明顯了。

生活中,若是體檢中遇到了某種罕見病,不要慌張,趕忙再從新體檢一次。

0x4:屢次重複試驗對貝葉斯統計推斷結果的影響的例子

在這個小節中,筆者但願經過一個具體的案例,向讀者朋友展現貝葉斯統計推斷的兩個核心特色,即:

  • 合理利用先驗信息(take advance of prior knowledge)
  • 經過不斷試驗,不斷動態更新先驗,也即數據驅動的先驗得到(data driven prior knowledge)

1. 題目說明

一袋中共裝有10個球,分貝爲紅球和白球,可是每種顏色的球有幾個不是很明確,若是按照完備事件組的定義,總有有11種可能(這是一個古典摡型),可是爲了簡化討論,咱們假設完備集由下列三種可能組成:

  • A1:6個紅球,4個白球
  • A2:7個紅球,3個白球
  • A3:5個紅球,5個白球

在沒有任何前置知識的狀況下,咱們先設定一個先驗,開始認爲這三種可能的機率分別爲:

  • P(A1) = 1/6
  • P(A2) = 1/3
  • P(A3) = 1/2

試驗的過程是每次從袋中有放回的拿一個球,接下來咱們來簡要闡述下貝葉斯統計的過程。

2. 第一輪貝葉斯估計

第一輪的試驗結果是,咱們取出的球是紅色的。

咱們設」任取出一個球是紅色「這個隨機事件爲B。試驗的先驗信息,P(A1) = 1/6,P(A2) = 1/3,P(A3) = 1/2。

根據全機率公式有:

又根據貝葉斯公式獲得各個先驗的後驗機率估計:

因此,通過一次樣本抽取試驗後(引入了條件信息),結合歷史先驗信息,咱們獲得了關於A1,A2,A3的後驗機率。

2. 第二次,即以後的n次迭代試驗

在貝葉斯估計理論體系中,先驗來自於歷史,即包括先天的認知,也包括經過經驗總結獲得的歷史經驗認知(康德的理性與經驗主義)。咱們在第一次試驗中因爲沒有任何歷史試驗經驗可總結,因此只能依據先天的認知假定了一個先驗。可是通過了一次歷史試驗後,咱們已經有了一個後驗機率估計,這時,咱們就能夠將這個後驗機率估計用做下一次試驗的先驗估計,即:

  • P(A1) = 6/35
  • P(A2) = 2/5
  • P(A3) = 3/7

能夠看到,相比於第一次的試驗,A1和A2的先驗都有微弱的提升,而A3的先驗則微弱降低了。這是由於第一次的實驗結果更傾向於強化A1和A2的發生可能,而弱化A3的發生可能。

能夠想象,隨着不斷地試驗,貝葉斯估計對事物的認識會不斷加深和調整,對錯誤的先驗會修正,對正確的先驗會強化,最後收斂到真實附近。

Relevant Link:

《機率論與數理統計》同濟大學數學系 第一章 - 第五節
https://zhuanlan.zhihu.com/p/22467549 

 

6. 樸素貝葉斯法原理

在完成了對條件機率機率、全機率公式、貝葉斯公式的討論以後,咱們接下來繼續討論一個基於理論的具體應用,本質上說,樸素貝葉斯法和貝葉斯理論之間的關係就至關於樹枝和樹根的關係,樸素貝葉斯法的理論依據來自於貝葉斯理論。

0x1:從貝葉斯最優分類器提及,貝葉斯最優分類器存在哪些問題

一言以蔽之,貝葉斯最優分類器是一種基於貝葉斯理論(全機率公式和貝葉斯公式)的生成式模型

在貝葉斯最優分類理論中,對於給定的特徵向量,咱們的目的是預測樣本的標籤

貝葉斯最優分類器的函數形式是:

接下來問題來了,根據全機率公式的分解,爲了描述機率函數,咱們須要個參數,這意味着,咱們所需的樣本數量隨特徵個數呈現指數型增加(事件分解的越細,所需估計的參數數量就越多),很顯然,這直接致使了維度爆炸問題。

0x2:獨立同分布假設下的貝葉斯最優分類器

獨立同分布假設,是學者們提出的爲了解決貝葉斯最優分類器運算量過大的一種方法。

咱們知道,在PAC可學習理論中,經過限制假設類能夠緩解欠擬合問題,同時減少逼近偏差,雖然可能會引入估計偏差增大的問題。

在樸素貝葉斯方法中,咱們增長的一個假設是:對於給定的標籤(目標值),各特徵之間是彼此獨立的。

有了這個假設,就能夠由以下全機率公式:

也就是說,對於樸素貝葉斯生成式推測來講,須要估計的參數個數只有 2d+1 個。這個獨立假設顯著減小了須要學習的參數數量。

注意,這裏用的是」假設「這個詞,也就是說這個假設並不必定是合理的(例如一段文本中不一樣單詞之間是存在語法依賴關係的),只是咱們爲了簡化運算而添加上的一個約束條件。

獨立同分布假設其實也並非什麼新的概念,文章前面提到的事件之間兩兩相互獨立於事件之間互相獨立的概念,就是這裏所謂的獨立同分布假設。

綜上,樸素貝葉斯(naive Bayes)法是基於貝葉斯定理與特徵條件獨立假設的分類方法

0x3:樸素貝葉斯法算法流程

1. 模型訓練 - 基於全機率公式計算(X,Y)的聯合機率分佈

設輸入空間爲 n 維向量的集合,輸出空間爲類標記集合 Y = {C1,C2,...,Ck},輸入特徵向量,輸出類標記是X和Y的聯合機率分佈,訓練數據集獨立同分布產生。

樸素貝葉斯法的訓練目標是,經過數據集學習聯合機率分佈

但遺憾的是,聯合機率不能直接產生(事實上它是未知的),咱們能夠經過全機率公式計算獲得聯合機率。

先驗機率分佈

條件機率分佈

先驗機率和條件機率累乘獲得聯合機率。

2. 模型預測 - 預測貝葉斯後驗估計機率值最大對應的類(label)

樸素貝葉斯預測的目的是」由果推因「,即根據n維輸入向量x,反推全部可能的目標類機率值,並從中選擇機率值最大的類做爲最終預測值。

目標類機率值的計算公式以下:

樸素貝葉斯從全部目標類中選出後驗機率最大的那一個類做爲預測結果,最大後驗機率估計的公式以下:

注意!上式中分母對全部分類Ck都是相同的,所以實際計算中,分母可約掉,最終最大後驗機率估計公式以下:

0x4:樸素貝葉斯估計合理性背後的數學原理 

樸素貝葉斯法預測時將實例分到後驗機率最大的類中,這等價於指望風險最小化。

假設選擇0-1損失函數做爲損失的評估函數:

這時,指望風險是:。該式中指望是對聯合分佈P(X,Y)取得,而聯合機率分佈咱們是未知的,所以取等價的後驗機率條件指望:

爲了使指望風險最小化,只需對X = x逐個極小化,由此獲得

等式推導的最後一步就是最後後驗機率的意思,由此,根據指望風險最小化準則就推導出了等價的後驗機率最大化準則:,這就是樸素貝葉斯法所採用的數學原理

Relevant Link:

https://www.google.com.hk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwj8m-mjmrvVAhUBzIMKHWiqCIoQFgglMAA&url=https%3a%2f%2fzh%2ewikipedia%2eorg%2fzh-cn%2f%25E6%259C%25B4%25E7%25B4%25A0%25E8%25B4%259D%25E5%258F%25B6%25E6%2596%25AF%25E5%2588%2586%25E7%25B1%25BB%25E5%2599%25A8&usg=AFQjCNGICcTloX_Ty9_xQ06UnWbSWHkcWw

0x5:樸素貝葉斯估計的一個例子 

咱們先計算先驗機率:P(Y = 1) = 9 / 15;P(Y = -1) = 6 / 15

而後計算輸入變量各個特徵的條件機率:

= 2 / 9; = 3 / 9; = 4 / 9

= 1 / 9; = 4 / 9; = 4 / 9

= 3 / 6; = 2 / 6; = 1 / 6

= 3 / 6; = 2 / 6; = 1 / 6

根據最大後驗機率公式,對於給定的,計算其最大後驗機率:

= 9 / 15 * 3 / 9 * 1 / 9 = 1 / 45

= 6 / 15 * 2 / 6 * 3 / 6 = 1 / 15

樸素貝葉斯法取後驗機率最大的對應的類,因此 y = -1

0x6:平滑化的樸素貝葉斯估計

這個小節咱們來討論一種樸素貝葉斯估計的變種,平滑化的樸素貝葉斯估計。

1. 傳統的樸素貝葉斯估計可能遇到的問題

原始的樸素貝葉斯估計是一種單純從訓練樣本推導機率分佈的算法,可是在實際工程實踐中,可能遇到一個問題:在根據全機率公式計算分子中的條件機率時,可能由於數據分佈不均勻致使結果出現零值等極端狀況

爲何會有這個問題呢?咱們前面不是說先驗分佈是根據人的先天經驗來設定的嗎?這裏怎麼又說不許確不均勻呢?

實際上,在工程項目中,除了一些特定場景,大部分時候咱們不可能直接人工指定一個先驗分佈,而是須要根據訓練樣本集來獲得先驗分佈以及先驗條件機率的。

爲了說明這個問題,咱們再來回顧一下樸素貝葉斯估計的公式:

公式中的分子是一個累乘式,試想若是有一個條件機率P(Xi | Yck) = 0,那整個分子的累乘結果就會等於0,分子爲零,直接致使最終的貝葉斯後驗機率估計也爲零。

那接下來問題來了,這個等於意味着什麼?合理嗎?筆者的觀點是,在海量均勻大數據下,可能合理,可是若是數據量不夠或者分佈不夠均勻,這不合理,至關於便可老鼠屎壞了一鍋湯,個別條件機率的0值,致使了總體的機率空洞,這顯然是不合理的。

例如在文本分類任務中,咱們會對文本進行ngram分詞並獲得一個詞表。以後在面對具體輸入文本的時候,會逐一統計詞表中的詞在輸入文本中的出現頻率,那這個時候,就很容易出現某些特徵在樣本中出現次數爲0的狀況,這樣就會致使這些詞的條件機率爲0,解決的方法也是進行平滑化,關於ngram平滑這個問題的討論,筆者在另外一篇文章裏有所涉及。

2. 經過加入拉普拉斯平滑因子,強行改變先驗分佈

解決傳統貝葉斯估計遇到0機率空洞問題的方法之一是加入平滑化因子,修改後的先驗條件機率公式:

,式中λ>=0,等價於在隨機變量各個取值的頻數上賦予一個正數λ。

  • 當λ=0時公式退化到傳統樸素貝葉斯估計
  • 一般取λ=1,這時被稱爲拉普拉斯平滑(Laplace smoothing)
  • 也能夠取其餘λ值,得到不一樣的效果

上面的公式,若是咱們對其進行對數化後能夠看到,公式可分爲兩部分。

  • 第一項是標準的對數似然函數
  • 第二項是先驗分佈的對數

這代表對參數的估計再也不僅僅考慮樣本的統計結果,還要考慮進先驗分佈,它如同一個懲罰項。也能夠理解爲經過平滑化因子,強行改變了經過統計方法獲得的先驗分佈。

筆者這裏多說一句,從原理上說,若是在具體應用中,算法開發者本身很是瞭解業務,例如筆者本身對安全攻防業務相對比較瞭解,是能夠直接經過專家經驗的方式,指定一個先驗分佈的,這麼作的效果,有時候要比平滑化要好,缺點也很明顯,比較費力,且對不一樣數據的適應性會降低。

Relevant Link: 

http://blog.csdn.net/juanjuan1314/article/details/78189527?locationNum=4&fps=1
http://www.cnblogs.com/liliu/archive/2010/11/24/1886110.html

 

7. 樸素貝葉斯法的具體應用 - Spam fileter(垃圾分類demo)

0x1: 分類原理

咱們知道,咱們若是假設用於預測的全部詞(例如15個詞)互相之間都是有相關依存關係的,則樸素貝葉斯法的公式以下

可是了簡便實現,咱們能夠假設全部詞之間是互相獨立的,則計算過程會大大簡化

下面咱們簡述原理與預測過程

1. 計算全部詞的 P(wordN | S)、以及 P(wordN | H) 

1. 輸入全部郵件,而後獲得郵件中每一個單詞出如今垃圾郵件中的次數(條件機率 P(wordN | S) ),出如今正常郵件中的次數( P(wordN | H) )
2. 設置默認機率,即若是在預測時遇到訓練語料庫中未見過的詞,則賦值默認機率例如: 3.7e-4
3. 先驗機率,設置Spam爲0.2,Ham爲0.8,即根據經驗,100封郵件裏有20封是垃圾郵件

有了這些參數,模型就訓練出來了。樸素貝葉斯分類器的訓練就是在計算條件機率

2. 預測新郵件,獲取全部關鍵字

而後輸入一封待處理郵件,找到裏面全部出現的關鍵詞

3. 計算獨立聯合條件機率

求出,A爲一封郵件是垃圾郵件的事件,T爲關鍵詞出如今一封郵件中的事件。

是多個關鍵詞。A和T是關聯的事件。每一個關鍵詞根據樸素貝葉斯的假設,是相互獨立的。

這些關鍵詞同時出現的狀況下A是垃圾郵件的機率。

表明了從待預測email中切出的詞,A表明Spam或者Ham,上面公式要分別計算A = S和A = H時的獨立聯合條件機率。

這個計算在工程上也十分簡單,就是把每一個詞在語料庫中出現的次數比例,累乘起來。分母可忽略不用計算,由於不影響分子的大小對比。

0x2: 利用樸素貝葉斯進行垃圾郵件分類 - 以單個詞爲依據

咱們用一個例子來講明樸素貝葉斯是怎麼應用在垃圾郵件分類中的

貝葉斯過濾器是一種統計學過濾器,創建在已有的統計結果之上。因此,咱們必須預先提供兩組已經識別好的郵件,一組是正常郵件(ham),另外一組是垃圾郵件(spam)
咱們用這兩組郵件,對過濾器進行"訓練"。這兩組郵件的規模越大,訓練效果就越好。這裏咱們假設正常郵件和垃圾郵件各4000封

1. 訓練

"訓練"過程很簡單。首先,解析全部郵件,提取每個詞(word)。而後,計算每一個詞語在正常郵件和垃圾郵件中的出現頻率。好比,咱們假定"sex"這個詞,在4000封垃圾郵件中,有200封包含這個詞,那麼它的spam出現頻率就是5%;而在4000封正常郵件中,只有2封包含這個詞,那麼ham出現頻率就是0.05%。(若是某個詞只出如今垃圾郵件中,就假定它在正常郵件的出現頻率是1%,反之亦然。這樣作是爲了不機率爲0。隨着郵件數量的增長,計算結果會自動調整。)
有了這個初步的統計結果,過濾器就能夠投入使用了

2. 機率計算

如今,咱們收到了一封新郵件。在未經統計分析以前,咱們假定它是垃圾郵件的機率爲50%。(有研究代表,用戶收到的電子郵件中,80%是垃圾郵件。可是,這裏仍然假定垃圾郵件的"先驗機率"爲50%。)
咱們用S表示垃圾郵件(spam),H表示正常郵件(healthy)。所以,P(S)和P(H)的先驗機率,都是50%

而後,對這封郵件進行解析,發現其中包含了sex這個詞,請問這封郵件屬於垃圾郵件的機率有多高?
咱們用W表示"sex"這個詞,那麼問題就變成了如何計算P(S|W)的值,即在某個詞語(W)已經存在的條件下,垃圾郵件(S)的機率有多大。
根據條件機率公式,立刻能夠寫出

公式中,P(W|S)和P(W|H)的含義是,這個詞語在垃圾郵件和正常郵件中,分別出現的機率。這兩個值能夠從歷史資料庫中獲得,對sex這個詞來講,上文假定它們分別等於5%和0.05%。另外,P(S)和P(H)的值,前面說過都等於50%。因此,立刻能夠計算P(S|W)的值:

所以,這封新郵件是垃圾郵件的機率等於99%。這說明,sex這個詞的推斷能力很強,將50%的"先驗機率"一會兒提升到了99%的"後驗機率"

0x3: 利用樸素貝葉斯進行垃圾郵件分類 - 以多個詞爲依據

在上面的例子中,基於一個詞就推斷一個email是不是垃圾郵件未免太過武斷,在實際使用中很容易出現誤報。由於在一封郵件裏每每會包含不少詞,爲了能下降誤報。更實際的作法是選出這封信中P(S|W)最高的15個詞(對推斷共享最高的15個詞),計算它們的聯合條件機率。若是有的詞是第一次出現則初始化爲0.4,由於垃圾郵件使用的每每是固定的語句,若是出現了訓練庫中從未出現的詞,則有很大機率是正常的詞

而所謂聯合機率,就是指在多個事件發生的狀況下,另外一個事件發生機率有多大。好比,已知W1和W2是兩個不一樣的詞語,它們都出如今某封電子郵件之中,那麼這封郵件是垃圾郵件的機率,就是聯合機率。

在已知W1和W2的狀況下,無非就是兩種結果:垃圾郵件(事件E1)或正常郵件(事件E2)

其中,W一、W2和垃圾郵件的機率分別以下:

若是假定全部事件都是獨立事件(這是一個強假設,可能會致使預測的準確性降低),那麼就能夠計算P(E1)和P(E2):

因爲在W1和W2已經發生的狀況下,垃圾郵件的機率等於下面的式子:

將上式帶入即

將先驗機率P(S)等於0.5代入,獲得

將P(S|W1)記爲P1,P(S|W2)記爲P2,公式就變成

這就是聯合機率的計算公式,將狀況從二詞擴展到15詞,最終公式爲

0x4: 代碼示例

# -*- coding: utf-8 -*-

# for tokenize
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import wordpunct_tokenize

# for reading all the files
from os import listdir
from os.path import isfile, join

# add path to NLTK file
nltk.data.path = ['nltk_data']
# load stopwords
stopwords = set(stopwords.words('english'))

# path for all the training data sets
# 用於訓練模型的語料集
spam_path = 'data/spam/'
easy_ham_path = 'data/easy_ham/'

# change it to the type of mails you want to classify
# path to the hard ham mails
# 用於預測檢驗效果4個語料庫
spam2_path = 'data/spam_2/'
easy_ham2_path = 'data/easy_ham_2/'
hard_ham2_path = 'data/hard_ham_2/'
hard_ham_path = 'data/hard_ham/'

# 分別測試模型在4種不一樣類型的數據集中的分類效果
test_paths = [spam2_path, easy_ham2_path, hard_ham_path, hard_ham2_path]



def get_words(message):
    """
    Extracts all the words from the given mail and returns it as a set.
    """

    # thanks http://slendermeans.org/ml4h-ch3.html

    # remove '=' symbols before tokenizing, since these
    # sometimes occur within words to indicate, e.g., line-wrapping
    # also remove newlines
    all_words = set(wordpunct_tokenize(message.replace('=\\n', '').lower()))

    # remove the stopwords
    msg_words = [word for word in all_words if word not in stopwords and len(word) > 2]

    return msg_words


def get_mail_from_file(file_name):
    """
    Returns the entire mail as a string from the given file.
    """

    message = ''

    with open(file_name, 'r') as mail_file:

        for line in mail_file:
            # the contents of the actual mail start after the first newline
            # so find it, and then extract the words
            if line == '\n':
                # make a string out of the remaining lines
                for line in mail_file:
                    message += line

    return message


def make_training_set(path):
    """
    Returns a dictionary of <term>: <occurrence> of all
    the terms in files contained in the directory specified by path.
    path is mainly directories to the training data for spam and ham folders.
    occurrence is the percentage of documents that have the 'term' in it.
    frequency is the total number of times the 'term' appears across all the
    documents in the path
    """

    # initializations
    training_set = {}

    mails_in_dir = [mail_file for mail_file in listdir(path) if isfile(join(path, mail_file))]

    # count of cmds in the directory
    cmds_count = 0
    # total number of files in the directory
    total_file_count = len(mails_in_dir)

    for mail_name in mails_in_dir:

        if mail_name == 'cmds':
            cmds_count += 1
            continue

        # get the message in the mail
        message = get_mail_from_file(path + mail_name)

        # we have the message now
        # get the words in the message
        terms = get_words(message)

        # what we're doing is tabulating the number of files
        # that have the word in them
        # add these entries to the training set
        for term in terms:
            if term in training_set:
                training_set[term] = training_set[term] + 1
            else:
                training_set[term] = 1

    # reducing the count of cmds files from file count
    total_file_count -= cmds_count
    # calculating the occurrence for each term
    for term in training_set.keys():
        training_set[term] = float(training_set[term]) / total_file_count

    return training_set




# c is an experimentally obtained value
# 貝葉斯估計P(S) = P(H) = 0.5
# 當一個新詞出現時,咱們假定爲3.7e-4
def classify(message, training_set, prior=0.5, c=3.7e-4):
    """
    Returns the probability that the given message is of the given type of
    the training set.
    """
    # 獲取word token list
    msg_terms = get_words(message)

    msg_probability = 1

    for term in msg_terms:
        if term in training_set:
            msg_probability *= training_set[term]
        else:
            msg_probability *= c

    return msg_probability * prior


spam_training_set, ham_training_set = {}, {}
def trainingProess():
    global spam_training_set, ham_training_set
    print 'Loading training sets...',
    spam_training_set = make_training_set(spam_path)
    ham_training_set = make_training_set(easy_ham_path)
    print 'done.'



def testProcess():
    global spam_training_set, ham_training_set
    SPAM = 'spam'
    HAM = 'ham'
    for mail_path in test_paths:
        mails_in_dir = [mail_file for mail_file in listdir(mail_path) if isfile(join(mail_path, mail_file))]

        results = {}
        results[SPAM] = 0
        results[HAM] = 0

        print 'Running classifier on files in', mail_path[5:-1], '...'

        for mail_name in mails_in_dir:
            if mail_name == 'cmds':
                continue
            # 獲取email的全文
            mail_msg = get_mail_from_file(mail_path + mail_name)

            # 0.2 and 0.8 because the ratio of samples for spam and ham were the same
            # 貝葉斯估計P(S) = 0.2;P(H) = 0.8
            # 當一個新詞出現時,咱們假定爲3.7e-4
            spam_probability = classify(mail_msg, spam_training_set, 0.2)
            ham_probability = classify(mail_msg, ham_training_set, 0.8)
            # 計算獲得獨立聯合條件機率:
            # P(T1|S) * P(T2|S) * ... * P(Tn|S)
            # P(T1|H) * P(T2|H) * ... * P(Tn|H)

            # 根據貝葉斯估計機率分別對S和H類的機率預測結果,斷定屬於垃圾郵件仍是正常郵件
            if spam_probability > ham_probability:
                results[SPAM] += 1
            else:
                results[HAM] += 1

            total_files = results[SPAM] + results[HAM]
            spam_fraction = float(results[SPAM]) / total_files
            ham_fraction = 1 - spam_fraction

        print 'Fraction of spam messages =', spam_fraction
        print 'Fraction of ham messages =', ham_fraction
        print ''


if __name__ == '__main__':
    # training process
    # 訓練模型,獲得訓練集中每一個詞的條件機率
    trainingProess()

    # test process
    # 測試模型
    testProcess()

    # 接收手工輸入,並基於當前模型斷定是不是惡意郵件
    mail_msg = raw_input('Enter the message to be classified:')
    print ''

    ## 0.2 and 0.8 because the ratio of samples for spam and ham were the 0.2-0.8
    spam_probability = classify(mail_msg, spam_training_set, 0.2)
    ham_probability = classify(mail_msg, ham_training_set, 0.8)
    if spam_probability > ham_probability:
        print 'Your mail has been classified as SPAM.'
    else:
        print 'Your mail has been classified as HAM.'
    print ''

Relevant Link:

http://www.ganecheng.tech/blog/53219332.html
https://en.wikipedia.org/wiki/Naive_Bayes_spam_filtering
https://github.com/aashishsatya/Bayesian-Spam-Filter/blob/master/ClassifierDemo.py
http://www.ganecheng.tech/blog/53219332.html
https://github.com/dwhitena/bayes-spam-filter
http://www2.aueb.gr/users/ion/data/enron-spam/
http://www.ruanyifeng.com/blog/2011/08/bayesian_inference_part_two.html
http://www.voidcn.com/blog/win_in_action/article/p-5800906.html
相關文章
相關標籤/搜索