答案页 · 12 道题

Python 朴素贝叶斯文本分类练习答案

本页汇总 Python 朴素贝叶斯文本分类 的 12 道练习。先做练习页,再回到这里核对准确答案和原因。

快速答案

本答案页包含 Python 朴素贝叶斯文本分类 的 4 道选择题、4 道填空题和 4 道输出预测题,每题都给出准确答案和简短解释。

答案已完整展示,建议先尝试作答,再用本页核对。第一次练习最好从互动练习页开始。

01 · 选择题

朴素贝叶斯的“朴素”来自哪个独立假设?

  1. 标签总是平衡的
  2. 给定类别后,各特征被假设为独立正确答案
  3. 所有词长度相同
  4. 每个类别先验相同

答案: 给定类别后,各特征被假设为独立

为什么: 模型把每个词的条件似然相乘,就像已知类别后各词互相独立。

02 · 选择题

为什么要给词频加入拉普拉斯平滑?

  1. 让训练文档变长
  2. 给词表排序
  3. 删除先验
  4. 避免没见过的词把概率变成零正确答案

答案: 避免没见过的词把概率变成零

为什么: 给每个计数加一,让没见过的词也有很小的非零似然。

03 · 选择题

为什么要在对数空间给朴素贝叶斯计分?

  1. 很多小概率连乘可能下溢正确答案
  2. 这样就不需要平滑
  3. 它把计数变成整数
  4. 对数会让类别自动平衡

答案: 很多小概率连乘可能下溢

为什么: 对数相加数值稳定,同时保留类别排序。

04 · 选择题

运行结果是什么?

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"].get("movie", 0))
  1. 0
  2. 4
  3. 1正确答案
  4. 2

答案: 1

为什么: movie 这个词在正类中出现了一次。

05 · 填空题

补全计数递增。

counts = {}
word = "movie"
counts[word] = counts.get(word, 0) + ____
print(counts[word])

答案: 1

为什么: 每出现一次,就在原有计数上加一。

06 · 填空题

补全拉普拉斯平滑的分子。

counts = {"movie": 1}
total = 2
vocab_size = 3
probability = (counts.get("film", 0) + ____) / (total + vocab_size)
print(round(probability, 2))

答案: 1

为什么: 平滑会给词表中每个词的观察计数加一。

07 · 填空题

补全对数空间的分数计算。

import math
probability = 0.2
print(round(math.____(probability), 3))

答案: log

为什么: log 函数把概率乘积变成加法。

08 · 填空题

补全先验的分母。

import math
class_docs = {"pos": 2, "neg": 2}
docs = ["a", "b", "c", "d"]
print(math.log(class_docs["pos"] / ____(docs)))

答案: len

为什么: 先验用某类文档数除以文档总数。

09 · 输出预测

这段程序打印出什么?

import math

docs = [("good movie", "pos"), ("great film", "pos"), ("bad movie", "neg"), ("boring film", "neg")]
vocab = sorted({word for text, _ in docs for word in text.split()})
counts = {}
priors = {}
for text, label in docs:
    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(docs))
        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)

print(predict("great film"))

答案: pos

为什么: 这两个词在训练数据中都偏正类,正类最终得到更高的对数分数。

10 · 输出预测

代码的输出结果是什么?

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["neg"]["bad"])

答案: 1

为什么: bad 在负类中出现一次,所以计数是 1。

11 · 输出预测

屏幕上会显示什么?

docs = ["good movie", "great film", "bad movie", "boring film"]
labels = ["pos", "pos", "neg", "neg"]
print(labels.count("pos") / len(docs))

答案: 0.5

为什么: 四篇训练文档中有两篇是正类,所以先验是 0.5。

12 · 输出预测

这段代码会输出什么?

counts = {"great": 0}
total = 4
vocab_size = 6
probability = (counts.get("great", 0) + 1) / (total + vocab_size)
print(round(probability, 1))

答案: 0.1

为什么: 平滑后的分子是 1,分母是 10,所以概率是 0.1。

先试一遍题目

打开 Python 朴素贝叶斯文本分类 练习页,用即时反馈回答同样的 12 道题。

练习本课