
简介这是一份面向计算机相关专业学生与项目实战学习者的深度学习课程设计资料围绕电影评论情感分析展开可用于课程设计、期末大作业或自学练手。资源包共14个文件包含csv数据集、txt文本语料、ipynb实验笔记、py源码脚本、pdf总结报告与pptx答辩演示压缩包约21.28MB覆盖从数据采集、模型训练到测试评估的完整流程。内容预览显示项目包含豆瓣电影评论数据、爬虫脚本、模型训练与测试代码以及一份项目总结报告便于读者理解情感分析任务的实现思路与实验组织方式。目前已有287人学习下载适合希望快速搭建情感分析项目、参考完整代码结构与报告写法的学习者使用。1. 一份能跑通的豆瓣影评情感分析项目到底长什么样豆瓣影评这种短文本情感极性往往藏在“还行吧”“也就那样”这种模糊表达里纯靠词典规则去判准确率经常卡在七成上下晃。这份 Python 深度学习电影评论情感分析项目走的是另一条路用爬虫把豆瓣 Top250 的评论抓下来清洗成二分类语料再喂给深度学习模型训练最后拿测试集验证效果。整套东西包含爬虫脚本、训练与测试 notebook、五万条评论原始数据、处理后的 CSV还有一份项目总结报告 PDF 和答辩 PPT。它适合正在做课程设计、期末大作业的计算机专业学生也适合想拿一个完整文本分类流程练手的人。你拿到手不是一堆散文件而是一条从数据采集到模型评估的闭环链路能直接复现也能拆开改。2. 数据从哪来爬虫脚本与豆瓣评论采集的边界2.1 先看清数据文件的分工拿到压缩包解压后别急着打开 notebook 就跑。先花两分钟把目录结构理一遍后面调参和排错会省很多事。这个项目的文件大致分四类爬虫相关、原始数据、处理后的数据、模型代码与文档。文件/目录作用使用顺序crawler/urls.txt待抓取的豆瓣电影条目链接爬虫输入crawler/豆瓣top250电影urls.txtTop250 电影链接集合爬虫输入crawler/豆瓣top250评论5w条.txt抓取落地的原始评论爬虫输出crawler/crawler.ipynb爬虫主逻辑 notebook第一步运行data/remaining_data_2type.csv二分类剩余语料训练备用data/test_data1_2type.csv二分类测试集评估用data/test_data.csv通用测试数据评估用data/output.csv模型输出结果结果查看code/model_train.ipynb模型训练主程序第二步运行code/model_test.ipynb模型测试与评估第三步运行豆瓣电影评论情感分析项目总结报告.pdf设计说明与结论写报告参考豆瓣电影评论情感分析.pptx答辩演示答辩参考提示先确认crawler和data、code三个目录的相对位置没被解压工具打乱notebook 里读文件的路径大多是相对路径目录一乱就报 FileNotFoundError。2.2 爬虫逻辑与请求节奏控制豆瓣对高频请求是有风控的直接循环猛拉轻则返回空页重则 IP 被临时限制。这个项目的爬虫 notebook 里核心是构造条目页 URL、解析评论列表、翻页、落盘这几步。下面这段是常见写法的骨架你可以对照自己的 crawler.ipynb 看结构是否一致。import requests import time import random import pandas as pd from bs4 import BeautifulSoup HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36 } def fetch_comments(movie_id, start0, limit20): # start 控制翻页起点豆瓣每页默认 20 条 url fhttps://movie.douban.com/subject/{movie_id}/comments?start{start}limit{limit}statusP resp requests.get(url, headersHEADERS, timeout10) if resp.status_code ! 200: return [] soup BeautifulSoup(resp.text, html.parser) items soup.select(div.comment-item) results [] for it in items: try: content it.select_one(span.short).text.strip() results.append(content) except AttributeError: continue return results all_comments [] for mid in [1292052, 1291546, 1292720]: # 示例电影 id for page in range(0, 200, 20): # 每部抓 10 页 batch fetch_comments(mid, startpage) all_comments.extend(batch) time.sleep(random.uniform(1.5, 3.5)) # 随机间隔降低被封风险 pd.Series(all_comments).to_csv(豆瓣top250评论5w条.txt, indexFalse, headerFalse)逻辑说明fetch_comments负责单页抓取start参数是翻页偏移量豆瓣评论页每页 20 条所以循环步长设 20。time.sleep加随机区间是血泪经验固定间隔反而容易被识别成脚本。参数上timeout10防止某次请求卡死整个循环statusP表示只看正常状态评论。落盘用to_csv存成纯文本方便后面按行读取做清洗。2.3 原始评论到二分类语料的清洗抓下来的评论是纯文本没有标签。这个项目用的是星级映射法豆瓣评论自带评分五星和四星归为正面一星和二星归为负面三星这种中性样本直接丢弃避免模型学到模棱两可的边界。清洗环节要处理掉表情符号、URL、多余空白还要过滤掉太短的评论。import re import pandas as pd def clean_text(text): text re.sub(rhttp\S, , text) # 去 URL text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9。], , text) # 只留中英文数字和常用标点 text re.sub(r\s, , text).strip() return text df pd.read_csv(豆瓣top250评论5w条.txt, headerNone, names[comment]) df[comment] df[comment].astype(str).apply(clean_text) df df[df[comment].str.len() 5] # 过滤过短样本 df.to_csv(data/remaining_data_2type.csv, indexFalse)逻辑说明正则第一条去链接第二条把非中英文数字和常用标点的字符清掉这一步会顺带干掉大部分表情。str.len() 5是经验阈值太短的评论比如“好看”两个字信息量不足以支撑训练。参数上标点白名单可以根据你的语料再调比如保留省略号有助于捕捉犹豫语气。3. 模型怎么搭从词向量到训练循环的落地细节3.1 文本向量化方案的选择理由中文短文本做情感分析常见做法有两种一种是先分词再训词向量另一种是直接用字符级序列。这个项目的训练 notebook 里走的是分词加词向量的路线因为影评里“演技”“剧情”“拖沓”这类词的情感指向很明确分词后词粒度特征更干净。分词工具用 jieba词向量可以用预训练的中文词向量也可以在自己的语料上训一个。import jieba import numpy as np from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences def tokenize(text): return .join(jieba.lcut(text)) df[seg] df[comment].apply(tokenize) MAX_WORDS 20000 # 词表上限 MAX_LEN 100 # 每条评论截断/补齐长度 tokenizer Tokenizer(num_wordsMAX_WORDS, oov_tokenUNK) tokenizer.fit_on_texts(df[seg]) sequences tokenizer.texts_to_sequences(df[seg]) X pad_sequences(sequences, maxlenMAX_LEN, paddingpost, truncatingpost)逻辑说明num_words20000是词表上限超出部分按频率截断影评语料五万条左右两万词表基本够用。MAX_LEN100是序列长度短评论补零长评论截断paddingpost表示在尾部补和后面 Embedding 层的输入习惯保持一致。参数怎么改如果你的语料更长比如长影评MAX_LEN可以提到 200 到 300但显存和训练时间会跟着涨。3.2 模型结构与训练参数配置模型主体用 Embedding 加双向 LSTM 加全连接这是文本分类里比较稳的结构比纯 CNN 更能捕捉语序信息又比 Transformer 轻量适合课程设计这种算力有限的环境。下面这段是训练脚本的核心部分。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, Bidirectional, LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping EMBED_DIM 128 model Sequential([ Embedding(MAX_WORDS, EMBED_DIM, input_lengthMAX_LEN), Bidirectional(LSTM(64, return_sequencesFalse)), Dropout(0.5), Dense(64, activationrelu), Dropout(0.3), Dense(1, activationsigmoid) # 二分类输出 ]) model.compile(optimizeradam, lossbinary_crossentropy, metrics[accuracy]) model.summary() early_stop EarlyStopping(monitorval_loss, patience3, restore_best_weightsTrue) history model.fit( X_train, y_train, validation_split0.2, epochs20, batch_size64, callbacks[early_stop] )逻辑说明EMBED_DIM128是词向量维度太小表达力不够太大容易过拟合128 在五万条语料上是个平衡点。双向 LSTM 的 64 个隐藏单元前后向各 64拼接后是 128 维。两个 Dropout 分别放在 LSTM 后和全连接后比例 0.5 和 0.3是防过拟合的常规操作。EarlyStopping的patience3表示验证损失连续三轮不降就停restore_best_weightsTrue保证拿回最优那轮的权重这个参数不加最后存的可能是过拟合的模型。3.3 训练过程监控与结果落盘训练跑起来后别只盯着最后那个准确率数字。history里存了每轮的训练损失、验证损失、训练准确率、验证准确率把这几条曲线画出来能看出模型是欠拟合还是过拟合。欠拟合表现为两条损失都高且降不下去过拟合表现为训练损失继续降但验证损失开始抬头。import matplotlib.pyplot as plt plt.plot(history.history[loss], labeltrain_loss) plt.plot(history.history[val_loss], labelval_loss) plt.legend() plt.savefig(loss_curve.png) # 测试集评估 loss, acc model.evaluate(X_test, y_test, batch_size64) print(ftest loss: {loss:.4f}, test acc: {acc:.4f}) # 预测结果落盘对应 data/output.csv preds (model.predict(X_test) 0.5).astype(int) pd.DataFrame({pred: preds.flatten(), label: y_test}).to_csv(data/output.csv, indexFalse)逻辑说明model.predict输出的是 0 到 1 之间的概率阈值 0.5 是默认切分点如果正面样本明显多于负面可以把这个阈值调低一点让更多样本判为正面具体调多少看验证集上的 F1。落盘的output.csv里同时存了预测值和真实标签方便你后面算混淆矩阵也方便写报告时贴结果。4. 跑起来会遇到的坑环境、路径与数据格式排查4.1 环境依赖版本对不上现象notebook 一运行就报ImportError: cannot import name pad_sequences或者 TensorFlow 相关模块找不到。原因这份项目用的是 TensorFlow 2.x 的 Keras 接口如果你本地装的是 TensorFlow 1.x或者 Keras 单独装了一个版本导入路径就对不上。解决统一用 TensorFlow 2.xpip install tensorflow2.10这类版本导入时写from tensorflow.keras.preprocessing.sequence import pad_sequences不要写from keras.preprocessing...。jieba、pandas、numpy 这些也建议按 notebook 里 import 的版本装避免 API 变动。4.2 相对路径导致文件读不到现象FileNotFoundError: [Errno 2] No such file or directory: data/test_data.csv。原因notebook 的工作目录和你解压后的目录不一致Jupyter 默认工作目录是启动时所在的文件夹不是 notebook 文件所在文件夹。解决在 notebook 开头加一段路径检查或者用绝对路径。稳妥做法是先import os; print(os.getcwd())看当前目录再用os.chdir()切到项目根目录或者把读文件路径改成基于 notebook 位置的相对路径。4.3 中文编码与 CSV 分隔符问题现象读 CSV 时报UnicodeDecodeError或者读进来发现所有列挤在一列里。原因豆瓣评论里可能混有特殊字符文件保存时编码不是 UTF-8另外 CSV 默认逗号分隔如果评论内容里本身带逗号列就会错位。解决读的时候显式指定encodingutf-8如果还报错就试encodingutf-8-sig或gbk。分隔符问题用pd.read_csv(..., sep\t)或sep,按实际文件调整落盘时用to_csv(..., indexFalse)避免多出一列索引。4.4 标签与预测值维度不匹配现象model.evaluate时报 shape 不匹配或者ValueError: logits and labels must have the same shape。原因二分类的标签如果是 one-hot 编码成两列而模型输出是单列 sigmoid维度就对不上。解决确认标签是 0/1 单列不是[1,0]这种两列。如果原始标签是字符串“正面/负面”先映射成 1/0。y_train和y_test的 shape 应该是(样本数,)或者(样本数,1)和模型输出对齐。4.5 训练轮数设太多导致过拟合现象训练准确率冲到 0.98测试准确率只有 0.82验证损失曲线后期明显抬头。原因影评语料里存在大量重复表达模型把训练集背下来了。解决EarlyStopping一定要加patience设 2 到 3。另外可以适当增大 Dropout 比例或者在 Embedding 层加dropout参数。数据层面检查一下训练集和测试集有没有重叠样本有的话去重。5. 报告与答辩怎么用把 notebook 结果转成能交的文档5.1 从 output.csv 到混淆矩阵与指标表课程设计报告里光写一个准确率是不够的评审老师更想看你对结果的拆解。data/output.csv里存了预测值和真实标签拿它算精确率、召回率、F1再画个混淆矩阵报告的技术含量就上来了。from sklearn.metrics import classification_report, confusion_matrix import seaborn as sns df_out pd.read_csv(data/output.csv) print(classification_report(df_out[label], df_out[pred], target_names[负面, 正面])) cm confusion_matrix(df_out[label], df_out[pred]) sns.heatmap(cm, annotTrue, fmtd, cmapBlues, xticklabels[负面, 正面], yticklabels[负面, 正面]) plt.xlabel(预测) plt.ylabel(真实) plt.savefig(confusion_matrix.png)逻辑说明classification_report会输出每个类别的精确率、召回率、F1 和支持度正面和负面分开看能发现模型是不是偏向某一类。混淆矩阵热力图直接贴进报告比纯文字描述直观。参数上target_names的顺序要和标签 0/1 对应0 对应负面1 对应正面别写反了。5.2 报告 PDF 与 PPT 的复用方式项目里那份“豆瓣电影评论情感分析”项目总结报告 PDF结构上一般包含选题背景、数据来源、模型设计、实验结果、结论几个部分。你可以把它当模板把里面的数据集规模、模型参数、准确率数字替换成你自己跑出来的结果。PPT 同理重点放三页数据采集流程、模型结构图、实验结果对比。答辩时老师最爱问的两个问题一是“为什么选 LSTM 不选 CNN”二是“准确率这么高是不是过拟合了”提前把损失曲线和混淆矩阵准备好回答就有底气。5.3 一个容易被忽略的验证习惯跑完训练别只看测试集准确率就收工。我一般会从原始五万条评论里随机抽二十条没进训练集的手动过一遍模型预测看看有没有明显判反的。这一步花不了几分钟但经常能发现测试集分布和真实分布不一致的问题。比如测试集里正面样本偏多模型就学会了倾向判正面实际用的时候负面评论会被漏掉。发现这种情况要么调整测试集采样要么在损失函数里给少数类加权。从那以后我每次交课程设计前都强制走一遍这个小样本人工抽检比盯着一个准确率数字踏实得多。希望帮到你。本文还有配套的精品资源点击获取