简介这份资源是面向计算机、自动化等相关专业学生与从业者的电商产品评论数据情感分析课程大作业源码包评审分达95分可直接用于期末课程设计、大作业或毕业设计。项目以Python实现围绕商品评论展开情感倾向分析涵盖数据采集、评论分数与内容吻合度处理、关键词提取、情感分数计算及可视化展示等环节并配有项目说明文档便于理解整体流程与模块划分。压缩包共1380个文件以478个py源码、237个csv评论数据、178个txt说明、125个html页面及若干模型与依赖文件为主整体约53.95MB目录结构清晰便于按模块检索学习。目前已有1697人学习下载具备较高参考价值。读者可据此掌握从数据到情感分析的完整实现思路并在此基础上调整算法、优化主题参数或替换情感分类方案完成类似功能的二次开发。1. 从一份 95 分课程大作业说起这套 Python 电商评论情感分析源码到底能跑出什么电商评论数据抓下来容易真正难的是把几万条“好评如潮”和“差评如潮”拆开看——哪句话在夸外观哪句话在骂售后评分和文字对不上的那批评论又该怎么处理。这套基于 Python 的电商产品评论数据情感分析源码就是冲着这个场景来的它把爬虫抓下来的 CSV 评论、分词、情感打分、LDA 主题建模、词云和 Streamlit 可视化串成了一条完整链路目录里已经带了spider_comments.csv、spider_meidi_comments2019.csv、spider_meidi_comments2020.csv以及美的Midea_正面.csv这类真实评论样本不是空壳工程。它适合计算机、自动化相关专业做课程大作业或毕设的同学也适合想快速搭一套评论分析原型的从业者。下面我按“能跑起来 → 看懂结构 → 避开坑 → 进阶改”的顺序把这份资源拆开讲清楚。2. 环境与目录结构把streamlit run之前的事做对2.1 虚拟环境与依赖为什么目录里会有activate和pyvenv.cfg拿到压缩包解压后第一眼会看到activate、activate.bat、deactivate.bat、sysconfig.cfg、pyvenv.cfg这几个文件。这不是作者乱放的而是他把整个 venv 虚拟环境目录一起打包进来了。pyvenv.cfg是 Python 3.3 之后venv模块创建虚拟环境时生成的配置文件里面记录了home基础解释器路径、include-system-site-packages、version这些信息activate和activate.bat分别是 Linux/macOS 和 Windows 下的激活脚本。常见做法是不要直接用作者打包进来的这个 venv因为pyvenv.cfg里的home指向的是作者本机的 Python 路径换台机器大概率失效。我一般会删掉旧环境自己重建# 进入项目根目录后重建一个干净的虚拟环境 python -m venv venv # Windows 激活 venv\Scripts\activate.bat # Linux / macOS 激活 source venv/bin/activate # 安装核心依赖版本按你本机 Python 版本微调 pip install pandas numpy jieba snownlp wordcloud matplotlib seaborn pip install scikit-learn gensim pyLDAvis streamlit这里几个包的职责要分清jieba负责中文分词snownlp负责情感倾向打分返回 0~1 的分数gensim提供 LDA 主题模型pyLDAvis做主题可视化streamlit是最终交互界面的框架。scikit-learn主要用来做 TF-IDF 向量化和一些聚类辅助。如果你的 Python 是 3.8 附近snownlp和gensim的兼容性最稳这也是热词里python 3.8被频繁搜到的原因之一。提示sysconfig.cfg是环境相关的配置文件通常不需要手动改真正影响能否运行的是pyvenv.cfg里的解释器路径和已安装包列表。2.2 目录框架与数据文件先认清哪份 CSV 是干什么的从正文给出的文件清单看数据层至少有这几份文件名推测用途使用建议spider_comments.csv通用爬虫抓取的评论原始数据作为主数据集字段最全spider_comments_34000.csv约 3.4 万条的大样本评论做 LDA 和词云时用样本足spider_meidi_comments2019.csv美的 2019 年评论做时间维度对比spider_meidi_comments2020.csv美的 2020 年评论与 2019 对比看趋势美的Midea_正面.csv已筛出的正面评论做正负样本对照或情感验证这套数据的价值在于它同时具备“跨年份”和“正负极性”两个维度正好对应正文里提到的“同一个热水器的评论内容随时间变化”和“评论分数和评论内容不吻合”这两个必须考虑的点。实际动手前先统一列名否则后面groupby和情感打分会对不上import pandas as pd # 读取时统一用 utf-8-sig避免 Excel 导出的 BOM 头导致列名带 \ufeff df pd.read_csv(spider_comments_34000.csv, encodingutf-8-sig) # 打印列名和缺失情况确认评论内容列、评分列、时间列的真实名称 print(df.columns.tolist()) print(df.isnull().sum()) # 统一重命名按你实际列名替换 df df.rename(columns{ 评论内容: content, 评分: score, 时间: comment_time }) # 丢掉内容为空的行评分转数值 df df.dropna(subset[content]) df[score] pd.to_numeric(df[score], errorscoerce)参数说明encodingutf-8-sig是关键很多同学读 CSV 报KeyError就是因为 BOM 头让第一列列名变成了\ufeff评论内容。errorscoerce把无法转成数字的评分变成NaN方便后续统一过滤而不是直接抛异常中断。2.3 启动入口streamlit run之前先确认路径正文给的运行命令是streamlit run ./Comment_analysis/Streamlit/streamlitEXP.py这条命令有两个容易翻车的点。第一必须在项目根目录执行因为脚本内部大概率用了相对路径去读 CSV换目录就会FileNotFoundError。第二streamlit要在虚拟环境激活状态下调用否则会用到全局环境里缺失依赖的解释器。稳妥做法是先确认脚本里的数据路径# 在 streamlitEXP.py 顶部通常会看到类似这样的读取 import pandas as pd import os BASE_DIR os.path.dirname(os.path.abspath(__file__)) data_path os.path.join(BASE_DIR, .., .., spider_comments_34000.csv) df pd.read_csv(data_path, encodingutf-8-sig)如果原脚本用的是硬编码相对路径建议改成上面这种基于__file__的写法这样无论从哪个目录启动都不会找不到文件。改完再跑streamlit run浏览器会自动打开localhost:8501看到界面才算真正跑通。3. 情感分析与主题建模从snownlp打分到 LDA 主题数怎么定3.1 用snownlp做情感打分分数怎么解读、阈值怎么设snownlp的中文情感分析返回的是 0 到 1 之间的浮点数越接近 1 越正面越接近 0 越负面。它底层用的是朴素贝叶斯在商品评论这种短文本上够用但别指望它像 BERT 那么准。核心代码from snownlp import SnowNLP import pandas as pd def get_sentiment(text): 返回情感分数异常文本返回 None try: return SnowNLP(str(text)).sentiments except Exception: return None df pd.read_csv(spider_comments_34000.csv, encodingutf-8-sig) df df.dropna(subset[content]) # 只取前 5000 条做演示全量跑 snownlp 会比较慢 df_sample df.head(5000).copy() df_sample[sentiment] df_sample[content].apply(get_sentiment) # 按 0.5 为界划分正负也可以按 0.4 / 0.6 做三分类 df_sample[label] df_sample[sentiment].apply( lambda x: 正面 if x and x 0.6 else (负面 if x and x 0.4 else 中性) ) print(df_sample[label].value_counts())参数说明阈值 0.6 和 0.4 不是固定的正文里提到“评论分数和评论内容不吻合”这时候就要拿score列和sentiment列做交叉验证。比如评分 5 星但情感分低于 0.4 的评论往往是“好评返现”或者反讽这批数据单独拎出来看能发现很多有意思的噪声。snownlp全量跑 3.4 万条大概要几分钟建议先采样调试确认逻辑没问题再全量。3.2 LDA 主题建模主题数怎么选、pyLDAvis怎么看LDA 是无监督的主题数K需要你自己定。正文里提到“参数优化主题数”这是 LDA 最核心的调参点。常见做法是用困惑度perplexity或一致性coherence来辅助判断但更实用的是直接看pyLDAvis的图主题之间重叠少、每个主题的关键词区分度高就是合适的K。import jieba from gensim import corpora, models import pyLDAvis.gensim_models # 1. 分词并去停用词 stopwords set(open(stopwords.txt, encodingutf-8).read().split()) texts [] for content in df_sample[content].astype(str): words [w for w in jieba.lcut(content) if w not in stopwords and len(w) 1] texts.append(words) # 2. 构建词典和语料 dictionary corpora.Dictionary(texts) corpus [dictionary.doc2bow(text) for text in texts] # 3. 训练 LDAK 先设 5num_topics 可调 lda models.LdaModel(corpus, num_topics5, id2worddictionary, passes10, random_state42) # 4. 打印每个主题的关键词 for idx, topic in lda.print_topics(num_words8): print(f主题{idx}: {topic}) # 5. pyLDAvis 可视化会生成一个 HTML vis pyLDAvis.gensim_models.prepare(lda, corpus, dictionary) pyLDAvis.save_html(vis, lda_vis.html)参数说明passes10是训练轮数太小主题不稳定太大耗时random_state42保证结果可复现这在课程大作业里很重要答辩时同一个K能跑出同样结果。num_topics从 3 试到 8每次看pyLDAvis左侧气泡是否分散、右侧关键词是否语义集中。如果两个主题关键词高度重合说明K偏大如果所有评论都挤在一个主题里说明K偏小。正文里提到的“外形外观”“售后服务”这类具体关键词就是通过这一步从主题词里读出来的。3.3 词云与可视化wordcloud中文乱码怎么解词云是课程大作业里最讨喜的可视化但中文词云十有八九会碰到方块乱码。根因是wordcloud默认字体不支持中文必须指定font_pathfrom wordcloud import WordCloud import matplotlib.pyplot as plt # 把所有评论拼成一个长字符串 all_text .join(df_sample[content].astype(str)) wc WordCloud( font_pathC:/Windows/Fonts/simhei.ttf, # Windows 用黑体 # font_path/System/Library/Fonts/PingFang.ttc, # macOS 用苹方 background_colorwhite, width1200, height800, max_words200 ).generate(all_text) plt.figure(figsize(12, 8)) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.savefig(wordcloud.png, dpi150, bbox_inchestight)参数说明font_path必须指向一个真实存在的中文字体文件Linux 服务器上如果没有中文字体需要先装fonts-noto-cjk之类的包。max_words200控制显示词数太多会糊成一团。这一步产出的wordcloud.png可以直接放进课程报告配合 LDA 主题词一起说明“用户最关心什么”。4. 避坑与常见问题这几处不处理答辩现场容易翻车4.1 现象streamlit run报ModuleNotFoundError: No module named snownlp原因虚拟环境没激活或者依赖装到了全局 Python 里streamlit调用的是另一个解释器。解决先which pythonWindows 用where python确认当前解释器路径在项目 venv 下再pip install snownlp装完重启streamlit。如果还不行用python -m streamlit run ...强制走当前解释器。4.2 现象读 CSV 报KeyError: 评论内容或列名带\ufeff原因Excel 另存为 CSV 时默认带 UTF-8 BOMpandas 用utf-8读会把 BOM 读进第一个列名。解决统一用encodingutf-8-sig或者在读取后df.columns df.columns.str.replace(\ufeff, )清洗一遍。这个坑在正文提到的多份 CSV 之间切换时特别常见因为不同来源的文件编码可能不一致。4.3 现象snownlp情感分和评分严重不符5 星评论打出 0.1 分原因snownlp训练语料偏新闻和通用文本对电商短评里的网络用语、反讽、方言不敏感。解决不要直接拿情感分当结论而是把它和score列做交叉表把“高分低情感”和“低分高情感”的评论单独导出人工看。正文里“评论分数和评论内容的不吻合问题”正是这个点处理好了反而是报告里的亮点而不是 bug。4.4 现象LDA 每次跑出来的主题词都不一样原因LDA 是概率模型初始化随机passes太小也会导致不稳定。解决固定random_state把passes提到 10~20并在报告里说明“在固定随机种子下结果可复现”。如果答辩要求展示稳定性可以跑 3 次不同种子取主题词交集作为最终主题描述。4.5 现象pyLDAvis保存的 HTML 打开是空白原因pyLDAvis依赖的 JS 资源默认从 CDN 加载离线环境或网络受限时页面渲染不出来。解决在save_html时加open_browserFalse或者把pyLDAvis的notebook参数设为False生成独立 HTML如果仍然空白检查gensim和pyLDAvis版本是否匹配两者版本差异过大会导致数据格式不兼容。5. 进阶改造把这份课程作业变成能讲出差异化的作品5.1 用texthero和pyLDAvis做可视化增强正文里提到texthero可视化它的优势是把文本清洗、TF-IDF、PCA 降维、K-means 聚类串成几行代码适合在报告里快速展示“评论可以自动聚成几类”。常见做法是先用texthero做一版聚类散点图再用 LDA 做主题词解释两者互相印证。pyLDAvis则负责把主题模型变成可交互网页答辩时直接打开 HTML 演示比静态截图有说服力。5.2 用装饰器统一计时和日志正文里专门提到“装饰器计时、log注解”这是工程规范加分项。我一般会写一个通用装饰器套在情感打分和 LDA 训练函数上import time import logging logging.basicConfig(levellogging.INFO, format%(asctime)s - %(message)s) def timer_log(func): def wrapper(*args, **kwargs): start time.time() result func(*args, **kwargs) cost time.time() - start logging.info(f{func.__name__} 耗时 {cost:.2f} 秒) return result return wrapper timer_log def run_sentiment(df): # 情感分析逻辑 return df这样跑全量 3.4 万条时日志里能清楚看到每一步耗时方便定位瓶颈。正文里“统一规范代码格式数据库完善注释log”这条要求用装饰器是最省事的落地方式。5.3 从snownlp升级到 BERT 情感分类如果想让报告有“算法优化与提升”的章节可以把snownlp换成 BERT 微调。常见做法是用transformers加载中文预训练模型在已有正负样本上微调二分类。代价是需要 GPU 或较长时间 CPU 训练但准确率提升明显尤其对反讽和长评论。对比实验可以写成表格同一批测试集上snownlp准确率 vs BERT 准确率再分析差异样本。这一步做完课程大作业的深度就和其他只跑snownlp的同学拉开了。5.4 跨年份对比2019 与 2020 评论的主题迁移正文里“同一个热水器的评论内容随时间变化”是个很好的切入点。把spider_meidi_comments2019.csv和spider_meidi_comments2020.csv分别跑 LDA对比主题词变化2019 年可能集中在“安装”“加热速度”2020 年可能更多出现“智能控制”“售后响应”。这种时间维度的对比不需要复杂模型但能让报告从“做了个分析”变成“发现了趋势”。我自己的习惯是每次拿到新数据集先按时间切一刀再看主题分布往往比单纯堆模型更能讲出故事。从那以后我每次跑这类评论分析都会先把编码、路径、随机种子这三件事固定死再动模型参数——这三处不稳后面所有结论都是空中楼阁。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?