前言
在自然语言处理(NLP)和文本分类任务中,朴素贝叶斯(Naive Bayes) 是一个非常经典且高效的算法。它基于概率论中的贝叶斯定理,并做了一个"朴素"的假设------特征条件独立。今天我们将从概率基础出发,逐步推导朴素贝叶斯,并通过一个真实的商品评论情感分析案例,带你彻底掌握它。
一、概率基础复习
在理解朴素贝叶斯之前,我们需要先搞懂几个常见的概率概念。
1. 条件概率
条件概率表示事件 A 在另外一个事件 B 已经发生条件下的发生概率,记作 P(A|B)。
例子:在"女神喜欢"的条件下,职业是"程序员"的概率是多少?
-
女神喜欢的样本有:2、3、4、7,共 4 个。
-
其中是程序员的有:3、4,共 2 个。
-
则
P(程序员|喜欢) = 2 / 4 = 0.5。
2. 联合概率
联合概率表示多个条件同时成立的概率,记作 P(AB)。
-
公式:
P(AB) = P(A) * P(B|A) -
例子:职业是程序员且体型匀称的概率是多少?
-
数据集中共 7 个样本。
-
职业是程序员有 1、3、4,共 3 个,概率为 3/7。
-
在程序员中,体型匀称的有 3,共 1 个,概率为 1/3。
-
则
P(程序员, 匀称) = 3/7 * 1/3 = 1/7。
-
3. 联合概率 + 条件概率
在女神喜欢的条件下,职业是程序员且体重超重的概率:P(AB|C) = P(A|C) * P(B|AC)。
-
在女神喜欢的条件下,有 2、3、4、7 共 4 个样本。
-
在这 4 个样本中,程序员有 3、4,概率为 2/4 = 0.5。
-
在这 2 个样本中,体型超重的有 4,概率为 1/2 = 0.5。
-
则
P(程序员, 超重|喜欢) = 0.5 * 0.5 = 0.25。
总结:条件概率是"去掉部分样本后计算概率",联合概率是"多个事件同时发生的概率"。
二、贝叶斯公式详解
贝叶斯公式的核心思想是:根据训练样本估计先验概率,再根据条件概率调整,最终得到后验概率。
公式如下:

参数解释:
-
P(C):先验概率,即 C 出现的概率。 -
P(W|C):条件概率,即 C 条件下 W 出现的概率。 -
P(W):W 出现的概率。 -
P(C|W):后验概率,即 W 出现的条件下 C 出现的概率。
计算示例:
-
P(C)= P(喜欢) = 4/7 -
P(W|C)= P(程序员,超重|喜欢) = 1/4 -
P(C|W)的分子 =P(W|C) * P(C)= 4/7 * 1/4 = 1/7 -
P(W)= P(程序员,超重) = 3/7 * 2/3 = 2/7 -
最终
P(喜欢|程序员, 超重)= (1/7) / (2/7) = 0.5
三、朴素贝叶斯:核心在于"朴素"
在贝叶斯计算中,计算 P(W|C) 和 P(W) 这样的联合概率往往很复杂。为了简化计算,朴素贝叶斯增加了"特征条件独立假设",即假设特征之间是互为独立的。
此时,联合概率的计算简化为:
-
P(程序员,超重|喜欢) = P(程序员|喜欢) * P(超重|喜欢) -
P(程序员,超重) = P(程序员) * P(超重)
这就是"朴素"二字的由来。虽然现实中特征往往不独立,但这个假设让计算变得极其高效,且在文本分类等任务中效果出奇的好。
四、拉普拉斯平滑系数
在训练样本不足时,概率计算可能会出现 0 的情况(比如某个词在某个类别中从未出现)。一旦出现 0,整个连乘结果就是 0,这会导致模型失效。
拉普拉斯平滑通过在分子和分母分别加上一个常数来解决这个问题:
-
αα:平滑系数,一般指定为 1。
-
NiNi:F1 中符合条件 C 的样本数量。
-
NN:在条件 C 下所有样本的总数。
-
mm:所有独立样本的总数。
核心作用:避免概率值为 0,保证模型能处理未见过的特征。
五、实战:商品评论情感分析
1. 学习目标
-
知道朴素贝叶斯的 API。
-
能够应用朴素贝叶斯实现商品评论情感分析。
2. API 介绍
python
sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
alpha:拉普拉斯平滑系数,默认为 1.0。
3. 步骤分析
-
获取数据
-
数据基本处理(取内容列、判定标准、选停用词、分词转化、统计词频、划分训练测试集)
-
模型训练
-
模型评估
4. 代码实现
python
import pandas as pd
import numpy as np
import jieba
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
# 1)获取数据
data = pd.read_csv("./data/书籍评价.csv", encoding="gbk")
# 2)数据基本处理
# 2.1)取出内容列
content = data["内容"]
# 2.2)判定评判标准 -- 1好评; 0差评
data.loc[data.loc[:, '评价'] == "好评", "评论标号"] = 1
data.loc[data.loc[:, '评价'] == '差评', '评论标号'] = 0
good_or_bad = data['评价'].values
print("真实标签:", good_or_bad)
# 2.3)选择停用词
stopwords = []
with open('./data/stopwords.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
for tmp in lines:
line = tmp.strip()
stopwords.append(line)
stopwords = list(set(stopwords)) # 去重
# 2.4)把"内容"处理,转化成标准格式
comment_list = []
for tmp in content:
# 对文本数据进行切割,默认为精确模式
seg_list = jieba.cut(tmp, cut_all=False)
seg_str = ','.join(seg_list) # 拼接字符串
comment_list.append(seg_str)
# 2.5)统计词的个数
# 实例化 CountVectorizer 类,将文本中的词语转换为词频矩阵
con = CountVectorizer(stop_words=stopwords)
X = con.fit_transform(comment_list) # 计算各个词语出现的次数
name = con.get_feature_names_out() # 获取词袋中所有文本的关键字
print("词频矩阵:\n", X.toarray())
print("特征词:", name)
# 2.6)准备训练集和测试集
# 这里将文本前10行当做训练集,后3行当做测试集
x_train = X.toarray()[:10, :]
y_train = good_or_bad[:10]
x_text = X.toarray()[10:, :]
y_text = good_or_bad[10:]
# 3)模型训练
# 构建贝叶斯算法分类器
mb = MultinomialNB(alpha=1) # alpha 为可选项,默认 1.0,添加拉普拉斯平滑
mb.fit(x_train, y_train) # 训练数据
y_predict = mb.predict(x_text) # 预测数据
print('预测值:', y_predict)
print('真实值:', y_text)
# 4)模型评估
score = mb.score(x_text, y_text)
print("模型准确率:", score)
六、总结
-
朴素贝叶斯基于贝叶斯定理,并假设特征之间相互独立。
-
通过拉普拉斯平滑解决零概率问题。
-
在文本分类(如情感分析)中,配合
jieba分词和CountVectorizer词频统计,可以快速构建高效基线模型。