
简介本资源是一份面向高校人工智能课程设计与深度学习初学者的完整LSTM文本情感分析实践项目聚焦三分类正面/中性/负面任务适用于机器学习、自然语言处理相关课程大作业或毕业设计参考。压缩包共15个文件包含3个CSV格式标注数据集pos/neg/neutral、3个核心Python脚本数据预处理、模型训练与测试、2个Jupyter Notebook含可视化与结果分析、1个H5模型权重文件、1个Word2Vec词向量Pkl模型及README说明文档等整体大小11.79MB结构清晰、模块分工明确。已有154人学习下载内容覆盖从原始文本清洗、词嵌入构建、LSTM序列建模到Softmax三分类预测的全流程实现并附带requirements依赖清单与训练配置YAML文件便于环境复现与二次开发。1. 这不是调用 API 的情感分析而是能跑通、能改参数、能换数据的 LSTM 三分类落地工程你手头有一份标注好的中文评论数据正面/中性/负面想快速验证一个深度学习模型能否稳定区分这三类语义倾向——但又不想被 HuggingFace 的预训练模型黑盒裹挟也不愿从零写 Keras 层堆叠。这份python实现基于LSTM的三分类文本情感分析源码说明高分大作业.zip正是为这种场景设计的它不依赖云端服务全部本地运行模型结构清晰可调不是.pkl一键加载的黑箱训练、验证、预测流程完整闭环连deal.py里怎么清洗微博式口语化文本比如“绝了”、“还行吧…”、“太拉垮了”都写了具体正则和替换逻辑。适合课程设计复现、毕设基线搭建、或作为 NLP 入门项目理解序列建模本质。如果你需要的是「知道每个.py文件干什么、为什么用 Word2Vec 而不是直接 Embedding 层、lstm_train.py里 batch_size32 怎么影响显存占用」而不是「pip install xxx 后 run.py 就出结果」的玩具这份源码就是你要拆解的实体。2. 数据预处理与词向量构建从原始 CSV 到可喂入 LSTM 的张量2.1 原始数据结构解析与清洗逻辑项目目录中的neg.csv、neutral.csv、pos.csv是三类情感标签的纯文本集合每行一条评论无列名。打开neg.csv可见典型样本差评发货慢包装破损 客服态度恶劣商品与描述严重不符 物流三天才到盒子压扁了deal.py是核心清洗模块其关键操作并非简单去标点而是针对中文网络文本特性定制# deal.py 片段 import re import jieba def clean_text(text): # 保留中文、数字、常见标点用于判断语气强度 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9。【】《》、], , text) # 合并连续空格 text re.sub(r\s, , text).strip() # 替换口语化重复符号如啊啊啊→啊→ text re.sub(r([。])\1, r\1, text) text re.sub(r([a-zA-Z])\1{2,}, r\1, text) # 如 aaabbb → ab return text def segment_and_filter(text): words jieba.lcut(text) # 移除停用词项目自带 stopwords.txt含的、了、吗等287个 with open(stopwords.txt, r, encodingutf-8) as f: stops set(f.read().splitlines()) words [w for w in words if w not in stops and len(w) 1] return words注意jieba.lcut分词后未做词性过滤如不剔除助词、介词因为 LSTM 需要上下文完整性停用词表是手动精简过的比通用表更适配情感词例如保留很、非常、略等程度副词。2.2 Word2Vec 词向量训练与固化项目未使用预训练词向量如 Tencent AI Lab 的 8M 中文词向量而是用data目录下全部三类文本联合训练专属 Word2Vec 模型。deal.py中关键参数如下# deal.py 中 Word2Vec 训练部分 from gensim.models import Word2Vec sentences [] # 所有清洗后的分词列表 for csv_file in [neg.csv, neutral.csv, pos.csv]: with open(fdata/{csv_file}, r, encodingutf-8) as f: for line in f: if line.strip(): words segment_and_filter(line.strip()) if words: # 过滤空行 sentences.append(words) model Word2Vec( sentencessentences, vector_size100, # 词向量维度非越大越好100 是平衡精度与显存的常用值 window5, # 上下文窗口大小中文短句建议 3–5 min_count2, # 词频阈值过滤低频噪声词如错别字zhuangbility workers4, # 并行线程数匹配 CPU 核心数 sg1 # 使用 skip-gram对稀疏情感词更敏感比 CBOW 更适合小数据集 ) model.save(Word2vec_model.pkl)训练后生成的Word2vec_model.pkl是二进制模型文件后续lstm_train.py通过gensim.models.KeyedVectors.load_word2vec_format()加载。需注意若新增测试文本含训练时未出现的词OOV代码中默认用零向量填充np.zeros(100)而非随机初始化——这避免了引入噪声但要求max_len设置合理见 2.3 节。2.3 文本序列化长度截断、补齐与张量生成LSTM 输入必须是固定长度的二维张量[batch_size, max_len, embedding_dim]。lstm_train.py中build_dataset()函数执行此转换# lstm_train.py 片段 def build_dataset(file_path, word2vec_model, max_len50): texts, labels [], [] label_map {neg: 0, neutral: 1, pos: 2} with open(file_path, r, encodingutf-8) as f: for line in f: if not line.strip(): continue # 清洗 分词复用 deal.py 逻辑 words segment_and_filter(clean_text(line.strip())) # 转词向量存在则取向量不存在则补零向量 vectors [] for word in words[:max_len]: # 先截断再补齐避免长文本拖慢训练 if word in word2vec_model.wv: vectors.append(word2vec_model.wv[word]) else: vectors.append(np.zeros(word2vec_model.vector_size)) # 补齐至 max_len while len(vectors) max_len: vectors.append(np.zeros(word2vec_model.vector_size)) texts.append(np.array(vectors)) labels.append(label_map[os.path.basename(file_path).split(.)[0]]) return np.array(texts), np.array(labels) # 生成训练集 X_train, y_train build_dataset(data/train.csv, wv_model, max_len50)提示max_len50是经验值。查看data下所有文本分词后长度分布可用pandas.Series([len(jieba.lcut(x)) for x in texts]).describe()若 95% 文本长度 ≤42则设为 45 更省显存若大量长评论如电商评价需调高至 60 并相应降低batch_size。3. LSTM 模型构建与训练三层结构、Dropout 策略与损失函数选择3.1 Keras 模型架构详解lstm_train.py中create_model()定义了端到端网络结构如下非黑盒每一层作用明确# lstm_train.py 片段 from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout, GlobalMaxPooling1D def create_model(embedding_dim100, max_len50, num_classes3): model Sequential([ # 第一层 LSTM返回序列供第二层捕获长期依赖 LSTM(64, return_sequencesTrue, dropout0.3, recurrent_dropout0.3), # 第二层 LSTM不返回序列压缩为固定长度向量 LSTM(32, dropout0.3, recurrent_dropout0.3), # Dropout 防止过拟合LSTM 层后接 Dropout 是标准做法 Dropout(0.5), # 全连接层映射到三分类空间 Dense(32, activationrelu), Dropout(0.3), # 输出层3 个神经元对应三类softmax 确保概率和为 1 Dense(num_classes, activationsoftmax) ]) return model model create_model(embedding_dim100, max_len50) model.compile( optimizeradam, losssparse_categorical_crossentropy, # 标签为整数0/1/2时用此损失 metrics[accuracy] )关键参数设计原理参数值选型依据LSTM(64)64中文情感分析常用隐藏单元数低于 32 捕捉能力弱高于 128 显存压力陡增return_sequencesTrueTrue第一层输出序列使第二层 LSTM 能接收完整时间步特征dropout0.30.3输入门/输出门丢弃率过高0.5导致梯度消失过低0.2正则不足recurrent_dropout0.30.3循环连接上的 Dropout缓解 LSTM 内部过拟合Keras 2.0 支持sparse_categorical_crossentropy—标签为[0,1,2]整数而非 one-hot 编码节省内存且等价3.2 训练配置与早停策略训练过程在lstm_train.py中通过model.fit()执行关键配置如下# lstm_train.py 片段 from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint callbacks [ # 当验证损失连续 3 轮不下降时终止训练防过拟合 EarlyStopping(patience3, restore_best_weightsTrue), # 保存最优模型权重非整个模型因含自定义层时 save_model() 可能失败 ModelCheckpoint(model/lstm.h5, save_best_onlyTrue) ] history model.fit( X_train, y_train, batch_size32, # 显存友好值GTX 10606GB可跑 32RTX 309024GB可提至 64 epochs50, # 配合 EarlyStopping实际常 20–35 轮收敛 validation_split0.2, # 20% 数据作验证集无需额外划分文件 callbackscallbacks, verbose1 )注意validation_split0.2是按顺序切分若数据未打乱会导致验证集集中于某类如neg.csv在前则验证集全为负面。应在build_dataset()后添加np.random.shuffle()或改用sklearn.model_selection.train_test_split保证随机性。3.3 模型评估与混淆矩阵可视化训练完成后lstm_test.py加载lstm.h5并在测试集上评估。核心代码包含精确率、召回率、F1 分数计算# lstm_test.py 片段 from sklearn.metrics import classification_report, confusion_matrix import seaborn as sns y_pred model.predict(X_test) y_pred_classes np.argmax(y_pred, axis1) print(classification_report(y_test, y_pred_classes, target_names[Negative, Neutral, Positive])) # 绘制混淆矩阵 cm confusion_matrix(y_test, y_pred_classes) sns.heatmap(cm, annotTrue, fmtd, cmapBlues, xticklabels[Neg, Neu, Pos], yticklabels[Neg, Neu, Pos]) plt.ylabel(True Label) plt.xlabel(Predicted Label) plt.show()典型输出示例precision recall f1-score support Negative 0.87 0.82 0.84 120 Neutral 0.79 0.85 0.82 110 Positive 0.91 0.88 0.89 130 accuracy 0.86 360 macro avg 0.86 0.85 0.85 360 weighted avg 0.86 0.86 0.86 360提示若中性类 F1 显著低于其他两类如 0.65说明数据中性样本噪声大如“一般”、“还行”易被误判应检查neutral.csv是否混入模糊表达并在deal.py中增强中性词识别规则如加入“尚可”、“凑合”等词干。4. 模型部署与单条文本预测从 .h5 到可调用的 inference 接口4.1 加载模型与词向量的完整链路lstm_test.py不仅做评估更提供了生产级预测函数predict_sentiment()其依赖项加载逻辑严格对应训练时的预处理# lstm_test.py 片段 import numpy as np from tensorflow.keras.models import load_model from gensim.models import KeyedVectors def load_resources(): # 加载训练好的 LSTM 权重 model load_model(model/lstm.h5) # 加载 Word2Vec 模型注意.pkl 是 gensim 保存格式非 Keras wv_model KeyedVectors.load(Word2vec_model.pkl) return model, wv_model def predict_sentiment(text, model, wv_model, max_len50): # 复用 deal.py 的清洗与分词 cleaned clean_text(text) words segment_and_filter(cleaned) # 构造输入张量同训练时逻辑 vectors [] for word in words[:max_len]: if word in wv_model: vectors.append(wv_model[word]) else: vectors.append(np.zeros(wv_model.vector_size)) while len(vectors) max_len: vectors.append(np.zeros(wv_model.vector_size)) X np.array([vectors]) # 添加 batch 维度[1, max_len, 100] pred model.predict(X) class_idx np.argmax(pred, axis1)[0] confidence np.max(pred) label_map {0: Negative, 1: Neutral, 2: Positive} return label_map[class_idx], confidence # 使用示例 model, wv_model load_resources() text 这个手机拍照效果真不错电池也耐用 label, conf predict_sentiment(text, model, wv_model) print(f预测结果: {label}, 置信度: {conf:.3f}) # 输出: Positive, 0.921注意load_model(model/lstm.h5)要求 TensorFlow/Keras 版本与训练时一致项目requirements.txt指定tensorflow2.8.0。若升级到 TF 2.15需用tf.keras.models.load_model()并处理 HDF5 兼容性问题。4.2 实时预测性能优化技巧单条文本预测耗时约 15–30msGTX 1060但批量预测时可显著加速。lstm_test.py提供batch_predict()函数def batch_predict(texts, model, wv_model, max_len50, batch_size32): # 预处理所有文本为张量 X_batch [] for text in texts: cleaned clean_text(text) words segment_and_filter(cleaned) vectors [] for word in words[:max_len]: vectors.append(wv_model[word] if word in wv_model else np.zeros(wv_model.vector_size)) while len(vectors) max_len: vectors.append(np.zeros(wv_model.vector_size)) X_batch.append(vectors) X_batch np.array(X_batch) # 批量推理GPU 并行加速 preds model.predict(X_batch, batch_sizebatch_size) labels np.argmax(preds, axis1) confidences np.max(preds, axis1) label_map {0: Negative, 1: Neutral, 2: Positive} return [label_map[i] for i in labels], confidences.tolist() # 示例100 条文本一次预测 texts [很好, 太差了, 还行] * 33 [不错] labels, confs batch_predict(texts, model, wv_model)性能对比100 条文本方式耗时说明单条循环调用2.1s每次重建张量GPU 利用率低batch_predict()0.38s张量预分配 GPU 批处理提速 5.5 倍model.predict()直接传入预构造张量0.35s最优但需自行管理张量构建5. 模型调优与边界案例处理当 LSTM 对“反讽”和“多义词”失效时怎么办5.1 反讽文本的识别瓶颈与缓解方案LSTM 本质是序列统计模型对“今天天气真好热得像蒸笼”这类反讽无感知。项目未内置反讽检测但可通过以下低成本方式增强方案一规则层后处理推荐在predict_sentiment()返回结果后添加启发式规则def post_process(text, pred_label, confidence): # 检测反讽关键词 情感词矛盾 irony_keywords [真, 确实, 简直, 堪称, 活该, 恭喜] sentiment_words [好, 棒, 赞, 差, 烂, 垃圾] if any(kw in text for kw in irony_keywords) and any(sw in text for sw in [差, 烂, 垃圾]): if pred_label Positive: return Negative, confidence * 0.8 # 降置信度并翻转 return pred_label, confidence # 使用 label, conf predict_sentiment(text, model, wv_model) label, conf post_process(text, label, conf)方案二集成 BiLSTM-CRF进阶若需系统性解决可将 LSTM 替换为Bidirectional(LSTM())并在输出层加 CRF 解码需tensorflow-addons但会增加 30% 训练时间且需重标数据。5.2 多义词歧义处理以“苹果”为例“苹果手机很流畅” vs “苹果坏了不能吃”——同一词在不同领域语义相反。项目Word2vec_model.pkl是通用语料训练无法区分。解决方案方法操作效果领域词典注入在deal.py清洗后对特定词强制替换text text.replace(苹果, 苹果手机) if 手机 in text else text.replace(苹果, 水果苹果)简单有效适合垂直场景如只分析数码评论上下文感知嵌入用bert-base-chinese替代 Word2Vec但需 GPU 显存 ≥12GB 且训练时间 ×3精度提升 12%但失去轻量级优势双通道输入主 LSTM 处理原文辅助通道用 TF-IDF 提取关键词权重concat 后接 Dense工程复杂度中等精度提升 5–8%5.3 模型可解释性LSTM 注意力权重提取虽项目未提供注意力机制但可通过keras-vis库可视化关键 token 贡献度pip install keras-vis# 在 lstm_test.py 中添加 from vis.visualization import visualize_saliency from vis.utils import utils from keras import backend as K # 获取中间层输出LSTM 层 layer_idx utils.find_layer_idx(model, lstm_1) # 名称需与 model.summary() 一致 grads visualize_saliency(model, layer_idx, filter_indices2, seed_inputX_sample) # grads 是 [max_len] 数组值越大表示该词对 Positive 预测贡献越高 words segment_and_filter(clean_text(屏幕清晰色彩鲜艳)) for word, grad in zip(words, grads[:len(words)]): print(f{word}: {grad:.3f})输出示例屏幕: 0.124 清晰: 0.872 : 0.003 色彩: 0.651 鲜艳: 0.915这证实模型正确聚焦于“清晰”、“鲜艳”等正向形容词而非停用词“”。提示若发现模型关注错误词汇如“清晰”权重低“屏幕”权重高说明词向量空间中“屏幕”未与正向语义强关联应检查Word2vec_model.pkl训练语料是否覆盖足够多正向设备评价。本文还有配套的精品资源点击获取