【机器学习 | 第八篇】- 朴素贝叶斯

前言

朴素贝叶斯作为概率论中的概念,通过对文本内容的训练,可以概率的方式进行情感分析!

一、概率基础复习

1.1 条件概率

  • 定义:在事件 B 已经发生的条件下,事件 A 发生的概率,记作 P(A∣B)。
  • 公式

1.2 联合概率

  • 定义:多个事件同时发生的概率,记作 P(AB)。
  • 一般公式:P(AB)=P(A)⋅P(B∣A)=P(B)⋅P(A∣B)。
  • 独立事件:若 A 与 B 独立,则 P(AB)=P(A)P(B)。

1.3 条件概率与联合概率示例

根据示例数据表(包含职业、体型、是否喜欢)

  • P(程序员∣喜欢)=2/4=0.5
  • P(程序员且匀称)=3/7×1/3=1/7
  • P(程序员且超重∣喜欢)=0.5×0.5=0.25(在独立假设下)

二、贝叶斯公式

2.1 公式

数学公式

等同于:

注释

  • P (C ):先验概率(没有观察到任何特征(证据)的情况下 ,类别 C 在样本空间中出现的概率)

  • P(W∣C):似然/条件概率(已知样本属于类别 C 的条件下,该样本具有特征 W 的概率)

  • P(W):证据/全局概率(在整个样本集中,特征 W 出现的概率

  • P(C∣W):后验概率(已知特征 W,样本属于类别 C 的概率)

核心逻辑 :通过先验概率 + 条件概率,推导后验概率,实现样本分类。

2.2 示例

三、朴素贝叶斯

朴素贝叶斯的核心思想可以概括为:利用贝叶斯定理计算后验概率,并假设特征之间相互独立以简化计算。它通过统计先验和条件概率,实现对样本的分类。虽然独立假设在现实中可能不成立,但其简单高效和较好的性能使其成为机器学习中的经典算法之一,特别适合文本分类等任务。

3.1 特征条件独立假设

如果特征不止一个(比如既有天气,又有温度、湿度),那么计算似然概率

会非常复杂,因为需要知道特征之间的联合分布。为了简化计算,朴素贝叶斯引入了一个强假设所有特征在给定类别的条件下相互独立

即:

  • P(程序员,超重∣喜欢) = P(程序员∣喜欢)⋅P(超重∣喜欢)

  • P(程序员,超重) = P(程序员)⋅P(超重)

这个假设称为"朴素"(naive),因为在现实中特征往往并不独立(例如"晴天"和"高温"可能相关),但实践表明它仍然能取得不错的效果。

为什么这样假设?
  • 将联合概率分解为多个边缘概率的乘积,大大简化了计算。
  • 每个
    可以独立地从训练数据中统计得到,避免了高维联合分布估计的困难。

3.2 拉普拉斯平滑(也称为加一平滑)

  • 问题:若某特征在训练集中未出现,则概率为 0,导致后验概率为 0,影响分类。
  • 解决:引入拉普拉斯平滑系数 α(通常取 1):

等同于:

注释

核心逻辑

它主要解决的是**"零概率问题"------ 当某个特征在训练集中从未出现过时,直接计算为 0 会导致整个模型预测失效,平滑机制可以给它一个很小的非零值。避免零概率,保证所有特征都有非零概率。**

核心原理(为什么要这么写?)

1. 为什么要加 α?(解决零概率)

如果不加分,当 =0(没见过这个词)时,概率会变成 0。这会导致后续的乘积计算变成 0,模型无法判断。加上 α(通常取 1),就是给这个没见过的词留一条活路,让它拥有一个极小的概率。

2. 为什么分母要乘 m?(归一化保证和为 1)
  • 不加 m 时:
    ,这会导致该类别下所有概率之和 ≠1。
  • 加上 m 后:相当于给每一个特征 (哪怕是没见过的)都预先分配了一个
    的概率,保证所有可能的特征概率之和为 1,符合概率定义。

3.3 朴素贝叶斯的三种常见变体

根据特征分布假设的不同,朴素贝叶斯有以下几种常用模型:

模型 适用特征 假设 典型应用
高斯朴素贝叶斯 连续特征 特征服从高斯分布(正态分布) 身高、体重等连续值分类
多项式朴素贝叶斯 离散特征(计数) 特征服从多项分布 文本分类(词频)
伯努利朴素贝叶斯 布尔特征(0/1) 特征服从伯努利分布 文本分类(词是否出现)
  • 多项式朴素贝叶斯 是最常用的文本分类模型,因为它能很好地处理词频。
  • 高斯朴素贝叶斯 适用于连续特征,如鸢尾花数据集。
  • 伯努利朴素贝叶斯 适合特征为二值的情况,如"是否包含某词"。

3.4 朴素贝叶斯的优缺点

优点

  • 算法简单,易于实现:只需要统计先验和条件概率。
  • 训练速度快:一次扫描数据即可完成统计。
  • 对小规模数据表现良好:不需要大量训练样本。
  • 可解释性强:分类结果基于概率,可以给出置信度。
  • 适合多分类任务:天然支持多类别。

缺点

  • 特征独立假设在现实中往往不成立,可能导致概率估计偏差。
  • 对输入数据的表达形式敏感:例如连续特征需假设分布。
  • 零概率问题需要平滑处理(已通过拉普拉斯解决)。

四、朴素贝叶斯 API 及案例

4.1 API 介绍(sklearn)

python 复制代码
from sklearn.naive_bayes import MultinomialNB

model = MultinomialNB(alpha=1.0)
  • alpha:拉普拉斯平滑系数,默认 1.0。
  • 适用于离散特征(如文本分类中的词频)。

4.2 案例:商品评论情感分析

需求:根据评论内容判断是好评还是差评。

4.2.1 需求说明

任务目标

利用已有的商品评论数据(包含评论文本和对应的情感标签),训练一个文本分类模型,使其能够自动判断新的评论是好评还是差评。这是一个典型的二分类问题。

数据概况

  • 数据来源:书籍评价.csv(样本片段共13条,实际完整数据可能更多)

  • 字段:

    • 内容:评论的文本内容(中文)
    • 评价:情感标签("好评"或"差评")
  • 数据特点:文本长度不一,包含口语化表达、标点符号等;标签为二值类别。

业务意义

帮助电商平台或内容网站自动分析用户反馈,量化产品口碑,及时发现负面评价,辅助产品改进和运营决策。

4.2.2 处理思维流程

1. 数据加载与理解

  • 读取CSV文件,查看数据结构和样本分布(好评、差评各自数量)。
  • 检查是否存在缺失值或空文本,若有则进行剔除或填充。

2. 文本预处理

  • 标签编码:将"好评"映射为1,"差评"映射为0(或其他数值),便于模型计算。
  • 文本清洗:去除无关符号(如标点、数字、特殊字符),统一大小写(英文),但中文需保留汉字。
  • 分词:使用中文分词工具(如jieba)将评论文本切分成词语序列。
  • 去停用词:加载停用词表,过滤掉"的"、"了"、"是"等无实际意义的词语,减少噪声。

3. 特征提取

  • 将分词后的文本转换为数值特征向量,常用方法:

    • 词袋模型(CountVectorizer):统计每个词在文档中出现的次数。
    • TF-IDF(可选):不仅考虑词频,还考虑词语在整个语料中的稀有程度,可提升效果。
  • 注意:特征维度可能较高,但朴素贝叶斯对此有较好的适应性。

4. 数据集划分

  • 将数据划分为训练集测试集(例如80%训练,20%测试)。
  • 由于数据量可能较小,可采用分层采样stratify)确保训练/测试集中正负样本比例与原始数据一致。
  • 若数据极少,可考虑交叉验证。

