1. 程式人生 > >資料科學和人工智慧技術筆記 十六、樸素貝葉斯

資料科學和人工智慧技術筆記 十六、樸素貝葉斯

十六、樸素貝葉斯

作者:Chris Albon

譯者:飛龍

協議:CC BY-NC-SA 4.0

伯努利樸素貝葉斯

伯努利樸素貝葉斯分類器假設我們的所有特徵都是二元的,它們僅有兩個值(例如,已經是獨熱編碼的標稱分類特徵)。

# 載入庫
import numpy as np
from sklearn.naive_bayes import BernoulliNB

# 建立三個二元特徵
X = np.random.randint(2, size=(100, 3))

# 建立二元目標向量
y = np.random.randint(2, size=(
100, 1)).ravel() # 檢視前十個觀測 X[0:10] ''' array([[1, 1, 1], [0, 1, 0], [1, 1, 1], [0, 0, 0], [1, 0, 1], [1, 1, 1], [0, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 0]]) ''' # 建立伯努利樸素貝葉斯物件,帶有每個類別的先驗概率 clf = BernoulliNB(class_prior=[0.25, 0.5]) # 訓練模型 model = clf.
fit(X, y)

校準預測概率

類別概率是機器學習模型中常見且有用的部分。 在 scikit-learn 中,大多數學習演算法允許我們使用predict_proba來檢視成員的類別預測概率。 例如,如果我們想要僅預測某個類,如果模型預測它們是該類的概率超過 90%,則這非常有用。 然而,一些模型,包括樸素貝葉斯分類器輸出的概率,不基於現實世界。 也就是說,predict_proba可能預測,觀測有 0.70 的機會成為某一類,而實際情況是它是 0.10 或 0.99。 特別是在樸素貝葉斯中,雖然不同目標類別的預測概率的排名是有效的,但是原始預測概率傾向於接近 0 和 1 的極值。

為了獲得有意義的預測概率,我們需要進行所謂的校準。 在 scikit-learn 中,我們可以使用CalibratedClassifierCV

類,使用 k-fold 交叉驗證建立校準良好的預測概率。 在CalibratedClassifierCV中,訓練集用於訓練模型,測試集用於校準預測概率。返回的預測概率是 k 折的平均值。

# 載入庫
from sklearn import datasets
from sklearn.naive_bayes import GaussianNB
from sklearn.calibration import CalibratedClassifierCV

# 載入資料
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 建立高斯樸素貝葉斯物件
clf = GaussianNB()

# 使用 sigmoid 校準建立校準的交叉驗證
clf_sigmoid = CalibratedClassifierCV(clf, cv=2, method='sigmoid')

# 校準概率
clf_sigmoid.fit(X, y)

'''
CalibratedClassifierCV(base_estimator=GaussianNB(priors=None), cv=2,
            method='sigmoid') 
'''

# 建立新的觀測
new_observation = [[ 2.6,  2.6,  2.6,  0.4]]

# 檢視校準概率
clf_sigmoid.predict_proba(new_observation)

# array([[ 0.31859969,  0.63663466,  0.04476565]]) 

高斯樸素貝葉斯分類器

由於正態分佈的假設,高斯樸素貝葉斯最適用於我們所有特徵都是連續的情況。

# 載入庫
from sklearn import datasets
from sklearn.naive_bayes import GaussianNB

# 載入資料
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 建立高斯樸素貝葉斯物件,帶有每個類別的先驗概率
clf = GaussianNB(priors=[0.25, 0.25, 0.5])

# 訓練模型
model = clf.fit(X, y)

# 建立新的觀測
new_observation = [[ 4,  4,  4,  0.4]]

# 預測類別
model.predict(new_observation)

# array([1]) 

注意:來自高斯樸素貝葉斯的原始預測概率(使用predict_proba輸出)未校準。 也就是說,他們不應該是可信的。 如果我們想要建立有用的預測概率,我們將需要使用等滲迴歸或相關方法來校準它們。

多項式邏輯迴歸

在多項邏輯迴歸(MLR)中,我們在 Recipe 15.1 中看到的邏輯函式被 softmax 函式替換:

P ( y i = k X ) = e β k x i j = 1 K e β j x i P(y_i=k \mid X)={\frac {e^{\beta_{k}x_{i}}}{{\sum_{j=1}^{K}}e^{\beta_{j}x_{i}}}}

其中 P ( y i = k X ) P(y_i=k \mid X) 是第 i i 個觀測的目標值 y i y_i 是類 k k 的概率, K K 是類的總數。MLR 的一個實際優點是使用predict_proba方法預測的概率更可靠(即校準更好)。

# 載入庫
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.preprocessing import StandardScaler

# 載入資料
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 標準化特徵
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# 建立 OVR 邏輯迴歸物件
clf = LogisticRegression(random_state=0, multi_class='multinomial', solver='newton-cg')

# 訓練模型
model = clf.fit(X_std, y)

# 建立新的觀測
new_observation = [[.5, .5, .5, .5]]

# 預測類別
model.predict(new_observation)

# array([1]) 

# 檢視預測概率
model.predict_proba(new_observation)

# array([[ 0.01944996,  0.74469584,  0.2358542 ]]) 

多項式樸素貝葉斯分類器

多項式樸素貝葉斯的工作方式類似於高斯樸素貝葉斯,但假設這些特徵是多項式分佈的。 在實踐中,這意味著當我們具有離散資料(例如,電影評級範圍為 1 到 5)時,通常使用該分類器。

