尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
豆瓣影评情感分析:朴素贝叶斯文本分类实战
简介面向人工智能与自然语言处理初学者的情感分析实践项目聚焦豆瓣Top250影评数据基于朴素贝叶斯分类器完成正负面情感判别。资料涵盖Scrapy爬虫采集的约5万条影评语料好评差评比例均衡并按照4:1划分训练集与测试集实测准确率在79%至80%之间描述中还指出部分好评含有负面词汇会影响结果便于读者进一步优化。项目从数据抓取、文本清洗、特征构建到模型训练与评估形成一套完整的实验闭环。全包共8个文件包括4个Python脚本、2个词典/停用词文本、1个CSV数据集以及1个Jupyter Notebook大小仅3.26MB麻雀虽小但闭环完整。已有3371人学习下载适合想快速上手文本分类、朴素贝叶斯建模及情感分析全流程的开发者参考。1. 为什么拿豆瓣影评练手短文本情感分析的最佳试验场一部电影上映后口碑怎么样最直观的方式是打开豆瓣短评页面刷几屏。可一旦短评数量上了万条人眼阅读就成了体力活。这个人工智能项目实践要把这个过程自动化把短评当作输入文本用朴素贝叶斯算法判断每一条评论的情感倾向输出“好评”或“差评”。在人工智能学习路径里它属于最典型的文本分类入门项目数据集好拿、模型训练快、结果可解释。很多学校的人工智能大作业都会选这个题目原因是它把数据采集、文本清洗、特征工程、模型训练和评估全部压缩到一个最小闭环里。做这个项目不需要GPU不需要部署服务一台普通笔记本、半小时到一小时就能跑通。适合刚接触自然语言处理、想用实践验证课堂理论的人。下面我会沿着数据准备、特征工程、模型训练、踩坑记录这条线把每一段的关键参数和调用逻辑拆开讲。2. 准备影评数据从抓取短评到清洗出干净的中文语料2.1 用 requests 拿豆瓣短评最小抓取代码与访问边界我一般先把数据收集做成独立脚本不放在训练代码里。这个环节最容易被低估实际做起来会发现清洗比建模更花时间。第一步是抓取短评页面短评列表每页大约20条翻页通过URL参数控制请求时带上一个常见的浏览器User-Agent即可。import time import requests from bs4 import BeautifulSoup headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0 Safari/537.36 } def fetch_comments(movie_id, pages3): comments [] for page in range(pages): url https://movie.douban.com/subject/%s/comments % movie_id params {start: page * 20, limit: 20} resp requests.get(url, headersheaders, paramsparams, timeout10) if resp.status_code ! 200: print(request failed, stop at page, page) break soup BeautifulSoup(resp.text, html.parser) for item in soup.select(div.comment-item): content item.select_one(span.short) rating item.select_one(span.rating) if content: comments.append({ text: content.get_text(stripTrue), rating: rating[class][0] if rating else }) time.sleep(1 page * 0.5) return comments这段代码的重点有三个。第一movie_id是豆瓣电影主页URL里subject后面的那串数字比如35554739这是《流浪地球2》的编号可以直接替换成你要分析的电影。第二短评里的星标控件在span的class属性中allstar50表示五星allstar10表示一星这个属性可以当作模型标签的来源。第三time.sleep控制请求间隔我习惯每页至少停一秒连爬几十页的行为很容易触发访问频率限制不建议一次性抓太多页面。实际操作里我会先把抓下来的数据存成CSV避免反复请求。常见做法是字段只有text和rating两列正负标签统一到后面再处理。豆瓣短评页面对外部工具不太友好如果连续几次请求失败我会直接换公开的中文影评语料来跑通后续流程项目重心始终是情感分析本身而不是和反爬机制较劲。import pandas as pd df pd.read_csv(douban_comments.csv, encodingutf-8-sig) df df.dropna(subset[text]).reset_index(dropTrue) print(df.shape) df.head()读取CSV时指定utf-8-sig比utf-8稳妥Windows下生成的CSV文件默认带BOM头用utf-8直接读会在第一列列名前面残留一个不可见字符。读进来之后先看shape和head确认字段没有串位再做后续清洗。2.2 文本清洗规则去HTML、去英文数字、分词与停用词豆瓣短评虽然是纯文本但抓下来的数据里仍可能混入HTML标签残留、英文单词和全角半角空格。中文情感分析的特征是词级别所以清洗顺序比清洗手段更重要。我先去掉HTML标签再去掉英文和数字最后做中文分词否则一个残留的“div”会被当成一个正经词送进模型。import re import jieba STOPWORDS set() with open(stopwords.txt, encodingutf-8) as f: for line in f: STOPWORDS.add(line.strip()) def clean_text(text): text re.sub(r[^], , text) text re.sub(r[a-zA-Z0-9], , text) text re.sub(r\s, , text) return text def tokenize(text): words jieba.lcut(text) return [w for w in words if w not in STOPWORDS and w.strip()] df[text_clean] df[text].apply(clean_text) df[tokens] df[text_clean].apply(tokenize) df[corpus] df[tokens].apply(lambda x: .join(x))停用词表我用的是网上公开的哈工大停用词表文件不大约几百KB放到项目根目录的data文件夹里。处理完每个字段后要检查一遍比如打印一条评论的清洗前后对比。中文分词阶段jieba默认词典对网络新词和电影术语覆盖有限后面会专门处理“不好看”这类容易被切碎的词。标签策略这里要提前定。豆瓣星级和情感不是严格对应关系我给项目定的规则是四星和五星算好评一星和两星算差评三星直接丢掉。原因在于三星评论的情感倾向太模糊很多人写三星只是觉得“还行”强行把它归到好评或差评都会污染数据。这一步会筛掉一部分样本但换回来的是更清晰的分类边界。3. 特征工程与朴素贝叶斯把“好看”变成概率3.1 词袋和TF-IDF中文句子怎么变成向量朴素贝叶斯算法不直接吃文本它需要数值特征。文本分类项目里最常见的做法是把句子切词后用词袋模型或TF-IDF把每条评论映射成固定长度的向量。词袋模型统计每个词在评论里出现的次数TF-IDF在这个基础上给高频通用词降权我习惯在文本分类里优先用TF-IDF。from sklearn.feature_extraction.text import TfidfVectorizer vectorizer TfidfVectorizer( max_features5000, ngram_range(1, 2), min_df2 ) X vectorizer.fit_transform(df[corpus]) print(X.shape)这里三个参数决定了特征空间的大小和形态。max_features5000表示只保留词频最高的5000个特征限制维度可以降低过拟合并缩短训练时间ngram_range(1, 2)同时保留单词和双词组合“不好”这个双词组合就能成为一个独立特征对评价类文本很关键min_df2意味着一个词至少要在2条评论里出现过才保留可以过滤掉只有在某一条评论里出现的个性化词汇。词袋与TF-IDF的差别在于权重语义。词袋里“电影”出现10次和“烂片”出现1次前者权重更高TF-IDF里“电影”几乎是语料公用的词会被压到很低的权重而“烂片”因为集中出现在差评里权重会明显抬高。这个差异直接决定了特征质量。特征矩阵X是稀疏矩阵格式直接喂给朴素贝叶斯模型没有问题不需要先转换成稠密数组。3.2 朴素贝叶斯在做什么从贝叶斯公式到评论文本朴素贝叶斯能在这个项目里稳定工作核心是它直接计算“给定一条文本属于好评的概率”。公式上就是P(好评|文本) P(文本|好评) * P(好评) / P(文本)。其中P(好评)是训练集里好评比例这是先验概率P(文本|好评)表示在好评的前提下看到这组词的概率这是似然。最后比较P(好评|文本)和P(差评|文本)哪个更大。“朴素”二字指的是条件独立性假设算法假设“好看”“感人”“演技”这些词在好评里出现与否互不影响。这个假设在真实语言里显然不成立但在短文本分类场景下它却意外地稳定而且让每个词的概率可以单独统计训练速度非常快。对几百到几千条影评这种量级的数据朴素贝叶斯足够可靠没必要上深度学习模型。一条影评“剧情很烂演技也烂”进入模型后会被拆成“剧情”“很”“烂”“演技”等词。模型查到P(“烂”|差评)远高于P(“烂”|好评)两个“烂”叠加后差评概率迅速占上风。这个逻辑可以一步步打印出来模型完全不黑匣子这也是它成为人工智能入门项目标配的原因。词袋模型和TF-IDF只负责把文本变成数字真正做判断的是概率表训练之后我通常会把每个词在好评和差评中的条件概率拉出来看一遍确认模型学到的不是噪音。4. 训练与评估用 sklearn 复现可量化的情感判断4.1 train_test_split 与 MultinomialNB参数与训练代码数据准备完成后先把特征和标签划分成训练集与测试集。常见的坑是先对全量语料做向量化再切分这会造成数据泄露正确的顺序是先切分再在训练集上fit向量器。这里的特征X已经在前面算出来了但更规范的做法是把原始corpus传入在切分后单独做向量化这部分我放到避坑章节细说。from sklearn.model_selection import train_test_split from sklearn.naive_bayes import MultinomialNB label df[rating].apply(lambda r: 1 if r in (allstar50, allstar40) else 0) X_train, X_test, y_train, y_test train_test_split( X, label, test_size0.2, random_state42, stratifylabel ) model MultinomialNB(alpha0.1) model.fit(X_train, y_train) print(train size:, X_train.shape)train_test_split里test_size0.2表示拿20%的数据做测试random_state固定随机种子保证多次运行结果一致。stratifylabel是必须的它会按标签比例分层抽样防止1000条好评、100条差评时切分出来的测试集里一条差评都没有。MultinomialNB适合处理TF-IDF这种非负的计数型特征alpha是拉普拉斯平滑的伪计数。alpha越小模型越依赖训练集中的原始统计alpha越大对未登录词的容错越高。我在小数据集上一般从0.01到1之间试。训练完成后模型内部实际生成了一张词概率表。可以用model.feature_log_prob_把特征词在好评和差评里的对数概率打印出来直观看到模型学到了哪些词。这个过程不涉及额外的推理成本强烈建议做一次。4.2 评估模型准确率不是唯一指标混淆矩阵更重要模型训练完后不能只看准确率。影评情感分析里如果差评只占训练集的10%模型全部预测好评就能拿到90%的准确率但它没有实际用处。所以我评估时会同时看F1分数、分类报告和混淆矩阵。from sklearn.metrics import accuracy_score, f1_score, classification_report, confusion_matrix y_pred model.predict(X_test) print(accuracy:, accuracy_score(y_test, y_pred)) print(f1:, f1_score(y_test, y_pred, pos_label1)) print(classification_report(y_test, y_pred)) print(confusion_matrix(y_test, y_pred))classification_report里的precision表示预测为好评的数据里有多少是真的好评recall表示真实好评里有多少被正确召回。F1是两者的调和平均适合评价样本不平衡的文本分类。混淆矩阵可以给出四象限结果比如有多少差评被误判成了好评。如果差评误判率偏高原因通常是训练集差评样本太少模型对差评的先验概率估计不足这时可以回来调整数据比例而不是盲目调alpha。评估之外我还会用predict_proba看模型输出概率而不是单纯类别。这条能力在情感分析里很有价值因为“72%倾向于好评”比“好评”两个字携带更多信息。比如可以把概率按0.4到0.6划为中立区用来识别模棱两可的评论这在真实业务里比强行二分类好用得多。proba model.predict_proba(X_test) print(proba[:5])pridict_proba默认输出两列第一列是差评概率第二列是好评概率。观察概率分布可以帮助发现模型是否过于自信比如绝大多数预测概率都接近0.99或0.01说明模型过拟合了训练数据泛化表现可能不如测试集看到的那么乐观。5. 实操避坑影评分类最常见的 5 个翻车点5.1 模型把所有评论都判成好评现象训练完成后的测试集准确率很高但看一下预测结果几乎所有样本都被预测为好评。原因豆瓣短评整体偏正向好评数量远大于差评训练集里差评占比低于20%时朴素贝叶斯学到的先验概率P(好评)很高会把模糊评论都推向好评一侧。解决采集数据时按星级配额采样控制好评和差评比例在1:1到2:1之间。如果数据已经固定切分时用stratify保证测试集分布一致训练集里可以手工抽样把好评样本数降到差评的两倍以内。注意MultinomialNB不像某些分类器带class_weight参数平滑系数调整解决不了类别不平衡问题应该从数据层面解决。5.2 “不好看”被切成了“不好”和“看”负面评论被判成好评现象检查被误判的评论时发现“不好看”“演技不行”这类明显负面表达出现在好评区间。原因jieba默认词典没有把“不好看”当作完整词切分成了“不好”和“看”而且停用词表里可能把“不”“没”这种否定词删掉了模型丢失了关键的否定语义。解决保留停用词表里的否定词把“不好”“难看”“烂片”“演技差”等电影评论高频表达加入用户词典。加词典后再看分词结果确认没有二次切碎。jieba.add_word(不好看) jieba.add_word(演技差)我还会单独打印这些词的TF-IDF权重确认它们真正进入了特征空间。仅仅做好这一步负面评论的F1通常就能提升好几个点。5.3 先用全量语料fit向量器再切分测试集“作弊”现象模型在测试集上的准确率接近1但换到新评论上预测却明显变差线下线上效果严重不一致。原因代码里对全量语料先执行了fit_transform再做的train_test_split。向量器的词表统计已经看到了测试集的内容测试集信息在训练阶段就泄露给了模型造成数据泄露。解决严格按顺序执行先切分数据再对训练集fit向量器然后对训练集和测试集分别transform。我把这个过程固定成模板X_train_raw, X_test_raw, y_train, y_test train_test_split( df[corpus], label, test_size0.2, random_state42, stratifylabel ) vectorizer TfidfVectorizer(max_features5000, ngram_range(1, 2), min_df2) vectorizer.fit(X_train_raw) X_train_vec vectorizer.transform(X_train_raw) X_test_vec vectorizer.transform(X_test_raw)这样测试集和训练集共用同一张从训练数据里学到的词表测试集信息不会泄漏进特征统计。这是文本分类项目里最隐蔽也最常见的错误头歌平台上朴素贝叶斯练习里不会踩这个坑真实数据集下绕不过去。5.4 自测准确率很漂亮换一部电影预测就崩现象在《流浪地球2》影评上训练测试都有85%以上准确率拿到另一部爱情片影评上预测差评全被预测成好评。原因训练语料来自单一题材词表里“特效”“演技”等词的分布完全偏向该题材情感表达有领域差异。爱情片里的“虐”“甜”“哭惨”和科幻片里的“宇宙”“飞船”在概率表里根本不占位置。解决训练集尽量覆盖多种类型电影至少包含动作、喜剧、科幻、爱情几类。如果只做单部电影分析模型只能描述该电影群体的表达习惯。往多模态情感分析方向走时也要注意弹幕和表情符号的表达方式与短评完全不同跨域迁移能力是有限度的。5.5 短评抓取到一半连续失败数据只有几百条现象脚本刚开始还能正常返回数据几页之后收到非200状态码重试也无效数据量不够训练。原因短评页面持续高频访问触发了访问频率限制通常按IP和访问特征统计。解决降低请求频率随机延时至少2秒每次运行只抓一页边抓边存CSV防止中途中断丢数据。别把全部评论抓完再落盘写文件的时间放在每次循环尾部。更保险的做法是放弃爬虫直接用公开的中文影评语料跑通训练流程项目价值集中在情感分类本身。我在后续实践里都会优先选择后者数据可复用、结果可复现不会因为一个环节失败拖垮整个项目。6. 进阶调参与验证的最后一公里基础模型跑通后我一般会做两件事用网格搜索选出更合适的alpha然后用新的样本外数据验证模型泛化能力。alpha虽然只接受一个浮点数但0.01和1之间的差异在几百条样本上非常明显。网格搜索可以把这一步自动化from sklearn.model_selection import GridSearchCV param_grid {alpha: [0.01, 0.05, 0.1, 0.5, 1.0]} gs GridSearchCV(MultinomialNB(), param_grid, cv5, scoringf1) gs.fit(X_train_vec, y_train) print(gs.best_params_, gs.best_score_)GridSearchCV用5折交叉验证评估每个alpha的F1分数比固定切分一次的结果更稳定。注意搜索过程用的仍然是训练集测试集要留在最后做一次最终验证不要在搜索阶段就把测试集用掉。验证泛化能力的手段是手工标注几十条新评论把它们通过同一套清洗和向量化流程输入模型。我习惯准备10条好评、10条差评、10条中性评论观察中性评论被强行分类时的置信度。如果中性评论全部以高置信度落到两端说明模型把情感判断做得太极端可以考虑把predict_proba落在0.4到0.6区间的样本直接判为“存疑”让情感分析输出三分类实际使用中比二分类更有说服力。最后还有个进阶方向可以尝试在现有特征基础上加入情感词典打分维度。比如统计每条评论里的积极词与消极词数量作为两个额外的数值特征拼进特征矩阵。这一步不改变朴素贝叶斯本身只是让模型拿到更接近人类判断的信号。做这个项目时我第一个版本的准确率看着还行后来把混淆矩阵拉出来才发现差评几乎全军覆没根源是训练集里差评太少。回头重新处理了数据分布模型才算真正可用。这个项目的价值不是调出一个完美分类器而是让你完整走一遍从文本到概率的流程以后遇到任何文本分类问题都能照这个套路搭出第一版方案。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