5. 模型选择与训练

  • 选择朴素贝叶斯 分类器,具体为多项式朴素贝叶斯(MultinomialNB),因为它适合离散计数特征(如词频)。
  • 设置拉普拉斯平滑系数(alpha,默认1.0)避免零概率问题。
  • 用训练集拟合模型。

6. 模型评估

  • 在测试集上进行预测,输出分类报告 (精确率、召回率、F1-score)和混淆矩阵,评估模型对好评和差评的识别能力。
  • 若数据不平衡,可重点关注少数类的召回率。
  • 也可计算准确率,但需结合其他指标综合判断。

7. 模型优化(可选)

  • 调整特征提取参数(如ngram_range、max_features)。
  • 尝试不同的分词工具或停用词表。
  • 若效果不佳,可考虑其他模型(如支持向量机、逻辑回归),但朴素贝叶斯在文本分类中通常表现良好且高效。

8. 模型保存与应用

  • 将训练好的模型和向量化器保存为文件(如.pkl),便于后续对新评论进行实时预测。
  • 部署时可封装为API,接收文本返回情感类别。

4.2.2 代码实现

python 复制代码
# 导入必要的包
import re # 导入正则表达式包
import pandas as pd # 导入数据处理包
import jieba # 导入分词包"结巴"
from sklearn.feature_extraction.text import CountVectorizer # 导入词频统计工具
from sklearn.naive_bayes import MultinomialNB # 导入朴素贝叶斯对象
from sklearn.metrics import (classification_report, # 评价报告包
                             confusion_matrix) # 混淆矩阵包