# 載入庫
import numpy as np
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer

# 建立文字
text_data = np.array(['I love Brazil. Brazil!',
                      'Brazil is best',
                      'Germany beats both'])

# 建立詞袋
count = CountVectorizer()
bag_of_words = count.fit_transform(text_data)

# 建立特徵矩陣
X = bag_of_words.toarray()

# 建立目標向量
y = np.array([0,0,1])

# 建立多項式樸素貝葉斯物件,帶有每個類別的先驗概率
clf = MultinomialNB(class_prior=[0.25, 0.5])

# 訓練模型
model = clf.fit(X, y)

# 建立新的觀測
new_observation = [[0, 0, 0, 1, 0, 1, 0]]

# 預測新觀測的類別
model.predict(new_observation)

# array([0]) 

從零編寫樸素貝葉斯分類器

樸素貝葉斯是一種簡單的分類器,當只有少量觀測可用時,這種分類器表現良好。 在本教程中,我們將從頭開始建立一個高斯樸素貝葉斯分類器,並使用它來預測以前未見過的資料點的類別。本教程基於 Wikipedia 的樸素貝葉斯分類器頁面上的示例,我已經用 Python 實現了它並調整了一些符號來改進解釋。

import pandas as pd
import numpy as np

我們的資料集包含八個個體的資料。 我們將使用資料集構建一個分類器,該分類器接收個體的身高,體重和腳碼,並輸出其性別預測。

# 建立空資料幀
data = pd.DataFrame()

# 建立我們的目標變數
data['Gender'] = ['male','male','male','male','female','female','female','female']

# 建立我們的特徵變數
data['Height'] = [6,5.92,5.58,5.92,5,5.5,5.42,5.75]
data['Weight'] = [180,190,170,165,100,150,130,150]
data['Foot_Size'] = [12,11,12,10,6,8,7,9]

# 檢視資料
data
Gender Height Weight Foot_Size
0 male 6.00 180 12
1 male 5.92 190 11
2 male 5.58 170 12
3 male 5.92 165 10
4 female 5.00 100 6
5 female 5.50 150 8
6 female 5.42 130 7
7 female 5.75 150 9

上面的資料集用於構造我們的分類器。 下面我們將建立一個新的個體,我們知道它的特徵值,但不知道它的性別。我們的目標是預測它的性別。

# 建立空資料幀
person = pd.DataFrame()

# 為這一行建立相同特徵值
person['Height'] = [6]
person['Weight'] = [130]
person['Foot_Size'] = [8]

# 檢視資料
person
Height Weight Foot_Size
0 6 130 8

貝葉斯定理是一個著名的方程,它允許我們根據資料進行預測。 這是貝葉斯定理的經典版本:

P ( A B ) = P ( B A )   P ( A ) P ( B ) \displaystyle P(A\mid B)={\frac {P(B\mid A)\,P(A)}{P(B)}}

這可能過於抽象,所以讓我們替換一些變數以使其更具體。 在貝葉斯分類器中,給定資料的情況下,我們有興趣找出觀測的類別(例如男性或女性,垃圾郵件或非垃圾郵件):

p ( class data ) = p ( data class ) p ( class ) p ( data ) p(\text{class} \mid \mathbf {\text{data}} )={\frac {p(\mathbf {\text{data}} \mid \text{class}) * p(\text{class})}{p(\mathbf {\text{data}} )}}

其中:

  • class \text{class} 是特定類別(例如男性)
  • data \mathbf {\text{data}} 是觀測的資料
  • p ( class data ) p(\text{class} \mid \mathbf {\text{data}} ) 稱為後驗
  • p ( data|class ) p(\text{data|class}) 叫做似然
  • p ( class ) p(\text{class}) 叫做先驗
  • p ( data ) p(\mathbf {\text{data}} ) 叫做邊緣概率

在貝葉斯分類器中,我們計算每個觀測的每個類的後驗(嚴格來說,我們只計算後驗的分子,但現在忽略它)。 然後,基於後驗值最大的類別對觀測分類。 在我們的例子中,我們為觀測預測兩個可能的類別(例如男性和女性),因此我們將計算兩個後驗:一個用於男性,一個用於女性。

p ( person is male person’s data ) = p ( person’s data person is male ) p ( person is male ) p ( person’s data ) p(\text{person is male} \mid \mathbf {\text{person’s data}} )={\frac {p(\mathbf {\text{person’s data}} \mid \text{person is male}) * p(\text{person is male})}{p(\mathbf {\text{person’s data}} )}}

p ( person is female person’s data ) = p ( person’s data person is female ) p ( person is female ) p ( person’s data ) p(\text{person is female} \mid \mathbf {\text{person’s data}} )={\frac {p(\mathbf {\text{person’s data}} \mid \text{person is female}) * p(\text{person is female})}{p(\mathbf {\text{person’s data}} )}}

高斯樸素的貝葉斯可能是最受歡迎的貝葉斯分類器。 為了解釋這個名稱的含義,讓我們看一下當我們應用兩個類別(男性和女性)和三個特徵變數(高度,重量和尺寸)時貝葉斯方程式的樣子:

posterior (male) = P ( male )   p ( height male )   p ( weight male )   p ( foot size male ) marginal probability {\displaystyle {\text{posterior (male)}}={\frac {P({\text{male}})\,p({\text{height}}\mid{\text{male}})\,p({\text{weight}}\mid{\text{male}})\,p({\text{foot size}}\mid{\text{male}})}{\text{marginal probability}}}}