操作系统T1考题解析:进程状态迁移与上下文切换双线推演

操作系统T1考题解析:进程状态迁移与上下文切换双线推演

1. 项目概述:这是一份面向操作系统的教学实操型考题解析,不是试卷搬运工“第2单元进程的描述与控制考试T1”——光看标题,你可能以为这只是某高校《操作系统原理》课程的一道普通期中题。但作为带过十几届系统课实验的从业者,我得…

📅 2026/10/12 13:43:55
Java中extends与implements的区别:从语法到设计选型

Java中extends与implements的区别:从语法到设计选型

1. 为什么这两个关键字总让人犯迷糊刚入行那会儿,我在一个后台管理系统里写代码,需要定义一个订单服务类。当时脑子里想的是“订单服务是一种服务,那就用 extends 继承一个基础服务类吧”,结果写着写着发现基础服务类里有一堆跟订…

📅 2026/10/12 13:43:55
C语言浮点数精度陷阱与避坑指南:从IEEE 754到工程实践

C语言浮点数精度陷阱与避坑指南:从IEEE 754到工程实践

1. 从"整数思维"到"浮点思维"的认知切换很多人学C语言学到浮点数这一块,都会有一种"好像懂了但又好像没懂"的感觉。声明一个float变量、打印用%f、做做加减乘除,看起来和整数没什么区别。但一旦程序跑出0.1 0.2 ! 0.3这种…

