機器學習演算法(二): 樸素貝葉斯(Naive Bayes)

light-124發表於2020-12-23

這裡先給出阿里雲機器學習訓練營地址:阿里雲機器學習訓練營,可以將其程式碼下載進行學習或者參加最後一個任務的比賽。

1. 實驗室介紹

1.1 實驗環境

1. python3.7
2. numpy >= '1.16.4'
3. sklearn >= '0.23.1'

1.2 樸素貝葉斯的介紹

樸素貝葉斯演算法(Naive Bayes, NB) 是應用最為廣泛的分類演算法之一。它是基於貝葉斯定義和特徵條件獨立假設的分類器方法。由於樸素貝葉斯法基於貝葉斯公式計算得到,有著堅實的數學基礎,以及穩定的分類效率。NB模型所需估計的引數很少,對缺失資料不太敏感,演算法也比較簡單。當年的垃圾郵件分類都是基於樸素貝葉斯分類器識別的。

什麼是條件概率,我們從一個摸球的例子來理解。我們有兩個桶:灰色桶和綠色桶,一共有7個小球,4個藍色3個紫色,分佈如下圖:

從這7個球中,隨機選擇1個球是紫色的概率p是多少?選擇過程如下:

  1. 先選擇桶
  2. 再從選擇的桶中選擇一個球

上述我們選擇小球的過程就是條件概率的過程,在選擇桶的顏色的情況下是紫色的概率,另一種計算條件概率的方法是貝葉斯準則。

貝葉斯公式是英國數學家提出的一個資料公式:

p(A,B):表示事件A和事件B同時發生的概率。

p(B):表示事件B發生的概率,叫做先驗概率;p(A):表示事件A發生的概率。

p(A|B):表示當事件B發生的條件下,事件A發生的概率叫做後驗概率。

p(B|A):表示當事件A發生的條件下,事件B發生的概率。

我們用一句話理解貝葉斯:世間很多事都存在某種聯絡,假設事件A和事件B。人們常常使用已經發生的某個事件去推斷我們想要知道的之間的概率。 例如,醫生在確診的時候,會根據病人的舌苔、心跳等來判斷病人得了什麼病。對病人來說,只會關注得了什麼病,醫生會通道已經發生的事件來 確診具體的情況。這裡就用到了貝葉斯思想,A是已經發生的病人症狀,在A發生的條件下是B_i的概率。

1.3 樸素貝葉斯的應用

樸素貝葉斯演算法假設所有特徵的出現相互獨立互不影響,每一特徵同等重要,又因為其簡單,而且具有很好的可解釋性一般。相對於其他精心設計的更復雜的分類演算法,樸素貝葉斯分類演算法是學習效率和分類效果較好的分類器之一。樸素貝葉斯演算法一般應用在文字分類,垃圾郵件的分類,信用評估,釣魚網站檢測等。

補充說明:

貝葉斯公式沒有要求變數獨立。 樸素貝葉斯模型是假設變數是條件獨立的,從而模型容易求解。 這個假設很暴力,思想很naive,所以叫樸素貝葉斯。 真實世界,特徵之間很少是真的完全相互條件獨立的。

樸素貝葉斯為什麼需要變數之間獨立: 1.現實生活中,往往有非常多的特徵,每一個特徵的取值也是非常之多,那麼通過統計來估計後面概率的值 變得幾乎不可做,這也是為什麼需要假設特徵之間獨立的原因 2.假如我們沒有假設特徵之間相互獨立,那麼我們統計的時候,就需要在整個特徵空間中去找 這樣的話,由於資料的稀疏性,很容易統計到0的情況。 這樣是不合適的。

優點: 1.演算法邏輯簡單,易於實現(演算法思路很簡單,只要使用貝葉斯公式轉化一下即可!) 2.分類過程中時空開銷小(假設特徵相互獨立,只會涉及到二維儲存) 缺點: 理論上,樸素貝葉斯模型與其他分類方法相比具有最小的誤差率。但是實際上並非總是如此, 這是因為樸素貝葉斯模型假設屬性之間相互獨立,這個假設在實際應用中往往是不成立的, 在屬性個數比較多或者屬性之間相關性較大時,分類效果不好。 而在屬性相關性較小時,樸素貝葉斯效能最為良好。對於這一點,有半樸素貝葉斯之類的演算法通過考慮部分關聯性適度改進。

2. 實驗室手冊

2.1 學習目標

  1. 掌握貝葉斯公式
  2. 結合兩個例項瞭解貝樸素葉斯的引數估計
  3. 掌握貝葉斯估計

2.2 程式碼流程

  • Part 1. 鶯尾花資料集--貝葉斯分類

    • Step1: 庫函式匯入
    • Step2: 資料匯入&分析
    • Step3: 模型訓練
    • Step4: 模型預測
    • Step5: 原理簡析
  • Part 2. 模擬離散資料集--貝葉斯分類

    • Step1: 庫函式匯入
    • Step2: 資料匯入&分析
    • Step3: 模型訓練&視覺化
    • Step4: 原理簡析

2.3 演算法實戰

鶯尾花資料集--貝葉斯分類

Step1: 庫函式匯入

