MachineLearning—Naive Bayes

  • 2019 年 10 月 6 日
  • 筆記

第三天機器學習啦!今天我們主要來一個比較「樸素」的算法,樸素貝葉斯(Naive Bayes),至於它為什麼樸素我們待會兒再講吧!

首先,我們來看一下貝葉斯算法,它是幹嘛的呢?

貝葉斯算法是一類分類算法的統稱,這類算法全是基於貝葉斯定理,所以叫貝葉斯算法,那樸素貝葉斯呢?他是貝葉斯分類算法中最簡單的一個算法,它的樸素之處在於事件獨立。

我們現在先來講講貝葉斯理論吧:

現在我們有個數據集,它由兩類組成,一類是圓形點,一類是三角形點,如下圖:

我們現在用P1(x,y)表示圓點的概率,用P2(x,y)表示三角形點的概率,現在我們可以通過P1,P2的概率來判斷他們的類別:

if P1(x,y)>P2(x,y), then 類別為圓點

if P1(x,y)<P2(x,y), then 類別為三角形點

即選擇高概率對應的類別,這也就是貝葉斯的核心決策思想:選擇具有最高概率的決策。

現在我們來看看條件概率,什麼是條件概率?

【條件概率:兩個事件獨立,在一個事件已經發生的情況下去求另一件事發生的概率。所謂 獨立(independence) 指的是統計意義上的獨立,即一個特徵出現的可能性與它和其他特徵相鄰沒有關係,而這個獨立也就是樸素貝葉斯樸素的含義了。】

舉個例子來解釋一下,我有7個乒乓球,放在一個黑色不透明的箱子里。3個白的,4個黃的,取到白球的概率是多少?

這個題目應該很簡單,直接就可以算出答案,為3/7。

那我們現在把題目修改一下:

現在有兩個黑色不透明密閉的盒子,第一個盒子放2個白色2個黃色乒乓球,第二個盒子放1個白的,2個黃色的。現在我們要求:從第二個盒子里取出白球的概率。這個就是我們所謂的條件概率了。

P(白|在二盒子)就是我們所要求的結果

P(白|在二盒子)= P(白色且在二盒子)/P(在二盒子)

我們之前說了貝葉斯定理,那麼我們現在就需要來介紹一下,貝葉斯所表達的核心定理是什麼呢?

下面我們通過一張圖,一個公式來介紹:

首先我們介紹一下我們畫的圖:矩形框是我們的一個樣本空間,代表所有可能發的結果,圖中黃顏色的A就是事件A發生的可能性,想要表示成概率[P],那麼A發的概率的話就是P(A),那途中B事件發生的概率也就是P(B)了,那麼A和B中間重複的一部分是什麼意思呢,就是A和B同時一起發生的概率,我們可以用P(AB)來表示。為了去了解貝葉斯,我們還需要去了解一個東西P(B|A)是什麼意思?

P(B|A)所代表的意思是,在A事件已經發生的前提下發生B事件的概率(這個就是條件概率了)

了解了這些之後,我們下面來看公式:

這個公式的意思是,求在A已經發生的情況下B事件發生的概率,通過B事件發生的概率乘以B事件發生的前提下A事件發生的概率再除以A事件發生的概率。

這就是貝葉斯公式。

這是最基本的貝葉斯的概念,那我們然後將這個公式與機器學習掛上鉤呢?

很簡單,令A=特徵,B=類別,這樣不就是我們所想要的公式嗎?

P(類別|特徵)=P(特徵|類別)*P(類別)/P(特徵)

最後只要求P(類別|特徵)即可。

Now,我們現在使用條件概率進行分類

之前我們是只有兩類,圓點類和三角形點類,但是在實際應用中卻不止這麼兩個類或者說我們只需要從一些類別中調出對我們有效的類別,這個時候我們就需要條件概率了,引入類別class,對於之前的圓點和三角形點我們簡寫成c1,c2,那麼P(c1|x,y)=P(x,y|c1)*P(c1)/P(x,y)。以此推一下,我們求點想,y來自某個類別ci的概率:

在做垃圾郵件分類的時候,一份郵件就是實例,而電子郵件中的一些能辨別它是否為垃圾郵件的詞就是我們所要找的特徵,對於,每個詞出現的頻率為該特徵的值,這樣得到的特徵數目就會和我們對比的目標詞彙一樣多。

樸素貝葉斯是上面介紹的貝葉斯分類器的一個擴展,是用於文檔分類的常用算法。下面我們來做一做樸素貝葉斯分類的實踐項目。

首先我們明確一下我們要用樸素貝葉斯幹嘛,它的工作原理是?

這邊我們寫成Python的語法結構:

了解完它的工作原理之後,下面我們準備開發一個簡單的Python分類的項目,我們先來整理一下我們的開發步驟:

Step1:收集數據

Step2:準備數據,準備成我們想要的數字類型

Step3:分析數據,對於具有大量的特徵時我們使用直方圖

Step4:訓練算法,計算不同獨立特徵的條件概率

Step5:測試算法,看算法的效率如何,如果效率很低,返回Step4

Step6:使用已經訓練好的算法。

Step1: 收集數據,這裡我們是創建自己的數據集

Step2:準備數據,從文本中構建詞向量

便利查看單詞的位置

Step3:分析數據,檢查詞條確保解析的正確性

在我們現在的這個代碼中就很簡單了,檢查函數的有效性,我們多運行幾次函數,輸入數據,查看該詞彙出現的次數

輸出結果:

[0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]

多測幾次…..

Step4:訓練算法,對於詞向量的計算概率

取代之前的特徵值想x,y,我們用一個向量w來表示,w裏面可以包含多個值,我們的計算公式就變成了:

利用這個公式計算不同的ci對呀的值,如何比較他們概率的大小。

那麼問題來了,我們沒有P(w)怎麼辦,我們之前都沒有計算P(w),現在沒有這個值我們該怎麼去比較大小呢?

OK,那麼我們來想一下,ci一定的時候,我們對應的P(w)是不是也是一定的?結果當然是肯定的,對於我們剛剛創建的數據集,無論是0還是1他們各自對應的P(w)都特么事個定值,簡而言之我們就可以直接去比較分子的大小了,直接通過分子的大小來確定分類。

這邊我們有個公式介紹一下,就是將w向量展開成所有的獨立特徵的時候,我們可以樸素貝葉斯假設,即:

p(w | ci) = (w0 | ci)p(w1 | ci)p(w2 | ci)…p(wn | ci)

這樣我們就可以來寫訓練函數了:

這邊我們要定義兩個參數,第一個trainMatrix,它代表文件單詞矩陣,即我們的w,第二個參數是trainCategory,代表文件對應的類別。

Step5:測試算法(優化)

在測試算法的時候,我們發現當計算p(w0|ci) * p(w1|ci) * p(w2|ci)… p(wn|ci)的時候,由於這個概率本身就都非常小,這些很小的數相乘會造成下溢出,答案往往接近0,無法準確的將結果表達出來(大家都是賊接近0的數,怎麼比),這個時候你的高中數學就可以幫到你的忙了。我們在高中學過,與一次函數成正比的函數(就是圖像趨勢相同),沒錯!就是對數函數,而且這邊的對數函數我們可以將原來的乘法計算換算成加法計算,減少了我們的計算量,同時,更重要的是解決了下溢出的問題。

我們需要:from math import log

Step6:使用算法

搞定,分分鐘實現了樸素貝葉斯!

代碼地址:

https://www.bytelang.com/o/s/c/NqiiCImUXo4=