跳到主要内容Python 基于朴素贝叶斯的中文评价情感分析 | 极客日志PythonAI算法
Python 基于朴素贝叶斯的中文评价情感分析
中文评价情感分析利用 NLP 技术解决人工处理海量文本效率低的问题。通过 jieba 分词、停用词过滤、CountVectorizer 向量化及 SMOTE 过采样处理类别不平衡,构建多项式朴素贝叶斯模型实现好评差评自动识别。系统支持批量训练与交互式预测,评估指标涵盖精准率与召回率,可直接应用于电商评价分析与客服场景。
虚拟内存1 浏览 前言
在电商、本地生活、内容平台等场景中,每天都会产生海量的用户评价文本。人工逐条区分好评 / 差评、挖掘用户痛点效率极低,而通过 NLP + 机器学习技术实现评价情感倾向自动分类,可以帮助商家快速定位产品问题、优化服务体验,也能为平台运营提供数据支撑。
本文将从 0 到 1 完整实现一套中文评价情感分析系统:从原始文本数据预处理、中文分词、停用词过滤,到词向量转换、朴素贝叶斯模型训练,再到解决数据不平衡问题、最终实现用户输入任意评价自动判断好评 / 差评,全程附带代码解析、踩坑记录和真实运行效果,新手也能直接复现。
一、项目整体效果与技术选型
1. 最终实现效果
- 支持本地优质评价 / 差评文本批量训练模型
- 自动完成中文文本分词、停用词过滤、词向量转换全流程
- 针对评价数据常见的类别不平衡问题,通过 SMOTE 过采样优化模型效果
- 提供交互式输入功能:输入任意评价文本,实时输出「优质评价」/「差评」的判断结果
- 完整的模型评估报告,精准查看模型在训练集 / 测试集的分类效果
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 cp_content:
result = jieba.lcut(line)
(result) > :
cp_sum.append(result)
yz_sum = []
line yz_content:
yo = jieba.lcut(line)
(yo) > :
yz_sum.append(yo)
cp_content.close()
yz_content.close()
in
if
len
1
for
in
if
len
1
3. 停用词过滤
分词后的结果里包含大量无情感意义的停用词,会干扰模型的特征学习,因此需要过滤掉;同时补充过滤长度≤1 的单字,进一步降低噪声。
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:
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 词频向量化,核心逻辑是:基于训练集构建高频词库,将每条文本转为「词频向量」,向量的每个维度对应词库中的一个词,值为该词在文本中出现的次数。
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,
lowercase=False,
ngram_range=(1,3)
)
vec.fit(words)
x_train_vec = vec.transform(words)
注!!!
新手必看踩坑点:***测试集只能用 vec.transform(),绝对不能用 fit_transform()!***否则会用测试集重新构建词库,导致数据泄露,模型评估结果失真。
四、解决核心痛点:类别不平衡问题
从我的运行结果可以看到,电商评价数据存在严重的类别不平衡:
- 训练集中,优质评价(标签 0)有 2911 条,差评(标签 1)仅 15 条
- 测试集中,优质评价 725 条,差评仅 7 条
如果直接用不平衡的数据集训练,模型会严重偏向多数类(好评),哪怕全部预测为好评,准确率也能达到 99%,但完全无法识别差评,失去了业务价值。
这里我们用 SMOTE 过采样解决该问题:通过算法合成少数类(差评)的样本,让训练集中两类样本的数量达到平衡,提升模型对差评的识别能力。
from imblearn.over_sampling import 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
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):
seg = jieba.lcut(text)
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}")
七、新手必看踩坑记录
- 停用词判断失效:读取停用词后直接用 DataFrame,没有转为列表,导致 word in stopwords 判断完全失效,必须用.values.tolist() 转为列表格式
- 数据泄露问题:测试集使用 fit_transform() 重新构建词库、在全数据集执行过采样,都会导致模型评估结果虚高,正确做法是仅用训练集 fit / 过采样
- 文件资源泄露:用 open 打开文件后没有 close,长时间运行会导致句柄泄露,推荐用 with open() 上下文管理器自动管理文件
- 预处理流程不一致:预测单条文本时,没有执行和训练集完全一致的分词、停用词过滤规则,导致预测结果出错
- 只看准确率:不平衡数据中,哪怕全部预测为多数类,准确率也能达到 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:
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))
vec.fit(words)
x_train_vec = vec.transform(words)
from imblearn.over_sampling import 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)
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}")
九、总结与拓展优化方向
本文完整实现了从原始评价文本到自动情感分类的全流程,解决了中文分词、文本向量化、数据不平衡等核心问题,最终实现了用户输入任意评价自动判断好评 / 差评的功能,可直接落地到电商评价分析、客服消息情感识别等场景。
- **数据优化:**继续爬取差评,增加真实差评数量。进而增加差评训练能力
- 词向量优化:用 TfidfVectorizer 替代 CountVectorizer,给有区分度的词更高权重,进一步提升分类效果
- 模型优化:使用专为不平衡文本分类设计的 ComplementNB 模型,或尝试 SVM、随机森林、XGBoost 等算法
- 功能拓展:批量读取 Excel/CSV 中的评价数据,批量完成分类并输出结果文件,生成词云可视化
- 效果升级:使用预训练语言模型(如 BERT、RoBERTa)实现更精准的情感分析,适配更复杂的语义场景
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online