朴素贝叶斯算法
前言
- 接下来我们介绍一种用于分类的算法。
一、概念
- 朴素贝叶斯 (Naive Bayes) 是一种基于贝叶斯定理的分类算法,广泛应用于文本分类、垃圾邮件过滤、情感分析等领域。
- 它的“朴素”之处在于它假设特征之间相互独立,尽管在实际情况中特征往往存在相关性,但朴素贝叶斯算法依然能在很多场景下取得不错的效果。
二、贝叶斯定理
-
P
(
A
∣
B
)
=
P
(
B
∣
A
)
⋅
P
(
A
)
P
(
B
)
P(A \mid B) = \frac{P(B∣A) \cdot P(A)}{P(B )}
P(A∣B)=P(B)P(B∣A)⋅P(A)
- P ( A ∣ B ) P(A∣B) P(A∣B) 是已知 B B B 发生的情况下 A 发生的概率(后验概率)
- P ( B ∣ A ) P(B∣A) P(B∣A)是已知 A A A 发生的情况下 B 发生的概率(似然度)
- P ( A ) P(A) P(A) 是 A A A 发生的概率(先验概率)
- P ( B ) P(B) P(B)是 B B B 发生的概率(边缘概率)
三、朴素贝叶斯分类器
- 1、在分类问题中,我们希望根据输入特征向量 X = ( x 1 , x 2 , x 3 , . . . , x n ) X = (x_1, x_2,x_3,...,x_n) X=(x1,x2,x3,...,xn) 来预测类别 C k C_k Ck
- 2、朴素贝叶斯分类器的目标是找到后验概率最大的类别
C
k
C_k
Ck :
- C ^ = a r g m a x C k P ( C k ∣ X ) \hat{C}=argmax_{C_k}P(C_k \mid X) C^=argmaxCkP(Ck∣X)
- 3、根据贝叶斯定理:
-
P ( C k ∣ X ) = P ( X ∣ C k ) ⋅ P ( C k ) P ( X ) P(C_k \mid X) = \frac{P(X∣C_k) \cdot P(C_k)}{P(X )} P(Ck∣X)=P(X)P(X∣Ck)⋅P(Ck)
- P ( C k ) P(C_k) P(Ck) 是类别 C k C_k Ck 的先验概率
- P ( X ∣ C k ) P(X \mid C_k) P(X∣Ck) 是给定类别 C k C_k Ck 的时特征向量 X 的条件概率
- P ( X ) P(X) P(X)是特征向量 X 的边缘概率
-
- 4、由于
P
(
X
)
P(X)
P(X) 对所有类别
C
k
C_k
Ck 都是相同的,因此在最大化
P
(
C
k
∣
X
)
P(C_k \mid X)
P(Ck∣X) 时可以忽略它:
- C ^ = a r g m a x C k [ P ( X ∣ C k ) ⋅ P ( C k ) ] \hat{C}=argmax_{C_k}[P(X \mid C_k)\cdot P(C_k)] C^=argmaxCk[P(X∣Ck)⋅P(Ck)]
- 5、由于假设独立性,也就是朴素贝叶斯算法:特征之间相互独立
- P ( C k ∣ X ) = ∏ i = 1 n P ( x i ∣ C k ) P(C_k \mid X) = \prod_{i=1}^n P(x_i\mid C_k) P(Ck∣X)=∏i=1nP(xi∣Ck)
- 这意味着每个特征 x i x_i xi 对类别 C k C_k Ck 的条件概率只取决于自身,而不受其他特征的影响。这一假设简化了模型,使得计算变得更为简单。
- 6、然而,在实际应用中,训练集中可能会出现某些特征的概率
P
P
P 为 0 的情况,这在统计学上不太合理,因为不能仅因一个事件未被观察到就断定其概率为 0。因此,拉普拉斯平滑系数被引入来解决这一问题。
- 拉普拉斯平滑处理的思想是将样本值加上一个常数(通常是1),以对数据集进行平滑处理,从而避免概率为 0 的情况。使用拉普拉斯平滑处理后的概率计算公式为:
- P ( X ∣ C k ) = N i + a l p h a N + a l p h a ⋅ M P(X\mid C_k) = \frac{N_i + alpha}{N + alpha \cdot M } P(X∣Ck)=N+alpha⋅MNi+alpha
- 其中, P ( X ∣ C k ) P(X \mid C_k) P(X∣Ck) 表示在给定类别 C k C_k Ck 的条件下,特征 X X X 出现的概率; N i N_i Ni 表示在类别 C k C_k Ck 中特征 X X X 出现的次数; N N N 表示类别 C k C_k Ck 中所有特征出现的总次数; M M M 表示训练文档中统计出来的特征词的个数; a l p h a alpha alpha 是指定的拉普拉斯平滑系数,一般取值为1。
四、训练过程
- 在训练阶段,我们需要估计每个类别的先验概率 P ( C k ) P (C_k) P(Ck) 和每个特征在各个类别下的条件概率 P ( x i ∣ C k ) P(x_i \mid C_k) P(xi∣Ck)
第一步:计算计算先验概率
- 对于每个类别 C k C_k Ck ,计算其在训练集中的出现频率
第二步:计算条件概率
- 对于每个特征 x i x_i xi计算其在各个类别下的条件概率分布。这可以通过统计每个特征值在各类别中的频率来完成。
五、模型预测
- 在预测阶段,对于新的特征向量 X X X 计算每个类别的后验概率,并选择后验概率最大的类别作为预测结果。
六、常见变体
6.1 高斯朴素贝叶斯(Gaussian Naive Bayes):
- 适用场景:
- 适用于特征属性为连续变量,且这些变量可能服从高斯(正态)分布的数据集。
- 工作原理:
- 高斯朴素贝叶斯假设每个特征在每个类别下都服从高斯分布,通过计算每个特征在每个类别下的均值和方差来估计条件概率。
- 特点:
- 对于连续变量数据表现良好,能够处理具有不同尺度(scale)和分布的特征。
6.2 多项式朴素贝叶斯(Multinomial Naive Bayes):
- 适用场景:
- 适用于特征属性为离散变量,特别是计数数据(如词频)的数据集,常用于文本分类。
- 工作原理:
- 多项式朴素贝叶斯基于多项式分布来计算特征在每个类别下的条件概率,它考虑了特征出现的次数。
- 特点:
- 对于文本数据(如单词计数)表现良好,能够处理具有稀疏性(即许多特征值为零)的数据。
6.3 伯努利朴素贝叶斯(Bernoulli Naive Bayes):
- 适用场景:
- 适用于特征属性为布尔值(0或1)的数据集,即每个特征只有两种可能的取值。
- 工作原理:
- 伯努利朴素贝叶斯假设每个特征在每个类别下都服从伯努利分布,即特征取值为1(出现)或0(不出现)的概率是独立的。
- 特点:
- 对于二元特征数据表现良好,能够处理具有大量缺失值或零值的数据,因为它只关心特征是否出现,而不关心出现的次数
6.4 CategoricalNB(类别朴素贝叶斯):
- 适用场景:
- CategoricalNB通常用于离散数据集,特别是当特征属性是分类变量(如类别标签)时。
- 工作原理:
- CategoricalNB通过计算每个特征在每个类别下的条件概率来进行分类。它假设每个特征都服从一个分类分布,并使用平滑参数(如拉普拉斯平滑)来避免零概率问题。
- 特点:
- 可以处理具有多个类别的分类任务。对数据的输入格式有一定要求,通常需要将分类特征编码为整数或字符串数组。
6.5 ComplementNB(补充朴素贝叶斯):
- 适用场景:
- 特别适用于不平衡数据集上的分类任务,尤其是当特征属性为离散变量时(如文本分类)。
- 工作原理:
- 补充朴素贝叶斯通过计算补数(即不属于某个类别的特征计数)来改进模型的权重估计,从而在处理不平衡数据集时更加稳定。
- 特点:
- 在不平衡数据集上通常比多项式朴素贝叶斯表现更好,因为它考虑了每个类别中未出现的特征。
七、优缺点
7.1 优点
- 简单快速:计算复杂度较低,易于实现
- 较少的训练数据:即使在数据量有限的情况下也能取得不错的性能
- 线性模型:可以很好地处理高维数据
7.2 缺点
- 独立性假设:在现实中特征往往是相关的,这一假设有时会导致预测不准确
- 零概率问题:某些特征在训练集中未出现,导致其条件概率为零,影响预测结果。可以通过平滑技术(如拉普拉斯平滑)来解决这一问题
八、应用场景
- 文本分类:新闻分类、情感分析
- 垃圾邮件过滤:标记电子邮件是否为垃圾邮件
- 医学诊断:基于症状预测疾病
- 推荐系统:根据用户的偏好推荐商品
九、举例说明
9.1 训练数据
短信内容 | 类别 |
---|---|
你好,很高兴见到你 | 正常 |
优惠券领取 | 垃圾 |
明天见 | 正常 |
赠送礼品 | 垃圾 |
谢谢你的回复 | 正常 |
点击链接获取大奖 | 垃圾 |
限时折扣 | 促销 |
新品上市 | 促销 |
欢迎再次光临 | 正常 |
9.2 训练阶段
9.2.1 计算先验概率
- 我们需要计算每个类别的先验概率。
- 总共的短信数量:
N
=
9
N = 9
N=9
- “正常”短信的数量: N 正常 = 4 N_{正常}=4 N正常=4
- “垃圾”短信的数量: N 垃圾 = 3 N_{垃圾}=3 N垃圾=3
- “促销”短信的数量: N 促销 = 2 N_{促销}=2 N促销=2
- 总共的短信数量:
N
=
9
N = 9
N=9
- 因此
- “正常”的先验概率: P ( 正常 ) = 4 9 ≈ 0.444 P(正常)=\frac{4} {9} \approx 0.444 P(正常)=94≈0.444
- “垃圾”的先验概率: P ( 垃圾 ) = 3 9 ≈ 0.333 P(垃圾)=\frac{3} {9} \approx 0.333 P(垃圾)=93≈0.333
- “促销”的先验概率: P ( 促销 ) = 2 9 ≈ 0.222 P(促销)=\frac{2} {9} \approx 0.222 P(促销)=92≈0.222
9.2.2 计算条件概率
-
接下来,我们需要计算每个单词在各个类别中的条件概率
-
1、首先,我们要对“正常”短信进行分词
- “正常”短信的数量: N 正常 = 4 N_{正常}=4 N正常=4
- “正常”短信中的总单词数: N 正常 = 12 N_{正常}=12 N正常=12(每个短信的单词数之和)
- 具体统计如下:
- “你好”:出现 1 次
- “高兴”:出现 1 次
- “见到”:出现 1 次
- “你”:出现 2 次
- “明天”:出现 1 次
- “见”:出现 1 次
- “谢谢”:出现 1 次
- “回复”:出现 1 次
- “欢迎”:出现 1 次
- “再次”:出现 1 次
- “光临”:出现 1 次
-
2、其次,对“垃圾”短信进行分词
- “正常”短信的数量: N 垃圾 = 3 N_{垃圾}=3 N垃圾=3
- “正常”短信中的总单词数: N 垃圾 = 8 N_{垃圾}=8 N垃圾=8(每个短信的单词数之和)
- 具体统计如下:
- “优惠券”:出现 1 次
- “领取”:出现 1 次
- “赠送”:出现 1 次
- “礼品”:出现 1 次
- “点击”:出现 1 次
- “链接”:出现 1 次
- “获取”:出现 1 次
- “大奖”:出现 1 次
-
3、最后,对“促销”短信进行分词
- “正常”短信的数量: N 垃圾 = 2 N_{垃圾}=2 N垃圾=2
- “正常”短信中的总单词数: N 垃圾 = 4 N_{垃圾}=4 N垃圾=4(每个短信的单词数之和)
- 具体统计如下:
- “限时”:出现 1 次
- “折扣”:出现 1 次
- “新品”:出现 1 次
- “上市”:出现 1 次
9.2.2.1 计算“正常”类别中的条件概率
- 你好: P ( 你好 ∣ 正常 ) = 1 12 P(你好 \mid 正常) = \frac{1} {12} P(你好∣正常)=121
- 高兴 : P ( 高兴 ∣ 正常 ) = 1 12 P(高兴 \mid 正常) = \frac{1} {12} P(高兴∣正常)=121
- 见到 : P ( 见到 ∣ 正常 ) = 1 12 P(见到 \mid 正常) = \frac{1} {12} P(见到∣正常)=121
- 你: P ( 你 ∣ 正常 ) = 2 12 = 1 6 P(你 \mid 正常) = \frac{2} {12}=\frac{1} {6} P(你∣正常)=122=61
- 明天 : P ( 明天 ∣ 正常 ) = 1 12 P(明天 \mid 正常) = \frac{1} {12} P(明天∣正常)=121
- 见 : P ( 见 ∣ 正常 ) = 1 12 P(见 \mid 正常) = \frac{1} {12} P(见∣正常)=121
- 谢谢 : P ( 谢谢 ∣ 正常 ) = 1 12 P(谢谢 \mid 正常) = \frac{1} {12} P(谢谢∣正常)=121
- 回复 : P ( 回复 ∣ 正常 ) = 1 12 P(回复 \mid 正常) = \frac{1} {12} P(回复∣正常)=121
- 欢迎 : P ( 欢迎 ∣ 正常 ) = 1 12 P(欢迎 \mid 正常) = \frac{1} {12} P(欢迎∣正常)=121
- 再次 : P ( 再次 ∣ 正常 ) = 1 12 P(再次 \mid 正常) = \frac{1} {12} P(再次∣正常)=121
- 光临 : P ( 光临 ∣ 正常 ) = 1 12 P(光临 \mid 正常) = \frac{1} {12} P(光临∣正常)=121
9.2.2.2 计算“垃圾”类别中的条件概率
- 优惠卷: P ( 优惠卷 ∣ 垃圾 ) = 1 8 P(优惠卷\mid 垃圾) = \frac{1} {8} P(优惠卷∣垃圾)=81
- 领取: P ( 领取 ∣ 垃圾 ) = 1 8 P(领取 \mid 垃圾) = \frac{1} {8} P(领取∣垃圾)=81
- 赠送: P ( 赠送 ∣ 垃圾 ) = 1 8 P(赠送 \mid 垃圾) = \frac{1} {8} P(赠送∣垃圾)=81
- 礼品: P ( 礼品 ∣ 垃圾 ) = 1 8 P(礼品\mid 垃圾) = \frac{1} {8} P(礼品∣垃圾)=81
- 点击: P ( 点击 ∣ 垃圾 ) = 1 8 P(点击 \mid 垃圾) = \frac{1} {8} P(点击∣垃圾)=81
- 链接: P ( 链接 ∣ 垃圾 ) = 1 8 P(链接\mid 垃圾) = \frac{1} {8} P(链接∣垃圾)=81
- 获取: P ( 获取 ∣ 垃圾 ) = 1 8 P(获取\mid 垃圾) = \frac{1} {8} P(获取∣垃圾)=81
- 大奖: P ( 大奖 ∣ 垃圾 ) = 1 8 P(大奖\mid 垃圾) = \frac{1} {8} P(大奖∣垃圾)=81
9.2.2.3 计算“促销”类别中的条件概率
- 限时: P ( 限时 ∣ 促销 ) = 1 4 P(限时\mid 促销) = \frac{1} {4} P(限时∣促销)=41
- 折扣: P ( 折扣 ∣ 促销 ) = 1 4 P(折扣\mid 促销) = \frac{1} {4} P(折扣∣促销)=41
- 新品: P ( 新品 ∣ 促销 ) = 1 4 P(新品\mid 促销) = \frac{1} {4} P(新品∣促销)=41
- 上市: P ( 上市 ∣ 促销 ) = 1 4 P(上市\mid 促销) = \frac{1} {4} P(上市∣促销)=41
9.2.2 预测阶段
- 假设我们收到一条新的短信:“点击链接获取礼品”,我们预测这条短信属于什么类型的短信。
9.2.2.1 计算后验概率
-
我们需要计算这条短信属于“正常”、“垃圾”和“促销”类别的后验概率。
-
1、计算 P ( 正常 ∣ 短信 ) P(正常\mid短信) P(正常∣短信)
-
1.1 、 P ( 正常 ∣ 短信 ) ∝ P ( 正常 ) P(正常\mid短信) ∝ P(正常) P(正常∣短信)∝P(正常) X P ( 点击 ∣ 正常 ) P(点击\mid正常) P(点击∣正常) X P ( 链接 ∣ 正常 ) P(链接\mid正常) P(链接∣正常) X P ( 获取 ∣ 正常 ) P(获取\mid正常) P(获取∣正常) X P ( 礼品 ∣ 正常 ) P(礼品\mid正常) P(礼品∣正常)
-
1.2、由于“点击”、“链接”、“获取”和“礼品”在“正常”类别中没有出现,我们假设每个单词至少出现了一次(也就是拉普拉斯平滑,alpha取默认值 = 1),即:
- P ( 点击 ∣ 正常 ) P(点击\mid正常) P(点击∣正常) = P ( 链接 ∣ 正常 ) P(链接\mid正常) P(链接∣正常) = P ( 获取 ∣ 正常 ) P(获取\mid正常) P(获取∣正常) = P ( 礼品 ∣ 正常 ) P(礼品\mid正常) P(礼品∣正常) = 0 + 1 12 + 1 ⋅ M \frac{0+1}{12+1 \cdot M} 12+1⋅M0+1
- 其中
M
M
M 是词汇表大小(假设为 14),因此:
- P ( 点击 ∣ 正常 ) P(点击\mid正常) P(点击∣正常) = P ( 链接 ∣ 正常 ) P(链接\mid正常) P(链接∣正常) = P ( 获取 ∣ 正常 ) P(获取\mid正常) P(获取∣正常) = P ( 礼品 ∣ 正常 ) P(礼品\mid正常) P(礼品∣正常) = 1 26 \frac{1}{26} 261
-
1.3、因此:
- P ( 正常 ∣ 短信 ) ∝ 4 9 P(正常\mid短信) ∝ \frac{4} {9} P(正常∣短信)∝94 X ( 1 26 ) 4 = 1 1028196 (\frac{1} {26})^4 = \frac{1}{1028196} (261)4=10281961
-
-
2、计算 P ( 垃圾 ∣ 短信 ) P(垃圾\mid短信) P(垃圾∣短信)
-
2.1 、 P ( 垃圾 ∣ 短信 ) ∝ P ( 垃圾 ) P(垃圾\mid短信) ∝ P(垃圾) P(垃圾∣短信)∝P(垃圾) X P ( 点击 ∣ 垃圾 ) P(点击\mid垃圾) P(点击∣垃圾) X P ( 链接 ∣ 垃圾 ) P(链接\mid垃圾) P(链接∣垃圾) X P ( 获取 ∣ 垃圾 ) P(获取\mid垃圾) P(获取∣垃圾) X P ( 礼品 ∣ 垃圾 ) P(礼品\mid垃圾) P(礼品∣垃圾)
-
2.2、使用拉普拉斯平滑,alpha取默认值 = 1
- P ( 点击 ∣ 垃圾 ) P(点击\mid垃圾) P(点击∣垃圾) = P ( 链接 ∣ 垃圾 ) P(链接\mid垃圾) P(链接∣垃圾) = P ( 获取 ∣ 垃圾 ) P(获取\mid垃圾) P(获取∣垃圾) = P ( 礼品 ∣ 垃圾 ) P(礼品\mid垃圾) P(礼品∣垃圾) = 1 + 1 8 + 1 ⋅ M \frac{1+1}{8+1 \cdot M} 8+1⋅M1+1
- 其中
M
M
M 是词汇表大小(假设为 14),因此:
- P ( 点击 ∣ 垃圾 ) P(点击\mid垃圾) P(点击∣垃圾) = P ( 链接 ∣ 垃圾 ) P(链接\mid垃圾) P(链接∣垃圾) = P ( 获取 ∣ 垃圾 ) P(获取\mid垃圾) P(获取∣垃圾) = P ( 礼品 ∣ 垃圾 ) P(礼品\mid垃圾) P(礼品∣垃圾) = P ( 礼品 ∣ 正常 ) P(礼品\mid正常) P(礼品∣正常) = 1 11 \frac{1}{11} 111
-
2.3、因此:
- P ( 垃圾 ∣ 短信 ) ∝ 3 9 P(垃圾\mid短信) ∝ \frac{3} {9} P(垃圾∣短信)∝93 X ( 1 11 ) 4 = 1 43926 (\frac{1} {11})^4 = \frac{1}{43926} (111)4=439261
-
-
3、计算 P ( 促销 ∣ 短信 ) P(促销\mid短信) P(促销∣短信)
-
3.1 、 P ( 促销 ∣ 短信 ) ∝ P ( 促销 ) P(促销\mid短信) ∝ P(促销) P(促销∣短信)∝P(促销) X P ( 点击 ∣ 促销 ) P(点击\mid促销) P(点击∣促销) X P ( 链接 ∣ 促销 ) P(链接\mid促销) P(链接∣促销) X P ( 获取 ∣ 促销 ) P(获取\mid促销) P(获取∣促销) X P ( 礼品 ∣ 促销 ) P(礼品\mid促销) P(礼品∣促销)
-
3.2、由于“点击”、“链接”、“获取”和“礼品”在“促销”类别中没有出现,我们假设每个单词至少出现了一次(也就是拉普拉斯平滑,alpha取默认值 = 1),即:
- P ( 点击 ∣ 促销 ) P(点击\mid促销) P(点击∣促销) = P ( 链接 ∣ 促销 ) P(链接\mid促销) P(链接∣促销) = P ( 获取 ∣ 促销 ) P(获取\mid促销) P(获取∣促销) = P ( 礼品 ∣ 促销 ) P(礼品\mid促销) P(礼品∣促销) = 0 + 1 4 + 1 ⋅ M \frac{0+1}{4+1 \cdot M} 4+1⋅M0+1
- 其中
M
M
M 是词汇表大小(假设为 14),因此:
- P ( 点击 ∣ 促销 ) P(点击\mid促销) P(点击∣促销) = P ( 链接 ∣ 促销 ) P(链接\mid促销) P(链接∣促销) = P ( 获取 ∣ 促销 ) P(获取\mid促销) P(获取∣促销) = P ( 礼品 ∣ 促销 ) P(礼品\mid促销) P(礼品∣促销) = 1 18 \frac{1}{18} 181
-
3.3、因此:
- P ( 促销 ∣ 短信 ) ∝ 2 9 P(促销\mid短信) ∝ \frac{2} {9} P(促销∣短信)∝92 X ( 1 18 ) 4 = 1 472392 (\frac{1} {18})^4 = \frac{1}{472392} (181)4=4723921
-
9.2.2.2 比较后验概率
-
比较三个后验概率:
- P ( 正常 ∣ 短信 ) ∝ 1 1028196 P(正常\mid短信) ∝ \frac{1}{1028196} P(正常∣短信)∝10281961
- P ( 垃圾 ∣ 短信 ) ∝ 1 43926 P(垃圾\mid短信) ∝ \frac{1}{43926} P(垃圾∣短信)∝439261
- P ( 促销 ∣ 短信 ) ∝ 1 472392 P(促销\mid短信) ∝ \frac{1}{472392} P(促销∣短信)∝4723921
-
显然
- 1 1028196 < 1 43926 > 1 472392 \frac{1}{1028196}< \frac{1}{43926}>\frac{1}{472392} 10281961<439261>4723921
-
因此,这条短信更可能是“垃圾”。
十、代码演示
代码演示:
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 # 多项式分布朴素贝叶斯
def my_naive_bayes():
# 1. 获取数据
# 因为pd.read_csv默认的码表是utf-8,这里的数据 编码是 gbk 所以要指定码表
data = pd.read_csv('./data/书籍评价.csv', encoding='gbk')
# print(data)
# 2. 数据的基本处理
# - 2.1 取出内容列,对数据进行分析
content = data["内容"]
# - 2.2 判定评判标准 -- 新加列来表示 好评和差评: 1好评;0差评
data.loc[data.loc[:, '评价'] == "好评", '评论标号'] = 1 # 把好评修改为1
data.loc[data.loc[:, '评价'] == '差评', '评论标号'] = 0 # 把差评修改为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:
# 对文本数据进行切割
# cut_all 参数默认为 False,所有使用 cut 方法时默认为精确模式
seg_list = jieba.cut(tmp, cut_all=False)
# print(seg_list) # <generator object Tokenizer.cut at 0x0000000007CF7DB0>
seg_str = ','.join(seg_list) # 拼接字符串
# print(seg_str)
comment_list.append(seg_str) # 目的是转化成列表形式
# 上述内容的合并写法
# comment_list = [','.join(jieba.lcut(line)) for line in data['内容']]
# - 2.5 统计词的个数
# 进行统计词个数
# 实例化对象
# CountVectorizer 类会将文本中的词语转换为词频矩阵
con = CountVectorizer(stop_words=stopwords)
# 进行词数统计
X = con.fit_transform(comment_list) # 它通过 fit_transform 函数计算各个词语出现的次数
name = con.get_feature_names_out() # 通过 get_feature_names_out()可获取词袋中所有文本的关键字
# print(X.toarray()) # 通过 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. 模型训练
# 构建贝叶斯算法分类器
estimator = MultinomialNB(alpha=1) # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参数
# 训练数据
estimator.fit(x_train, y_train)
# 预测数据
y_predict = estimator.predict(x_text)
# 预测值与真实值展示
print(f'预测值:{y_predict}, 好评1 差评0')
print(f'真实值:{y_text}, 好评1 差评0')
# 4. 模型评估
score = estimator.score(x_text, y_text)
print(f'模型的准确率为{score}')
if __name__ == '__main__':
my_naive_bayes()
总结
- 我们对机器学习中的朴素贝叶斯算法进行了详细的讲解,代码演示中的文件比较小,所以可能会出现过拟合的情况,在这里我们不与讨论。