import warnings
warnings.filterwarnings('ignore')
#忽略警告
import numpy as np
# 載入鶯尾花資料集
from sklearn import datasets
# 匯入高斯樸素貝葉斯分類器
from sklearn.naive_bayes import GaussianNB
#匯入貝葉斯分類器
from sklearn.model_selection import train_test_split

Step2: 資料匯入&分析

X, y = datasets.load_iris(return_X_y=True)
#下載資料集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
#測試集分20%

Step3: 模型訓練

# 使用高斯樸素貝葉斯進行計算
clf = GaussianNB(var_smoothing=1e-8)
#prior:
#可輸入任何類陣列結構,形狀為(n_classes,),表示類的先驗概率。
#如果指定,則不根據資料調整先驗,如果不指定,則自行根據資料計算先驗概率P(Y)。
#浮點數,可不填(預設值= 1e-9)
#var_smoothing:
#在估計方差時,為了追求估計的穩定性,將所有特徵的方差中最⼤大的方差以某個比例新增到估計的方差中。
#這個比例,由var_smoothing引數控制。
clf.fit(X_train, y_train)

Step4: 模型預測

# 評估
y_pred = clf.predict(X_test)
acc = np.sum(y_test == y_pred) / X_test.shape[0]
print("Test Acc : %.3f" % acc)

# 預測
y_proba = clf.predict_proba(X_test[:1])
#X_test[:1]表示的是第一個樣本,y_proba輸出的是一個概率值。
print(clf.predict(X_test[:1]))
#predict直接輸出的預測的分類值
print("預計的概率值:", y_proba)

Step5: 原理簡析

模擬離散資料集--貝葉斯分類

Step1: 庫函式匯入 + Step2: 資料匯入&分析 + Step3: 模型訓練&視覺化 + Step4: 原理簡析

import random
import numpy as np
# 使用基於類目特徵的樸素貝葉斯
from sklearn.naive_bayes import CategoricalNB
#CategoricalNB:用於模擬離散資料集
#GaussianNB:資料呈正太分佈
#BernoulliNB:特徵是特徵是binary的
#MultinomialNB:特徵是categorical的
from sklearn.model_selection import train_test_split

Step2: 資料匯入&分析

# 模擬資料
rng = np.random.RandomState(1)
#可通過用Numpy工具包生成模擬資料集,使用RandomState獲得隨機數生成器。
##1為隨機種子,只要隨機種子seed相同,產生的隨機數序列就相同

# 隨機生成600個100維的資料,每一維的特徵都是[0, 4]之前的整數
X = rng.randint(5, size=(600, 100))
#size為形狀。5表示的是資料在5以內。
y = np.array([1, 2, 3, 4, 5, 6] * 100)
#y的形狀是(600,)

data = np.c_[X, y]
#data的形狀是(600, 101),資料型別是numpy.ndarray

# X和y進行整體打散
random.shuffle(data)

X = data[:,:-1]
y = data[:, -1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

所有的資料特徵都是離散特徵,我們引入基於離散特徵的樸素貝葉斯分類器。

Step3: 模型訓練&預測

clf = CategoricalNB(alpha=1)
#alpha為一個大於0的常數,常常取為1,即拉普拉斯平滑。
clf.fit(X_train, y_train)
acc = clf.score(X_test, y_test)
print("Test Acc : %.3f" % acc)

# 隨機資料測試,分析預測結果,貝葉斯會選擇概率最大的預測結果
# 比如這裡的預測結果是6,6對應的概率最大,由於我們是隨機資料
# 讀者執行的時候,可能會出現不一樣的結果。
x = rng.randint(5, size=(1, 100))
print(clf.predict_proba(x))
print(clf.predict(x))

2.4 原理簡析

2.4.1 結果分析

可以看到測試的資料的結果,貝葉斯會選擇概率最大的預測結果,比如這裡的預測結果是6,6對應的概率最大,由於我們是隨機資料,讀者執行的時候,可能會出現不一樣的結果。

這裡的測試資料的準確率沒有任何意義,因為資料是隨機生成的,不一定具有貝葉斯先驗性,這裡只是作為一個列子引導大家如何使用。

alpha=1這個參數列示什麼?

2.4.3 樸素貝葉斯的優缺點

優點: 樸素貝葉斯演算法主要基於經典的貝葉斯公式進行推倒,具有很好的數學原理。而且在資料量很小的時候表現良好,資料量很大的時候也可以進行增量計算。由於樸素貝葉斯使用先驗概率估計後驗概率具有很好的模型的可解釋性。

缺點: 樸素貝葉斯模型與其他分類方法相比具有最小的理論誤差率。但是實際上並非總是如此,這是因為樸素貝葉斯模型給定輸出類別的情況下,假設屬性之間相互獨立,這個假設在實際應用中往往是不成立的,在屬性個數比較多或者屬性之間相關性較大時,分類效果不好。而在屬性相關性較小時,樸素貝葉斯效能最為良好。對於這一點,有半樸素貝葉斯之類的演算法通過考慮部分關聯性適度改進,例如為了計算量不至於太大,我們假定每個屬性只依賴另外的一個。解決特徵之間的相關性,我們還可以使用資料降維(PCA)的方法,去除特徵相關性,再進行樸素貝葉斯計算。

相關文章