📅 2026/10/12 13:43:55
MORE NEWS

更多资讯

📰

计算机网络实验全链路:从Boson Netsim拓扑到SOCKET编程实战

简介:这份华中科技大学计算机学院《计算机网络》实验报告,面向高校计算机专业学生及网络工程初学者,帮助读者系统掌握网络组建与协议配置的实践方法。报告围绕IP协议、网络层与数据链路层协议、子网划分、RIP与OSPF路由协议、路由器及二/三层…

📰

基于Python的微博舆情分析可视化系统:爬虫、情感分析与展示全流程

简介:基于Python的微博舆情分析可视化系统,是一套面向毕业设计、课程设计与期末大作业的完整项目源码。整合爬虫采集、情感分析与可视化展示三大模块,适合计算机专业学生作为高分毕设参考。代码带有详细注释,新手也能较快上手&…

📰

近红外光谱回归建模:物理约束驱动的深度学习方法

简介:本资源是一套面向计算机专业本科生的毕业设计与课程作业级深度学习实践项目,聚焦近红外光谱(NIR)数据的回归建模任务,适用于化学分析、食品检测、生物医学等交叉领域中的成分定量预测场景。压缩包共9个文件&#…

📰

开题报告写作新思路:千笔与灵感风暴AI的分工协作指南

开题这件事,我见过太多种“卡法”。有人卡在“这个题值不值得做”,坐了一下午连题目方向都定不下来;有人卡在文献综述,读了二三十篇摘要,落到Word里还是写不出三句人话;还有人卡得最冤——初稿都交了&#…

📰

网红罗盘时钟:物理+代码+光影的时间装置入门指南

1. 这个“网红时钟罗盘”到底在火什么?——从零理解它的底层逻辑与真实价值你刷短视频时,有没有被那种悬浮在空中的金属圆盘吸引过?它缓缓旋转,指针不是指向数字,而是嵌着细小的指南针、经纬度刻线,甚至微缩…

📰

Advanced Installer 20.7.1:打造干净可复现的MSI安装包与升级链路

简介:Advanced Installer 20.7.1 是一款面向软件开发者与打包工程师的 Windows 安装包制作工具,专注于生成符合 MS Windows 认证的 MSI 安装文件,同时支持自定义欢迎界面与安装过程界面,适合需要规范化发布桌面应用的团队或个人使…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