from sklearn.model_selection import train_test_split # 导入数据集划分工具
import pickle # 导入pickle包

##### 1. 数据加载与理解
# 读取数据
data = pd.read_csv(r'file/书籍评价.csv', encoding='gbk') # 文件内容是中文,在win系统下需要GBK编码
# 查看数据结构和样本分布(好评、差评各自数量)
print("数据结构:",data.shape) # 样本结构:(13行, 3列)
print("字段信息:", data.info())
print("样本分布:\n",data['评价'].value_counts())

# 检查是否存在缺失值或空文本,若有则进行剔除或填充。
print("缺失值:", data.loc[:,data.isnull().any()].sum()) # 仅显示有缺失值的字段
print("重复值:", data.duplicated().sum())
# # 缺失值处理,若存在缺失,采用中位数填充或删除。
# data.fillna(data.median(), inplace=True)
# # 删除重复行
# data.drop_duplicates(inplace=True)
print("数据预览:\n", data.head())

##### 2. 文本预处理
### 标签映射编码:
# 将"好评"映射为1,"差评"映射为0(或其他数值),便于模型计算。
data['标签'] = data['评价'].apply(lambda x: 1 if x == '好评' else 0) # 映射标签
print("标签映射:\n", data.head())

### 文本清洗:
# 去除无关符号(如标点、数字、特殊字符),统一大小写(英文),但中文需保留汉字。
# 保留中文字符、英文字母,将其他字符替换为空格
# 中文字符范围:\u4e00-\u9fff
# 英文字母:a-zA-Z
# 使用re.sub,将不匹配保留字符的任意字符替换为空格
cleaned = data['内容'].apply(lambda x: re.sub(r"[^a-zA-Z\u4e00-\u9fff]", " ", x))
# 将英文字母转为小写
cleaned = cleaned.apply(lambda x: x.lower())
# 合并多个空格为一个空格
cleaned = cleaned.apply(lambda x: re.sub(r"\s+", " ", x).strip())
data['内容'] = cleaned
print("文本清洗:\n", data.head())

### 文本分词:
# 对用户的评论信息,做切词
comment_list = []
for line in data['内容']:
    # 对每一行进行切词
    result = jieba.lcut(line)
    comment_list.append(' '.join(result))
print("文本分词:\n", comment_list)

### 去停用词:加载停用词表,过滤掉"的"、"了"、"是"等无实际意义的词语,减少噪声。
with open('file/stopwords.txt', encoding='utf-8') as f:
    stopwords_list = f.readlines() # 逐行读取文件
    stopwords_list = [x.strip() for x in stopwords_list] # 去掉换行符
    stopwords_list = list(set(stopwords_list)) # 去重
    print("停用词:\n", stopwords_list)

### 3.特征提取
# 将分词后的文本转换为数值特征向量,常用方法:
# 词袋模型(CountVectorizer):统计每个词在文档中出现的次数。
# 定义词袋模型吗,创建CountVectorizer对象,参数:停用词列表
transfer = CountVectorizer(stop_words=stopwords_list)
x = transfer.fit_transform(comment_list) # 返回词频矩阵
# print("特征矩阵:\n", x, x.shape) # (13行, 37列)

### 4.数据集划分
# 将数据划分为训练集和测试集(例如80%训练,20%测试)。
x_train, x_test, y_train, y_test = train_test_split(x, data['标签'], train_size=0.8, test_size=0.2, random_state=42)

### 5. 模型选择与训练
# 选择朴素贝叶斯分类器,具体为多项式朴素贝叶斯(MultinomialNB),因为它适合离散计数特征(如词频)。
# 创建贝叶斯对象
bayes = MultinomialNB(alpha=1.0)
# 模型训练
bayes.fit(x_train, y_train)
print("模型训练完成!")
# 模型预测
y_predict = bayes.predict(x_test)
print("预测结果:", y_predict)
print("真实结果:", y_test)
print("准确率:", bayes.score(x_test, y_test))

### 6. 模型评估
# 在测试集上进行预测,
# 输出分类报告(精确率、召回率、F1-score)和混淆矩阵,
# 评估模型对好评和差评的识别能力。
print("分类报告:\n", classification_report(y_test, y_predict))
print("混淆矩阵:\n", confusion_matrix(y_test, y_predict))
print("准确率:", bayes.score(x_test, y_test))

# 测试模型
# 创建测试用例
test_case = ['我非常喜欢这个书,非常推荐给朋友!', '这个书 sucks, 垃圾']
test_case = [' '.join(jieba.lcut(x)) for x in test_case]
test_case = transfer.transform(test_case)
y_predict = bayes.predict(test_case)
print("预测结果:", y_predict)

# 7. 模型调参,意义不大,所以跳过

# 8. 模型保存
pickle.dump(bayes, open('file/商品评论情感分析.pkl', 'wb'))
相关推荐
A 小码农1 小时前
亲测AI智能小助手-IDEA中使用腾讯混元大模型
java·人工智能·intellij-idea
ssdfang2 小时前
Gemini 3.1镜像深度推理实战:解构多模态长视频理解与结构化知识抽取
人工智能·音视频·语音识别
MediaTea2 小时前
人工智能通识课:Matplotlib 绘图基础
人工智能·matplotlib
CoderJia程序员甲2 小时前
GitHub 热榜项目 - 日榜(2026-03-31)
人工智能·ai·大模型·github·ai教程
童园管理札记2 小时前
2026实测|GPT-4.5+Agent智能体:3小时搭建企业级客服系统,附完整源码与部署教程(二)
人工智能·python
fuquxiaoguang2 小时前
Qdrant:为AI构建的高性能向量搜索引擎
人工智能·向量数据库
学术小白人2 小时前
【落幕新闻】2026年计算智能与机器学习国际学术会议在杭启幕 共探领域前沿发展新路径
人工智能·机器学习·能源·rdlink研发家·智能感知·内燃机
兮℡檬,2 小时前
视觉几何(3D->2D,2D->3D)
人工智能·数码相机·计算机视觉
AI服务老曹2 小时前
异构计算与边缘协同:基于 Docker 的企业级 AI 视频中台硬件适配架构
人工智能·docker·音视频