Python 樸素貝葉斯練習:計數、先驗與平滑
樸素貝葉斯大部分工作就是細緻地計數。這些練習構造計數表、轉成平滑機率、在對數空間比較類別,並在未參與訓練的文字上檢查結果。
練習:為每個類別建立計數表
標籤不是特徵。先按標籤拆分訓練文件,再在每個組內統計詞元。所有文件必須使用相同的分詞規則。
docs = [("good movie", "pos"), ("great film", "pos"), ("bad movie", "neg"), ("boring film", "neg")]
counts = {}
for text, label in docs:
counts.setdefault(label, {})
for word in text.split():
counts[label][word] = counts[label].get(word, 0) + 1
print(counts["pos"])
print(counts["neg"])按標籤分組的證據
練習:計算類別先驗
先驗是某個類別在文件中的佔比。當類別極不平衡時,它尤其重要。列印兩個先驗,並檢查它們之和為一。
labels = ["pos", "pos", "neg", "neg"]
for label in ("pos", "neg"):
print(label, labels.count(label) / len(labels))每個類別有多常見?
練習:平滑一個沒見過的詞
不做平滑時,某類別從未出現的詞會讓整個乘積變成零。給每個計數加一,並在分母加上詞表大小。
counts = {"great": 0}
total = 4
vocab_size = 6
probability = (counts.get("great", 0) + 1) / (total + vocab_size)
print(round(probability, 2))是很小的機率,不是零
練習:比較對數分數
類別分數等於對數先驗加上每個詞的對數似然。比較兩個候選分數,不需要連乘很小的數。分數更大者獲勝,同時要規定確定性的平局規則。
import math
pos = math.log(0.5) + math.log(0.2) + math.log(0.2)
neg = math.log(0.5) + math.log(0.1) + math.log(0.1)
print(round(pos, 2), round(neg, 2))
print("pos" if pos > neg else "neg")先加對數,再比較
練習:預測留出文字
用訓練文件建立模型,再給新文件分類。兩個例子上的準確率只是快速檢查,不能證明生產品質。
import math
train = [("good movie", "pos"), ("great film", "pos"), ("bad movie", "neg"), ("boring film", "neg")]
tests = [("great movie", "pos"), ("boring movie", "neg")]
vocab = sorted({word for text, _ in train for word in text.split()})
counts = {}
priors = {}
for text, label in train:
priors[label] = priors.get(label, 0) + 1
counts.setdefault(label, {})
for word in text.split():
counts[label][word] = counts[label].get(word, 0) + 1
def predict(text):
scores = {}
for label in counts:
total = sum(counts[label].values())
score = math.log(priors[label] / len(train))
for word in text.split():
score += math.log((counts[label].get(word, 0) + 1) / (total + len(vocab)))
scores[label] = score
return max(scores, key=scores.get)
correct = sum(predict(text) == label for text, label in tests)
print(correct / len(tests))一次快速檢查,不是基準測試
你的練習清單
- 訓練和預測使用同一個分詞器。
- 不要把標籤放進特徵詞表。
- 對詞表中的每個詞都做拉普拉斯平滑。
- 在對數空間計分,並規定平局規則。
- 在留出文字上評估,並報告樣本量。
常見問題
樸素貝葉斯需要神經網路嗎?
不需要。它是基於計數的機率分類器,也是許多文字任務的強基線。
詞不在詞表裡怎麼辦?
常見做法是忽略它,或映射到訓練時已經存在的未知詞元特徵。要在評估前定好。
為什麼對數分數都是負數?
機率最大為一,所以對數最大為零。比較相對大小即可,不必糾結符號。
練習計數與計分
12 道題,覆蓋計數、先驗、平滑、對數分數與留出預測。
繼續閱讀: