資料科學和人工智慧技術筆記 十六、樸素貝葉斯
十六、樸素貝葉斯
作者:Chris Albon
譯者:飛龍
伯努利樸素貝葉斯
伯努利樸素貝葉斯分類器假設我們的所有特徵都是二元的,它們僅有兩個值(例如,已經是獨熱編碼的標稱分類特徵)。
# 載入庫
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
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 函式替換:
其中
是第
個觀測的目標值
是類
的概率,
是類的總數。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 |
貝葉斯定理是一個著名的方程,它允許我們根據資料進行預測。 這是貝葉斯定理的經典版本:
這可能過於抽象,所以讓我們替換一些變數以使其更具體。 在貝葉斯分類器中,給定資料的情況下,我們有興趣找出觀測的類別(例如男性或女性,垃圾郵件或非垃圾郵件):
其中:
- 是特定類別(例如男性)
- 是觀測的資料
- 稱為後驗
- 叫做似然
- 叫做先驗
- 叫做邊緣概率
在貝葉斯分類器中,我們計算每個觀測的每個類的後驗(嚴格來說,我們只計算後驗的分子,但現在忽略它)。 然後,基於後驗值最大的類別對觀測分類。 在我們的例子中,我們為觀測預測兩個可能的類別(例如男性和女性),因此我們將計算兩個後驗:一個用於男性,一個用於女性。
高斯樸素的貝葉斯可能是最受歡迎的貝葉斯分類器。 為了解釋這個名稱的含義,讓我們看一下當我們應用兩個類別(男性和女性)和三個特徵變數(高度,重量和尺寸)時貝葉斯方程式的樣子: