跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Python 基于朴素贝叶斯的中文评价情感分析

中文评价情感分析利用 NLP 技术解决人工处理海量文本效率低的问题。通过 jieba 分词、停用词过滤、CountVectorizer 向量化及 SMOTE 过采样处理类别不平衡,构建多项式朴素贝叶斯模型实现好评差评自动识别。系统支持批量训练与交互式预测,评估指标涵盖精准率与召回率,可直接应用于电商评价分析与客服场景。

虚拟内存发布于 2026/3/29更新于 2026/9/1266 浏览
Python 基于朴素贝叶斯的中文评价情感分析

前言

在电商、本地生活、内容平台等场景中,每天都会产生海量的用户评价文本。人工逐条区分好评 / 差评、挖掘用户痛点效率极低,而通过 NLP + 机器学习技术实现评价情感倾向自动分类,可以帮助商家快速定位产品问题、优化服务体验,也能为平台运营提供数据支撑。

本文将从 0 到 1 完整实现一套中文评价情感分析系统:从原始文本数据预处理、中文分词、停用词过滤,到词向量转换、朴素贝叶斯模型训练,再到解决数据不平衡问题、最终实现用户输入任意评价自动判断好评 / 差评,全程附带代码解析、踩坑记录和真实运行效果,新手也能直接复现。

一、项目整体效果与技术选型

1. 最终实现效果
  1. 支持本地优质评价 / 差评文本批量训练模型
  2. 自动完成中文文本分词、停用词过滤、词向量转换全流程
  3. 针对评价数据常见的类别不平衡问题,通过 SMOTE 过采样优化模型效果
  4. 提供交互式输入功能:输入任意评价文本,实时输出「优质评价」/「差评」的判断结果
  5. 完整的模型评估报告,精准查看模型在训练集 / 测试集的分类效果
2. 核心技术栈
工具 / 库核心用途
jieba中文文本分词,解决中文无天然分词符的核心问题
pandas文本数据读取、结构化处理与数据集整合
scikit-learn数据集切分、词向量转换、朴素贝叶斯模型构建、分类效果评估
imblearn(SMOTE)过采样处理,解决好评 / 差评样本数量严重不平衡的问题
MultinomialNB多项式朴素贝叶斯模型,专为文本分类这类离散特征场景优化
3. 环境准备

执行以下命令一键安装所有依赖:

pip install pandas jieba scikit-learn imbalanced-learn

二、数据准备与文本预处理

1. 数据源说明

本文使用 3 个核心数据文件,和代码放在同一目录下即可:

  • 优质评价.txt:每行一条用户好评文本,作为正样本
  • 差评.txt:每行一条用户差评文本,作为负样本
  • stopword.txt:中文停用词表,包含「的、了、啊、吧」等无情感意义的语气词、连接词,用于过滤噪声
2. 文本读取与中文分词

中文和英文最大的区别是没有天然的空格分隔词,因此第一步必须用分词工具将句子拆分为独立的词语。这里选用最主流的 jieba 分词库,使用精确模式 lcut 完成分词。

import pandas as pd 
import jieba 
# 读取评价文件
cp_content = open(r'差评.txt', encoding='utf-8') 
yz_content = open(r'优质评价.txt', encoding='utf-8') 
# 对差评文本逐行分词
cp_sum = [] 
for line in cp_content: 
    result = jieba.lcut(line) 
    # 过滤空行和分词后仅 1 个词的无意义内容
    if len(result) > 1: 
        cp_sum.append(result) 
# 对优质评价文本逐行分词
yz_sum = [] 
for line in yz_content: 
    yo = jieba.lcut(line) 
    if len(yo) > 1: 
        yz_sum.append(yo) 
# 关闭文件,避免资源泄露(新手易踩坑点)
cp_content.close() 
yz_content.close()
3. 停用词过滤

分词后的结果里包含大量无情感意义的停用词,会干扰模型的特征学习,因此需要过滤掉;同时补充过滤长度≤1 的单字,进一步降低噪声。

# 读取停用词表,转为列表格式(关键修正:直接用 DataFrame 会导致 in 判断失效)
stopwords = pd.read_csv(r'stopword.txt', encoding='utf-8', engine='python') 
stopwords_list = stopwords['stopword'].values.tolist() 
# 定义停用词过滤函数
def stop(contests, stopwords): 
    seg_clear = [] 
    for contest in contests: 
        line_clear = [] 
        for word in contest: 
            # 核心过滤规则:停用词 + 长度≤1 的无意义词
            if word in stopwords or len(word) <= 1: 
                continue 
            line_clear.append(word) 
        seg_clear.append(line_clear) 
    return seg_clear 
# 对分词结果执行停用词过滤
cp_fc_results_clear = stop(cp_sum, stopwords_list) 
yz_fc_results_clear = stop(yz_sum, stopwords_list)
4. 标签标注与数据集合并

监督学习需要为样本标注标签,这里我们定义:优质评价(好评):标签为 0,差评:标签为 1,将两类样本合并为完整的训练数据集,方便后续切分和训练。

# 为样本标注标签
cp_train = pd.DataFrame({'pj':cp_fc_results_clear,'lable':1}) 
yp_train = pd.DataFrame({'pj':yz_fc_results_clear,'lable':0}) 
# 纵向合并两个数据集,得到完整的标注数据集
pj_train = pd.concat([cp_train,yp_train])

三、数据集切分与词向量转换

1. 训练集 / 测试集切分

将数据集按 8:2 的比例切分为训练集和测试集。训练集:用于模型学习特征和拟合。测试集:用于验证模型的泛化能力,避免过拟合。

固定 random_state 保证每次运行的切分结果一致,方便复现效果。

from sklearn.model_selection import train_test_split 
x_train, x_test, y_train, y_test = \ 
train_test_split( 
    pj_train['pj'].values, pj_train['lable'].values, 
    train_size=0.8, random_state=0 
)
2. 文本转词向量(核心步骤)

计算机无法直接处理文本字符串,必须将其转为数值型的向量,这一步就是文本向量化。本文使用 CountVectorizer 词频向量化,核心逻辑是:基于训练集构建高频词库,将每条文本转为「词频向量」,向量的每个维度对应词库中的一个词,值为该词在文本中出现的次数。

# 格式化文本:将分词列表转为空格分隔的字符串,适配 CountVectorizer 的输入格式
words = [] 
for line_index in range(len(x_train)): 
    words.append(' '.join(x_train[line_index])) 
# 导入词向量转换库
from sklearn.feature_extraction.text import CountVectorizer 
# 初始化词向量转换器
vec = CountVectorizer( 
    max_features=1700, # 只保留词频最高的 1700 个词作为词库,降低维度避免过拟合
    lowercase=False, # 中文无需转为小写,关闭该功能
    ngram_range=(1,3) # 同时考虑 1-3 个词的组合,捕捉「物流慢、质量差」这类短语语义
) 
# 核心步骤:fit 基于训练集构建词库,transform 将文本转为词频向量
vec.fit(words) # 仅用训练集构建词库,避免数据泄露
x_train_vec = vec.transform(words) # 训练集转为词向量

注!!!

新手必看踩坑点:***测试集只能用 vec.transform(),绝对不能用 fit_transform()!***否则会用测试集重新构建词库,导致数据泄露,模型评估结果失真。

四、解决核心痛点:类别不平衡问题

从我的运行结果可以看到,电商评价数据存在严重的类别不平衡:

  • 训练集中,优质评价(标签 0)有 2911 条,差评(标签 1)仅 15 条
  • 测试集中,优质评价 725 条,差评仅 7 条

如果直接用不平衡的数据集训练,模型会严重偏向多数类(好评),哪怕全部预测为好评,准确率也能达到 99%,但完全无法识别差评,失去了业务价值。

这里我们用 SMOTE 过采样解决该问题:通过算法合成少数类(差评)的样本,让训练集中两类样本的数量达到平衡,提升模型对差评的识别能力。

# 导入 SMOTE 过采样器
from imblearn.over_sampling import SMOTE 
# 初始化 SMOTE,固定随机种子保证结果可复现
smote = SMOTE(random_state=42) 
# 仅对训练集执行过采样,测试集保持原始分布
x_train_smote, y_train_smote = smote.fit_resample(x_train_vec, y_train)

五、朴素贝叶斯模型训练与效果评估

1. 模型训练

文本分类场景中,多项式朴素贝叶斯 MultinomialNB 是最经典、高效的算法,对离散的词频特征适配性极强,训练速度快,泛化效果好。

# 导入朴素贝叶斯模型
from sklearn.naive_bayes import MultinomialNB 
# 初始化模型,alpha=1 为拉普拉斯平滑,避免出现零概率问题
classifier = MultinomialNB(alpha=1) 
# 用平衡后的训练集训练模型
classifier.fit(x_train_smote, y_train_smote)
2. 模型效果评估

使用 classification_report 输出完整的分类报告,重点关注精准率、召回率、F1-score,不要只看整体准确率(不平衡数据中准确率无参考意义)。

from sklearn import metrics 
# 训练集效果验证
train_pr = classifier.predict(x_train_vec) 
print("训练集分类报告(原始数据预测):") 
print(metrics.classification_report(y_train,train_pr)) 
# 测试集效果验证(核心看泛化能力)
test_words = [] 
for line_index in range(len(x_test)): 
    test_words.append(' '.join(x_test[line_index])) 
test_pr = classifier.predict(vec.transform(test_words)) 
print("测试集分类报告:") 
print(metrics.classification_report(y_test,test_pr))
真实运行结果展示

文章配图

从运行结果可以看到:

  • 模型整体准确率达到 99%,对优质评价的识别效果极佳
  • 经过 SMOTE 过采样后,模型对差评的召回率达到 71%,解决了不平衡数据下少数类完全无法识别的问题
  • 测试集泛化效果稳定
  • 由于差评数据较少,即使通过过拟合,结果仍然不是很理想。可以通过继续爬取差评数据来增加差评的真实数据。增强差评的训练能力

六、交互式预测:输入评价自动判断好评 / 差评

封装预测函数,实现和训练集完全一致的预处理流程,保证预测结果的准确性,同时增加边界处理,避免无效输入导致报错。

def predict_sentiment(text): 
    # 1. 对输入文本执行 jieba 分词
    seg = jieba.lcut(text) 
    # 2. 执行停用词过滤,和训练集预处理规则保持一致
    clear_seg = stop([seg], stopwords_list)[0] 
    # 边界处理:过滤后无有效词汇,返回提示信息
    if not clear_seg: 
        return "无法判断(输入文本过短或无有效词汇)" 
    # 3. 转为词向量,使用训练集构建的词库
    text_vec = vec.transform([' '.join(clear_seg)]) 
    # 4. 模型预测
    pred = classifier.predict(text_vec)[0] 
    # 5. 返回可读性强的结果
    return "优质评价(好)" if pred == 0 else "差评(坏)" 
# 程序入口:用户交互式输入
if __name__ == "__main__": 
    user_input = input("请输入要判断的评价:") 
    result = predict_sentiment(user_input) 
    print(f"判断结果:{result}")

七、新手必看踩坑记录

  1. 停用词判断失效:读取停用词后直接用 DataFrame,没有转为列表,导致 word in stopwords 判断完全失效,必须用.values.tolist() 转为列表格式
  2. 数据泄露问题:测试集使用 fit_transform() 重新构建词库、在全数据集执行过采样,都会导致模型评估结果虚高,正确做法是仅用训练集 fit / 过采样
  3. 文件资源泄露:用 open 打开文件后没有 close,长时间运行会导致句柄泄露,推荐用 with open() 上下文管理器自动管理文件
  4. 预处理流程不一致:预测单条文本时,没有执行和训练集完全一致的分词、停用词过滤规则,导致预测结果出错
  5. 只看准确率:不平衡数据中,哪怕全部预测为多数类,准确率也能达到 99%,必须重点关注少数类的 F1-score 和召回率

八、完整可运行代码

import pandas as pd 
import jieba 
# 读取评价文件
cp_content = open(r'差评.txt', encoding='utf-8') 
yz_content = open(r'优质评价.txt', encoding='utf-8') 
# 对差评分词
cp_sum = [] 
for line in cp_content: 
    result = jieba.lcut(line) 
    if len(result) > 1: 
        cp_sum.append(result) 
cp_fc_results = pd.DataFrame({'chaping': cp_sum}) 
# 对优质评价分词
yz_sum = [] 
for line in yz_content: 
    yo = jieba.lcut(line) 
    if len(yo) > 1: 
        yz_sum.append(yo) 
yz_fc_results = pd.DataFrame({'content': yz_sum}) 
# 导入停用词(关键修正:读取后转为列表)
stopwords = pd.read_csv(r'stopword.txt', encoding='utf-8', engine='python') 
stopwords_list = stopwords['stopword'].values.tolist() 
# 提取停用词列表
# 定义去除停用词(关键修正:判断词是否在停用词列表中)
def stop(contests, stopwords): 
    seg_clear = [] 
    for contest in contests: 
        line_clear = [] 
        for word in contest: 
            # 过滤停用词 + 过滤长度为 1 的无意义词(可选优化,不影响核心功能)
            if word in stopwords or len(word) <= 1: 
                continue 
            line_clear.append(word) 
        seg_clear.append(line_clear) 
    return seg_clear 
# 去除停用词(传入停用词列表)
cp_fc_results_clear = stop(cp_sum, stopwords_list) 
yz_fc_results_clear = stop(yz_sum, stopwords_list) 
# 关闭文件(原代码遗漏,补充关闭避免资源泄露)
cp_content.close() 
yz_content.close()
'''朴素贝叶斯分类'''
'''标签分类'''
cp_train = pd.DataFrame({'pj':cp_fc_results_clear,'lable':1})#表格数据 
yp_train = pd.DataFrame({'pj':yz_fc_results_clear,'lable':0}) 
pj_train = pd.concat([cp_train,yp_train]) 
'''数据切分'''
from sklearn.model_selection import train_test_split 
x_train, x_test, y_train, y_test = \ 
train_test_split(pj_train['pj'].values,pj_train['lable'].values,train_size=0.8,random_state=0)
'''将所有词转化为词向量'''
words = [] 
#将转化的词向量为标准格式
for line_index in range(len(x_train)): 
    words.append(' '.join(x_train[line_index])) 
print(words) 
#导入词向量转化库
from sklearn.feature_extraction.text import CountVectorizer 
vec = CountVectorizer(max_features=1700,lowercase=False,ngram_range=(1,3)) 
#max_features 表示提取词频最高的 1700 个作为词库
#lowercase 表示把所有词转化为小写,False 不需要
vec.fit(words) #传入训练集的所有词
##fit_transform()2 个功能 1:训练出词库 2:transform 根据词库转化为词向量
x_train_vec = vec.transform(words) 
# 添加过采样处理(SMOTE)
from imblearn.over_sampling import SMOTE 
# 初始化 SMOTE 过采样器
smote = SMOTE(random_state=42) 
# 对训练集进行过采样
x_train_smote, y_train_smote = smote.fit_resample(x_train_vec, y_train)
"""使用贝叶斯"""
from sklearn.naive_bayes import MultinomialNB,ComplementNB 
classifier = MultinomialNB(alpha=1) 
# 使用过采样后的数据集进行训练
classifier.fit(x_train_smote, y_train_smote) 
train_pr = classifier.predict(x_train_vec) # 用原始训练集向量预测(对比用)
from sklearn import metrics 
print("训练集分类报告(原始数据预测):") 
print(metrics.classification_report(y_train,train_pr)) 
# 测试集数据分析测试
test_words = [] 
for line_index in range(len(x_test)): 
    test_words.append(' '.join(x_test[line_index])) 
test_pr = classifier.predict(vec.transform(test_words)) 
print("测试集分类报告:") 
print(metrics.classification_report(y_test,test_pr)) 
'''用户输入预测部分'''
def predict_sentiment(text): 
    # 对输入文本分词
    seg = jieba.lcut(text) 
    # 去除停用词和长度为 1 的词
    clear_seg = stop([seg], stopwords_list)[0] 
    # 传入列表的列表,取第一个结果
    if not clear_seg: # 若处理后无有效词汇
        return "无法判断(输入文本过短或无有效词汇)" 
    # 转换为词向量格式
    text_vec = vec.transform([' '.join(clear_seg)]) 
    # 预测
    pred = classifier.predict(text_vec)[0] 
    return "优质评价(好)" if pred == 0 else "差评(坏)" 
# 用户交互
if __name__ == "__main__": 
    user_input = input("请输入要判断的评价:") 
    result = predict_sentiment(user_input) 
    print(f"判断结果:{result}")

九、总结与拓展优化方向

本文完整实现了从原始评价文本到自动情感分类的全流程,解决了中文分词、文本向量化、数据不平衡等核心问题,最终实现了用户输入任意评价自动判断好评 / 差评的功能,可直接落地到电商评价分析、客服消息情感识别等场景。

后续可拓展优化的方向:

  1. **数据优化:**继续爬取差评,增加真实差评数量。进而增加差评训练能力
  2. 词向量优化:用 TfidfVectorizer 替代 CountVectorizer,给有区分度的词更高权重,进一步提升分类效果
  3. 模型优化:使用专为不平衡文本分类设计的 ComplementNB 模型,或尝试 SVM、随机森林、XGBoost 等算法
  4. 功能拓展:批量读取 Excel/CSV 中的评价数据,批量完成分类并输出结果文件,生成词云可视化
  5. 效果升级:使用预训练语言模型(如 BERT、RoBERTa)实现更精准的情感分析,适配更复杂的语义场景

目录

  1. 前言
  2. 一、项目整体效果与技术选型
  3. 1. 最终实现效果
  4. 2. 核心技术栈
  5. 3. 环境准备
  6. 二、数据准备与文本预处理
  7. 1. 数据源说明
  8. 2. 文本读取与中文分词
  9. 读取评价文件
  10. 对差评文本逐行分词
  11. 对优质评价文本逐行分词
  12. 关闭文件,避免资源泄露(新手易踩坑点)
  13. 3. 停用词过滤
  14. 读取停用词表,转为列表格式(关键修正:直接用 DataFrame 会导致 in 判断失效)
  15. 定义停用词过滤函数
  16. 对分词结果执行停用词过滤
  17. 4. 标签标注与数据集合并
  18. 为样本标注标签
  19. 纵向合并两个数据集,得到完整的标注数据集
  20. 三、数据集切分与词向量转换
  21. 1. 训练集 / 测试集切分
  22. 2. 文本转词向量(核心步骤)
  23. 格式化文本:将分词列表转为空格分隔的字符串,适配 CountVectorizer 的输入格式
  24. 导入词向量转换库
  25. 初始化词向量转换器
  26. 核心步骤:fit 基于训练集构建词库,transform 将文本转为词频向量
  27. 四、解决核心痛点:类别不平衡问题
  28. 导入 SMOTE 过采样器
  29. 初始化 SMOTE,固定随机种子保证结果可复现
  30. 仅对训练集执行过采样,测试集保持原始分布
  31. 五、朴素贝叶斯模型训练与效果评估
  32. 1. 模型训练
  33. 导入朴素贝叶斯模型
  34. 初始化模型,alpha=1 为拉普拉斯平滑,避免出现零概率问题
  35. 用平衡后的训练集训练模型
  36. 2. 模型效果评估
  37. 训练集效果验证
  38. 测试集效果验证(核心看泛化能力)
  39. 真实运行结果展示
  40. 六、交互式预测:输入评价自动判断好评 / 差评
  41. 程序入口:用户交互式输入
  42. 七、新手必看踩坑记录
  43. 八、完整可运行代码
  44. 读取评价文件
  45. 对差评分词
  46. 对优质评价分词
  47. 导入停用词(关键修正:读取后转为列表)
  48. 提取停用词列表
  49. 定义去除停用词(关键修正:判断词是否在停用词列表中)
  50. 去除停用词(传入停用词列表)
  51. 关闭文件(原代码遗漏,补充关闭避免资源泄露)
  52. 添加过采样处理(SMOTE)
  53. 初始化 SMOTE 过采样器
  54. 对训练集进行过采样
  55. 使用过采样后的数据集进行训练
  56. 测试集数据分析测试
  57. 用户交互
  58. 九、总结与拓展优化方向

更多推荐文章

查看全部
  • JDK 安装与环境配置详解
  • MetaRTC 跨平台 WebRTC SDK 开发入门指南
  • C++中 memcpy 和赋值拷贝的核心区别
  • FPGA 比特流 (Bitstream) 深度解析
  • Prompt、Agent、Function Call、Skill、MCP 概念辨析与 Java 实现
  • B站:从二次元社区到AI创新孵化器的转型
  • Windows 系统下如何更新 npm 及 Node.js 至最新版本
  • Qwen3-VL-2B 部署教程:4090D 单卡 WebUI 配置详解
  • 全球与中国主流人工智能(AI)公司及机构介绍
  • Delphi 与大模型交互:SOAP 协议自动化生成方案
  • Rocky Linux 镜像下载与系统安装指南
  • Cursor 与 GitHub Copilot 技术对比分析
  • GitHub 界面中文化插件安装与使用指南
  • 基于 Trae IDE 与 MCP Server 实现 Figma 设计稿转前端代码
  • Python Selenium 浏览器自动化入门教程
  • OpenClaw 多平台快速部署指南(Mac/Windows/阿里云)
  • STL 文件预览工具:Windows 资源管理器直接查看 3D 模型
  • Token 分析平台系统架构设计:从前端到核心逻辑
  • Visual Studio 2026 新特性详解:AI 驱动开发体验升级
  • ZXing-C++ 跨平台条码识别实现指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online