Naive Bayes 是一種分類問題演算法,它依據貝氏定理計算出每個資料點屬於特定類別的機率,例如將每封電子郵件分類成「惡意」或「正常」,Naive Bayes 的工作流程會像是這樣:(虛構情境)
先驗機率 (Prior Probability):
P(Spam) = 0.10 (惡意郵件的機率)
P(Not Spam) = 0.90 (正常郵件的機率)
我們將以三個關鍵字來進行分析:緊急、賺錢、飆股。以下是這些關鍵字在惡意郵件和正常郵件中的條件機率。
對於惡意郵件 (Spam):
P(Emergency | Spam) = 0.80
P(Money | Spam) = 0.70
P(Stocks | Spam) = 0.60
對於正常郵件 (Not Spam):
P(Emergency | Not Spam) = 0.10
P(Money | Not Spam) = 0.05
P(Stocks | Not Spam) = 0.10
假設我們收到一封郵件,其中包含了「緊急」和「賺錢」兩個關鍵字,我們需要計算這封郵件是惡意郵件的後驗機率。
計算條件機率:
P(Emergency, Money | Spam) = P(Emergency | Spam) * P(Money | Spam)
= 0.80 * 0.70
= 0.56
P(Emergency, Money | Not Spam) = P(Emergency | Not Spam) * P(Money | Not Spam)
= 0.10 * 0.05
= 0.005
計算邊際機率 (P(Emergency, Money)):
P(Emergency, Money) = P(Emergency, Money | Spam) * P(Spam) + P(Emergency, Money | Not Spam) * P(Not Spam)
= 0.56 * 0.10 + 0.005 * 0.90
= 0.056 + 0.0045
= 0.0605
使用貝氏定理計算後驗機率:
P(Spam | Emergency, Money) = (P(Emergency, Money | Spam) * P(Spam)) / P(Emergency, Money)
= (0.56 * 0.10) / 0.0605
= 0.056 / 0.0605
≈ 0.924
實作程式碼:
```
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline
# Define the dataset
documents = [
"urgent money making offer", # Spam
"limited time emergency sale", # Spam
"normal email from friend", # Not Spam
"hello, let's catch up", # Not Spam
"special offer just for you", # Spam
"buy now or miss out", # Spam
"meeting agenda", # Not Spam
"weekly newsletter", # Not Spam
"financial report", # Not Spam
"update on project" # Not Spam
]
# Labels: 1 for spam, 0 for not spam
labels = [1, 1, 0, 0, 1, 1, 0, 0, 0, 0]
# Create the model pipeline
model = make_pipeline(
CountVectorizer(),
MultinomialNB()
)
# Fit the model with the example data
model.fit(documents, labels)
# Define a new email to classify
new_email = ["emergency money"]
# Predict the class of the new email
prediction = model.predict(new_email)
# Calculate the probabilities
probabilities = model.predict_proba(new_email)
# Print the prediction and probabilities
print("Prediction (1 for spam, 0 for not spam):", prediction[0])
print("Probabilities (not spam, spam):", probabilities)
```
Prediction (1 for spam, 0 for not spam): 1
Probabilities (not spam, spam): [[0.28049793 0.71950207]]
如果使用BernoulliNB來進行測試..
```
BernoulliNB_model = make_pipeline(
CountVectorizer(binary=True), # Use binary=True to binarize the features
BernoulliNB()
)
# Fit the model with the example data
BernoulliNB_model.fit(documents, labels)
# Predict the class of the new email
BernoulliNB_prediction = BernoulliNB_model.predict(new_email)
# Calculate the probabilities
BernoulliNB_probabilities = BernoulliNB_model.predict_proba(new_email)
# Print the prediction and probabilities
print("Prediction (1 for spam, 0 for not spam):", BernoulliNB_prediction[0])
print("Probabilities (not spam, spam):", BernoulliNB_probabilities[0])
```
Prediction (1 for spam, 0 for not spam): 0
Probabilities (not spam, spam): [0.73484902 0.26515098]
------------------------------------------------------------
MultinomialNB的計算:
假設在訓練過程中,某些詞(例如 "money", "urgent", "offer" 等)在垃圾郵件中出現的頻率較高。
當我們輸入 "emergency money" 時,MultinomialNB 會根據這些詞的出現次數計算其在垃圾郵件中的概率。
因為這些詞出現頻率高,導致預測為垃圾郵件的概率較高,最終結果是 0.71950207。
BernoulliNB的計算:
在訓練過程中,每個詞是否出現在文檔中作為特徵進行計算。
當我們輸入 "emergency money" 時,BernoulliNB 會根據這些詞是否存在計算其在垃圾郵件中的概率。
由於 BernoulliNB 只考慮詞是否存在,而不考慮詞的出現次數,某些詞的影響力會降低。
最終,該模型可能認為這些詞的存在不足以強烈指示該郵件為垃圾郵件,結果是 0.73484902,即該郵件被分類為正常郵件的概率較高。
總結
MultinomialNB 強調詞的出現次數,高頻詞對結果影響大,導致它將 "emergency money" 預測為垃圾郵件。
BernoulliNB 強調詞的存在性,每個詞的影響力相對一致,導致它將 "emergency money" 預測為正常郵件。
------------------------------------------------------------
若再將方法換成ComplementNB:
```
from sklearn.naive_bayes import ComplementNB
ComplementNB_model = make_pipeline(
CountVectorizer(binary=True), # Use binary=True to binarize the features
ComplementNB()
)
ComplementNB_model.fit(documents, labels)
# Predict the class of the new email
ComplementNB_prediction = ComplementNB_model.predict(new_email)
# Calculate the probabilities
ComplementNB_probabilities = ComplementNB_model.predict_proba(new_email)
# Print the prediction and probabilities
print("Prediction (1 for spam, 0 for not spam):", ComplementNB_prediction[0])
print("Probabilities (not spam, spam):", ComplementNB_probabilities[0])
```
Prediction (1 for spam, 0 for not spam): 1
Probabilities (not spam, spam): [0.20628624 0.79371376]
在這個範例中,垃圾郵件(spam)的比例較低(40%),正常郵件(not spam)的比例較高(60%)。這樣的不平衡可能會導致 MultinomialNB 在某些情況下偏向於預測正常郵件。
使用 ComplementNB 後,模型更能有效地處理類別不平衡的情況,並給予垃圾郵件特徵更高的權重,這使得垃圾郵件更容易被正確分類
------------------------------------------------------------
方法比較:
1. Multinomial Naive Bayes
適用情況:
* 文本分類: 尤其適合詞頻數據(例如,文檔中詞的出現次數)。
* 自然語言處理: 如垃圾郵件檢測、情感分析、主題建模。
* 標籤型數據: 當特徵是離散計數時,例如電子郵件中的詞頻、點擊次數等。
2. Bernoulli Naive Bayes
適用情況:
* 二元/布爾特徵: 當特徵是存在/不存在時(0或1),如文本中詞的出現與否。
* 文檔分類: 尤其是短文本或包含大量二元特徵的數據。
* 垃圾郵件檢測: 對於特定關鍵詞的出現與否進行分類。
3. Gaussian Naive Bayes
適用情況:
* 連續數據: 特徵是連續值而非離散值,例如,在醫療數據、傳感器數據、股票價格等情境下。
* 分類問題: 用於二元或多類分類問題。
4. Complement Naive Bayes
適用情況:
* 不平衡數據: 特別適合於處理類別不平衡的文本分類問題。
* 文本分類: 用於垃圾郵件檢測、情感分析等。
5. Categorical Naive Bayes
適用情況:
* 分類特徵: 特徵是離散類別型變量,如問卷調查數據、用戶行為數據。
* 分類問題: 用於二元或多類分類問題。
6. Poisson Naive Bayes
適用情況:
* 計數數據: 特徵是計數型數據,如事件發生次數、點擊次數等。
* 分類問題: 用於二元或多類分類問題。