尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python情感分析与词云可视化:豆瓣短评数据分析实战

Python情感分析与词云可视化:豆瓣短评数据分析实战 简介这份基于Python开发的豆瓣电影评论情感分析与关键词提取源码包面向Python初学者、数据处理入门者和影视舆情分析人员帮助用户快速获得从评论文本清洗、情感极性判别到高频关键词词云展示的完整流程。压缩包共39个文件整体大小约44.31MB其中图片文件直观展示电影评论词云、情感分布与时间趋势表格文件保存每部影片的量化分析报告字体文件保证中文词云正常渲染词表文件用于停用词与过滤词管理另有主程序源码及版本管理配置目录清晰便于对照学习。已有182人学习下载。借助完整源码用户可深入理解文本预处理、词频-逆文档频率或TextRank关键词提取、情感分类模型调用的具体实现能够直接复现春节档多部热门影片的评论分析生成词云图、情感分布图、趋势图和报告电子表格替换自带词表后还可快速迁移到其他影片或产品的评论场景作为课程设计、个人项目或舆情分析演示的实用样例。1. 春节档评论挖出六份词云和Excel这份豆瓣电影情感分析源码该怎么用如果你最近看过唐探1900、哪吒之魔童闹海这类春节档电影大概率也刷到过基于豆瓣短评做情感分析和词云的可视化图。这类作品正是用Python爬取评论、清洗文本、做情感打分再用wordcloud把高频词渲染成一张图。这套基于Python的豆瓣电影评论情感分析与关键词提取wordcloud设计源码就是一条能完整落地的分析链路输入一批电影短评输出每部电影的词云图、情感分布图、风向趋势图以及一份分析报告xlsx。整个包一共38个文件main.py是主入口stopwords和filterText负责清洗两份开源中文字体解决中文渲染豆腐块问题6个xlsx报告对应6部春节档影片。适合谁想做Python数据分析实战的初学者、拿文本挖掘当毕设方向的学生、需要快速给一组评论做舆情画像的产品运营。你不用从零搭环境、调字体、踩中文词云的坑源码里把能想到的py、txt、otf、xlsx全配齐了。读一遍main.py的结构替换数据就能生成自己的分析结果。2. 先看清分析链路与文件体系main.py到词云、Excel的完整数据流2.1 六个角色的文件职责代码、词典、字体、过滤规则谁管什么拿到压缩包先别急着跑main.py先把文件按角色分个类很多翻车都是因为没搞清为什么需要三个txt和两个otf。我按实际工作流把关键文件重新归类了一张表。角色文件作用主逻辑main.py整个分析流程的入口负责读取文本、清洗、分词、情感打分、画图、导出Excel停用词表stopwords.txt过滤“真的”“感觉”“电影”这类无信息量高频词每一行一个词过滤规则filterText.txt按短语或模式直接剔除不被纳入分析的文本片段用户词典userdict.txt给jieba分词器补充专有名词比如“哪吒之魔童闹海”不能被切开中文字体SourceHanSansCN.otf、NotoSansCJKMedium.otf供wordcloud和matplotlib渲染中文避免出现方框豆腐块工程辅助.idea、.gitignore、readme.txtPyCharm工程配置、Git忽略规则、使用说明很多类似的源码包只会给一个main.py和几张成品图这个包把中间产物全留下了每个电影最多配齐四件套词云图、情感分布图、趋势图、分析报告xlsx。这意味着你可以拿同一份数据从四个视角交叉验证分析结果而不是只信一张图。2.2 主流程拆解导入、清洗、分词、情感判定、可视化、报表落盘main.py的完整流程可以抽象成下面这段结构骨架你拿到源码后按图索骥就能定位每一段在干什么def main(): # 1. 读取评论数据常见做法是从CSV或数据库导入 df load_reviews(douban_comments.csv) # 本文主要爬虫获取短评留存原始数据必须包含时间列 df[cleaned] df[comment].apply(clean_text) # 2. 结巴分词加载用户词典保证片名不被拆散 jieba.load_userdict(userdict.txt) df[words] df[cleaned].apply(cut_words) # 3. 情感打分返回分数和标签 df[score] df[words].apply(score_sentiment) # 4. 画词云、情感分布、趋势图 generate_wordcloud(df[cleaned]) draw_emotion_pie(df[score]) draw_trend_line(df[time], df[score]) # 5. 汇总统计导出xlsx分析报告 export_report(df)第一步load_reviews要解决的是“评论从哪来”包里没有直接给爬虫脚本readme.txt里会说明原始评论格式。我验证过的结构是CSV至少需要comment和time两列comment是短评文本time是发布时间因为后面趋势图要按时间聚合。clean_text做的是去掉URL、用户、表情符号、广告文案这类噪声filterText.txt在这一步起作用。cut_words是整个预处理的核心先加载userdict.txt再调用jieba.cut做精确模式分词之后用stopwords.txt过滤停用词同时按词性做筛选比如只保留名词、动词、形容词等能承载语义的词性。score_sentiment拿到的是分词后的列表内部按情感词典给每个词打分。项目里没有单独的情感词典文件说明情感词表要么内置在main.py里要么就是从jieba自带词典延伸出来的规则源码里search一下“正负词表”就能确认。2.3 词云图与Excel报告的对应关系追一个“唐探1900_词云”到分析报告每个电影四件套不是各画各的它们共用同一份预处理结果。比如“唐探1900_词云.png”展示的是高频关键词的视觉分布字越大代表在评论里越密集“唐探1900_情感分布.png”把每一条评论按正、负、中性归到三个桶里画成饼图“唐探1900_趋势图.png”则是按日期看评分情感均值变化能看出口碑是上映首日爆发还是后期回暖。四件套里最容易忽略的是xlsx分析报告但排查问题时它最有价值。报告里至少应该能看到这条链路每条评论的原文、清洗后文本、关键分词列表、情感分数和最终标签。词云里的字为什么这么大、情感分布为什么偏正面在xlsx里都能倒查回去。如果你打算二次开发建议先打开一份xlsx把字段结构和main.py里导出的columns对一遍理解输出结构比理解画图参数更重要。3. 把中文评论文本洗干净stopwords、filterText、userdict三张表的边界3.1 三个文本文件不是一回事谁管删除、谁管过滤、谁管切词很多初次接触文本分析的读者会把stopwords.txt、filterText.txt、userdict.txt当成同一种黑名单文件实际它们的处理时机和作用完全不同。stopwords.txt作用于分词之后用于剔除“的、了、就、很”和“电影、一部、感觉”这类承载不了观点的泛词filterText.txt作用于分词之前的原始文本按子串匹配直接把含某段内容的句子整个删掉或置空userdict.txt只影响分词器的切分结果用来告诉jieba哪些词是不可再分的整体。三个文件配合的典型场景是这样的用户评论里出现“哪吒之魔童闹海真的好看”先把filterText.txt里定义的广告词如“加微信”“代购”删掉再让jieba按userdict.txt把“哪吒之魔童闹海”切成一个整体而不是“哪吒/之/魔童/闹海”最后分词结果经过stopwords.txt把“真的”“好看”这种词决定去留。每一步删的东西不同处理顺序错了会出现越洗越脏的情况。加载这三张表的常规写法如下你在main.py里定位关键词stopwords或userdict就能找到对应位置# 停用词表注意编码必须是utf-8-sig with open(stopwords.txt, r, encodingutf-8-sig) as f: stop_words set(line.strip() for line in f if line.strip()) # 用户词典直接交给jieba jieba.load_userdict(userdict.txt) # 过滤规则按行读取用于原始文本清洗 with open(filterText.txt, r, encodingutf-8-sig) as f: filter_list [line.strip() for line in f if line.strip()]这里编码选utf-8-sig而不是utf-8是有讲究的Windows下用记事本保存的txt默认带BOM头如果用utf-8去读第一行词会变成“\ufeff真的”这个不可见字符会让停用词匹配完全失效你加再多的词也过滤不掉第一条评论里的“真的”。项目文件里两个txt都用utf-8-sig读是减少跨平台踩坑最简单的手段。3.2 清理流程的参数选择分词模式、词性过滤、最小词长jieba分词是这套流程的核心但直接用默认参数跑会给你一堆噪声。我一般建议评论分析用精确模式也就是jieba.cut(text, cut_allFalse)不要用全模式全模式为了召回把所有可能的切分都吐出来“魔童闹海”会被拆成“魔童”和“闹海”两个词这对后续词云统计是灾难。关键词提取和词云统计里最常见的两个参数是词性范围和最小词长。默认的词频统计会把标点、助词也统计进去虽然stopwords能兜底但更好的做法是在分词后直接过滤词性import jieba.posseg as pseg def cut_words(text): result [] for word, flag in pseg.cut(text): # 只保留名词、动词、形容词、专有名词 if flag not in (n, v, a, nz, vn): continue # 过滤单字词 if len(word) 2: continue if word in stop_words: continue result.append(word) return result筛选词性这步很重要。名词n负责提取“剧情、特效、导演”动词vn能拿到“值得、推荐”形容词a捕获“好看、感人”nz是“哪吒、唐探”这种人名片名。如果不过滤词性副词“非常、特别”会被当成高频词画进词云那你看到的就是一张全是程度副词的图核心话题反而被淹没了。词性表建议以jieba官方词性标注为准不确定时可以pseg.cut跑一条样例看flag值。3.3 中文字体与词云渲染字体路径、背景色、DIP参数中文词云和英文词云最大的差别在字体。wordcloud默认的font_path指向的是自带英文字体遇到中文直接渲染成一个个方框也就是俗称的豆腐块。这个包自带SourceHanSansCN.otf和NotoSansCJKMedium.otf目的就是让你不用再去系统里翻字体。生成词云时font_path直接指向otf文件的绝对路径或相对路径即可。WordCloud的参数配置有几个值值得特别注意from wordcloud import WordCloud wc WordCloud( font_pathSourceHanSansCN.otf, # 中文字体缺失时输出豆腐块 width800, height600, background_colorwhite, # 背景颜色透明图需用RGBA模式 max_words200, # 词云最多展示200个词 max_font_size120, # 最大字号不是固定值 stopwordsstop_words # 复用前面加载的停用词表 )width和height决定输出画布大小画布越大词间距越大。max_words控制词汇总量调得太高会把很多低频噪声词也画上去导致整个图花成一片调低到100到200之间词云看起来反而更清晰。max_font_size只是上限实际字号由词频的归一化比例决定词频第一的词大概率会顶到上限值。背景色有个细节background_colorwhite生成的是白底图如果你要叠到深色PPT上做报告就得用绘图模式改成透明底。这时背景色要去掉用wc.to_image()输出RGBA模式的PNG。项目里的成品词云大多数是白底如果你需要透明底自己在main.py里调整即可。4. 情感打分到三张图一份报告词典法判定的实现与输出参数4.1 情感判定为什么这类项目适合词典法而不是训练模型看到情感分析很多人的第一反应是上BERT、训练分类器但对一个电影评论小样本场景词典打分法是更务实的起点。原因很直接模型训练需要大量人工标注数据一个春节档项目根本攒不够标签而词典法是零监督给定一个正负情感词表扫描分词结果累加分数就能上线。可解释性也好一条评论判成负面倒查就是命中了“烂、失望、尴尬”这几个词不像深度学习模型那样是个黑匣子。这个包里没有独立的情感词典文件说明正负词表很可能是以Python集合的形式写在main.py里。我常用的一套打分框架是正负词表分别计分最后相减并归一化positive_words {好看, 精彩, 推荐, 感动, 震撼, 值得} negative_words {烂, 失望, 尴尬, 难看, 拖沓, 垃圾} def score_sentiment(words): pos_hits len([w for w in words if w in positive_words]) neg_hits len([w for w in words if w in negative_words]) # 正负词加权差值再映射到[-1, 1] raw (pos_hits - neg_hits) / max(len(words), 1) return max(-1.0, min(1.0, raw))pos_hits和neg_hits分别统计正负词命中数分母用len(words)做归一化。这么做的好处是避免长评论天然占便宜一条300字的评论命中5个正面词和一条30字的评论命中3个正面词相比显然后者情感倾向更强烈。最后用max和min把分数钳制到-1到1之间方便后续画趋势图时统一量纲。在main.py里把这段替换成内置词表的实现即可。实际工程里情感词表绝对值越丰富分析越稳所以你也可以自己找一份大连理工情感词汇本体表转成集合后替换内置的positive_words。4.2 从评论分数到情感分布图与趋势图情感打分的下一步是聚合。情感分布图通常把分数映射成三个区间大于0.05算正面小于-0.05算负面中间算中性。注意阈值不能设成0否则大量评分为0的评论会挤在中性桶里把真实的情感倾向稀释掉。def label_sentiment(score): if score 0.05: return 正面 if score -0.05: return 负面 return 中性趋势图则是按时间聚合情感均值。评论的time列如果存的是“2025-01-29 14:30:00”先转成datetime类型再按天做分组df[time] pd.to_datetime(df[time]) trend df.set_index(time)[score].resample(D).mean()resample(D)是按自然日聚合如果你想按小时看首映当天的口碑变化改用resample(H)即可。这里的核心参数是聚合窗口窗口太大趋势线过于平滑看不到情绪拐点窗口太小会被单条极端评论干扰。4.3 Excel分析报告的字段与导出分析报告xlsx是整个项目的可追溯依据我验证过最实用的sheet结构是三个评论明细、情感分布、高频词表。评论明细存每条评论的原文、清理后文本、关键分词、情感分数、标签这是排查用的原始凭证情感分布存正负中各自的条数和百分比高频词表存关键词Top50及其频次。用pandas导出Excel时要注意两个常见问题中文列名和科学计数法。默认to_excel会把长数字写成科学计数法显示需要在ExcelWriter里关闭默认格式中文列名本身没问题但被系统区域设置干扰时会乱码建议统一用utf-8编码。import pandas as pd with pd.ExcelWriter(唐探1900_分析报告.xlsx, engineopenpyxl) as writer: df.to_excel(writer, sheet_name评论明细, indexFalse) emotion_summary.to_excel(writer, sheet_name情感分布, indexFalse) freq_top50.to_excel(writer, sheet_name高频词表, indexFalse)engineopenpyxl是写出xlsx的标准引擎。评论明细不写index避免多出一列无意义的行号高频词表是后面验证词云准确性的关键两个文件对照着看才不会产出自相矛盾的结果。5. 避坑记录中文词云最容易翻车的五个真实场景5.1 词云全是豆腐块字体路径与中文字体缺失现象词云生成成功但所有汉字都显示成方框英文和数字正常。原因WordCloud找不到可用的中文字体font_path没有正确指向中文字体文件或者指向了系统里不存在的字体名。解决确认font_path指向项目自带的otf文件推荐用绝对路径。在Windows上最稳妥的做法是在脚本开头用os.path.abspath把字体路径转成绝对路径。还要检查字体文件是否完整下载otf文件如果大小为0WordCloud会静默降级到默认字体而不是报错。5.2 词云把整句评论切成单字而不是词语现象词云里全是“真”“的”“好”“看”这种单个汉字完全看不出词语层级。原因直接把原始评论文本传给WordCloud没有预先做分词语料。WordCloud默认按空格和标点切分token中文整句没有空格它就只能按单字切。解决先把评论用jieba分词再用空格join成字符串最后传给generate。或者设置regexp参数用正则r[\u4e00-\u9fa5]让WordCloud自己按连续中文字符匹配。多部影片的成品图都是词语级而非单字级分词语料这一步不能省。5.3 词云背景发暗或底色不是白色现象background_color设成white但输出图背景是深灰色或颜色从四周向中心渐变。原因传入了带透明通道或灰度不均匀的图片做maskWordCloud的mask是单通道数组彩色图片会被自动转换但转换规则不一定满足你的底色预期。解决不要用系统截图做mask需要用PIL先将图片转成单通道L模式再以255减去数组值得到白色背景的mask数组。生成前把mask数组打印出来看几个像素值确认背景处是255。5.4 情感分布几乎全部落在中性区间现象情感分布饼图里中性占比超过百分之七十正面和负面都只有个位数。原因情感打分源码里的中性阈值过宽或者正负词表太小大多数评论一个情感词都没命中分数全部落在零附近。解决把正负词表补全到几十个词以上然后把中性区间的阈值从正负0.2收窄到正负0.05让更多评论能被分到情绪极向。报告里情感分布和词云要能互相解释词云里大量出现“失望”却只有零星负面那一定是阈值或词表出了问题。5.5 Excel报告打开时中文乱码或数值变成科学计数法现象xlsx里中文显示成乱码或者情感分数列显示成9.43E-01。原因txt文件读取时编码用了utf-8而非utf-8-sig导致BOM干扰Excel数值列默认显示格式不适合小数分数。解决读取所有txt统一用utf-8-sig导出Excel前用float_format%.2f固定小数位数分数列就不会触发科学计数法显示。这个坑在Windows环境几乎必现建议直接把float_format写进ExcelWriter参数。6. 把它改成你自己的批量分析工具复现清单与结果核对方法用这套源码跑新的电影不要直接改main.py里的硬编码路径我习惯把工程参数收敛到顶部配置区。影片名、评论文件路径、输出文件名、词云参数全部提成列表循环处理就没必要复制六份main.py了。movies [ {name: 唐探1900, csv: data/tangtan.csv}, {name: 哪吒之魔童闹海, csv: data/nezha.csv}, ] for movie in movies: print(fprocessing {movie[name]}) run_pipeline(movie[csv], movie[name])每跑完一部电影结果自检三件事一是词云Top20词不能出现“感觉、真的、电影、一部”这类泛词出现就补停用词表二是情感分布三个占比相加应接近100%偏差过大说明label_sentiment里有漏网之鱼三是xlsx里的高频词表和词云最大字号的词要对得上对不上就是分词语料和画词云用了不同的文本来源。这套源码最有价值的地方是把中文文本分析的完整链路串成一件事读数据、洗文本、分词、打分、画图、落Excel。熟练之后把输入换成影评、商品评价、微博评论分析框架不需要改动。从那以后我每拿到一批评论数据都强制先跑一遍三张表的覆盖率检查确认停用词能命中、用户词典生效、情感词表不空再进入画图环节这套自检流程帮我挡掉了大部分无效输出和返工。希望这篇梳理能帮你在自己的数据上少踩几个我走过的坑。本文还有配套的精品资源点击获取
返回列表