资讯详情

淘宝评论情感分析实战:从爬虫到SVM与LSTM模型对比

📅 2026/10/14 8:01:56 | 华诺云谱 👁 阅读
淘宝评论情感分析实战:从爬虫到SVM与LSTM模型对比
简介这是一份用于毕业设计的机器学习项目聚焦电商淘宝商品评论情感分析适合计算机相关专业学生完成课程设计、大作业或毕业设计。项目基于自动化工具模拟真实登录爬取淘宝评论完成数据清洗、分词、词向量构造等预处理再分别构建支持向量机与长短期记忆网络两种分类模型进行效果对比完整覆盖从数据采集、特征工程到模型评估的流程。资源共四十三个文件压缩包约六十六兆字节包含十四个脚本、七个数据表格、四个数组、三个模型文件、两个神经网络模型以及配置、界面、驱动等辅助文件代码与数据集均打包在内。目前已有三百八十三人学习下载。解压后即可运行既可查看爬虫、预处理、模型训练与可视化脚本也可直接调用训练好的词向量和分类模型内置界面模块能直观演示情感分类结果帮助理解完整实现思路也为答辩展示提供可操作案例。1. 机器学习做淘宝评论情感分析从爬虫到模型对比的完整闭环情感分析在电商场景里的价值很直接商品评论是用户用脚投票的结果但一条条读人工标注成本太高于是用机器学习把「好评/中评/差评」自动分出来就成了毕设和工程实践的经典题目。这份项目源码最大的特点不是某个模型调得多花哨而是把「爬取评论 → 数据清洗 → 分词向量化 → SVM/LSTM 对比 → GUI 展示」整条链路都跑通了而且是基于淘宝真实评论数据做的。评审能拿 97 分靠的正是数据真实、流程完整、对比实验有说服力。适合两类人一是做毕设或课程设计需要一套可运行参考实现的在校生二是想快速上手中文情感分析全流程的从业者——你把模型文件换成自己的数据照样能跑通。2. 数据从哪来Selenium 模拟登录与淘宝评论爬虫的设计思路2.1 为什么选 Selenium 而不是 requests淘宝的商品评论接口有反爬策略直接拿 requests 构造请求要么被校验 cookie 和签名挡回来要么拿到的还是经过混淆的数据。常见的做法是用 Selenium 驱动真实浏览器让服务器以为你是正常用户。它的逻辑简单粗暴浏览器能加载的页面Selenium 就能拿到——这是 requests 方案不具备的兜底能力。项目里review_crawler目录下的crawler.py承担了核心爬取逻辑chromedriver是配套的驱动文件。要注意的是Chromedriver 版本必须和你本机的 Chrome 浏览器版本匹配否则启动就会报SessionNotCreatedException。我一般会先在命令行跑一句chrome://version确认浏览器版本号再下载对应的驱动省得来回换。2.2 登录态保持与滚动加载淘宝评论是动态加载的下拉页面才会分批请求数据。模拟登录之后关键点是不要关掉浏览器会话——Selenium 在同一个 driver 实例里会保持 cookie所以整个爬取过程应该在一个会话里完成不要中途重启。from selenium import webdriver from selenium.webdriver.chrome.options import Options import time options Options() options.add_argument(--disable-blink-featuresAutomationControlled) options.add_experimental_option(excludeSwitches, [enable-automation]) driver webdriver.Chrome(optionsoptions) driver.get(https://login.taobao.com/) # 人工扫码登录登录完成后按回车继续 input(请完成登录后按回车继续...) # 进入商品详情页后循环滚动加载评论 for i in range(10): driver.execute_script(window.scrollTo(0, document.body.scrollHeight)) time.sleep(2)这段代码里两个参数值得单独说。AutomationControlled去掉之后能降低被识别成自动化工具的概率excludeSwitches同理。滚动次数和time.sleep的间隔是经验值太快会被限流太慢浪费时间——实测 2 秒间隔、滚动 10 次左右能覆盖大部分评论列表。注意模拟登录只是保持正常浏览器行为不要通过任何方式绕过平台的风控机制。如果长时间大量抓取IP 可能被临时限制这是平台的正常保护策略。2.3 爬下来的数据长什么样项目里data目录存了review.csv、pos.xls、neg.csv、neutral.csv等文件。爬下来的原始评论会先落成 csv后续清洗和标注都用这份作为输入。文本内容一般是用户评论文案、评分、评论时间三个字段其中评分是情感标注的天然标签4~5 星归 positive3 星归 neutral1~2 星归 negative。3. 文本预处理与向量化从“废话连篇”到 Word2vec 能吃的数字3.1 去噪规则标点、纯数字、无意义叠词淘宝评论里「666666」「好好好好好」「哈哈哈哈」这类内容占比不小它们对情感判断没有贡献却会干扰词频统计和向量训练。项目review_treatment目录下的review_pretreatment.py做的事就是先过滤掉这类噪声。import re import jieba def clean_comment(text): # 去掉所有标点符号只保留中英文和数字 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , text) # 如果清洗后全是相同字说明是叠词或纯数字直接丢弃 if len(set(text)) 1: return # 长度过滤过短的评论没有分析价值 if len(text) 2: return return text这里有个容易被忽略的细节len(set(text)) 1这一步。像「666」去掉标点后是三个 6set去重后只剩一个字符说明是纯数字无意义内容「好好好」同理。这个规则比单纯按长度截断更精准。3.2 jieba 精确模式分词与自定义词典分词环节用的是 jieba 的精确模式因为评论文本短精确模式能保留更完整的语义单元。淘宝场景里有大量品牌名、商品属性词jieba 默认词典可能不认识所以需要add_word或load_userdict做补充。import jieba jieba.setLogLevel(20) # 关闭日志输出避免刷屏 def tokenize(text): words jieba.lcut(text.strip(), cut_allFalse) # 去掉单字词和纯空白 return [w for w in words if len(w) 1 and w.strip()]cut_allFalse就是精确模式它相比全模式会做更合理的切分比如「性价比高」不会被切成「性价」「价比」。单字过滤是个经验操作中文里单字词大多没有情感极性留着只会增加向量维度。3.3 Word2vec 训练把词变成有语义的向量模型目录里的comment_text.model和Word2vec_model.pkl就是训练好的向量模型。训练用的是 gensim 的 Word2vec关键参数有几个。from gensim.models import Word2Vec sentences [tokens for tokens in corpus] model Word2Vec( sentencessentences, vector_size200, window5, min_count3, sg1, workers4, epochs15 ) model.save(comment_text.model)参数含义vector_size200是词向量维度评论领域 200 维够用太高反而容易过拟合window5表示上下文窗口5 个词以内的共现关系都会被学习min_count3表示出现次数少于 3 次的词直接丢弃这是去低频噪声的主要手段sg1表示使用 Skip-gram 而不是 CBOWSkip-gram 在小数据集上对低频词更友好epochs15是迭代轮数淘宝评论这种短文本 10~15 轮基本就收敛了。Model 训练完还只是「词 - 向量」的映射句子还需要进一步处理。项目的做法是先建立词索引字典再把每个句子里的词映射成索引序列最后通过comment_text.vector保存统一格式的向量数据。这一步是给后边的 LSTM 准备的——SVM 需要固定长度的向量LSTM 需要变长序列所以两份特征要分别导。4. SVM 与 LSTM 对比实验为什么两个都跑而不是只挑一个4.1 SVM小样本上的稳定基线SVM 在文本分类里是老牌选手它的逻辑是把文本向量映射到高维空间找超平面。在评论情感分析场景下SVM 的优势是训练快、可解释性强、在小数据集上不容易翻车——对毕设项目来说它是保证「能跑出结果」的底线模型。svm目录下train_svm.py用词向量均值池化作为输入。做法是把一句话里所有词的向量做平均得到一条固定长度的特征向量再送去训练。from sklearn.svm import SVC from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report import numpy as np def sentence_to_vec(word_vectors, tokens, vector_size200): vec np.zeros(vector_size) count 0 for token in tokens: if token in word_vectors: vec word_vectors[token] count 1 if count 0: vec / count return vec X np.array([sentence_to_vec(w2v, tokens) for tokens in train_tokens]) y np.array(train_labels) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) clf SVC(kernellinear, C1.0, probabilityTrue) clf.fit(X_train, y_train) y_pred clf.predict(X_test)stratif分层采样这步很关键。评论数据里好评通常占大半差评很少如果不做分层测试集里很可能一个差评都分不到准确率虚高。C1.0是正则化强度的倒数默认值在文本分类上是合理起点一般不需要特意调。kernellinear对高维稀疏文本特征更合适RBF 核反而容易过拟合。SVM 在这个项目里的预期准确率大概能到 80%~85% 左右具体看数据的类别均衡程度如果差评样本特别少准确率会虚高但召回率很难看。4.2 LSTM捕获上下文顺序的升级版LSTM 能记住句子里的时序信息像「没有想象的那么好」这种句子SVM 的均值池化会把「没有」「想象」「好」的向量平权加在一起情感极性被稀释LSTM 却能通过门控机制学到「没有」对「好」的否定作用所以准确率上限更高。项目里lstm目录的train_lstm.py是主训练脚本它依赖前面处理好的词索引序列每句话变成一个长度不等的时间步序列。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout from tensorflow.keras.preprocessing.sequence import pad_sequences max_len 100 # 统一序列长度 X_train_seq pad_sequences(X_train_idxs, maxlenmax_len, paddingpost, truncatingpost) X_test_seq pad_sequences(X_test_idxs, maxlenmax_len, paddingpost, truncatingpost) model Sequential() model.add(Embedding(vocab_size, 200, input_lengthmax_len)) model.add(LSTM(128, return_sequencesFalse)) model.add(Dropout(0.5)) model.add(Dense(3, activationsoftmax)) model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) model.fit(X_train_seq, y_train, batch_size64, epochs10, validation_split0.1)pad_sequences是 LSTM 训练的必要步骤LSTM 要求一个 batch 内的序列等长所以短句补零、长句截断。paddingpost是在句子后边补 0truncatingpost是从尾部截断这两个参数保持方向一致很重要——如果 padding 在后而 truncating 在前序列内容会错位模型学到的位置信息就是乱的。Embedding 层vocab_size要根据词表大小设置可以先算一个len(word_index) 1如果不加 1索引最大值取不到训练时容易越界。LSTM 单元数 128 对 3 分类的中等规模数据集来说是比较稳的选择小于 64 会欠拟合大于 256 在小样本上就开始过拟合。4.3 两个模型的对比结论怎么看项目在draw_plot.py里画了准确率曲线和训练日志对比图这个对比的价值不只是「LSTM 更高」一句话。从工程实践角度看SVM 训练耗时是秒级LSTM 是分钟级到小时级SVM 调参维度少LSTM 需要调的 batch、epoch、dropout 都是变量。这份资源帮你把两条路都铺好了你可以直接改数据量大小去对比两个模型在样本增删时的表现差异写进论文里就是很好的实验章节素材。5. 避坑指南运行这份源码最容易翻车的四个地方5.1 路径问题相对路径在不同机器上直接崩溃现象运行train_lstm.py时报FileNotFoundError提示找不到comment_text.model或data/pos.xls。原因项目里的文件引用很多是相对路径在作者的目录结构下没问题但解压后如果直接挪到别的路径相对路径就断了。毕设项目常见这个问题因为它固定跑在一台机器上。解决解压后保持目录结构原样不要单独把某个文件夹拖出来。如果还是报错在运行脚本前先打印一下当前工作目录确认是不是在项目根目录下执行的。python -c import os; print(os.getcwd())5.2 Python 版本与依赖不匹配现象crawler.py里 Selenium 启动报错或者 gensim 导入失败。原因Selenium 4 的 API 和 Selenium 3 不兼容gensim 4.x 移除了部分旧的调用接口tensorflow 2.x 和 1.x 的函数路径也有差异。作者环境大概率是 Python 3.7~3.9 配上 gensim 3.x 和 tensorflow 2.x。解决建议直接建一个专用虚拟环境先装requirements.txt里的版本遇到报错再去搜具体的 API 迁移说明不要用最新版本强行跑。python -m venv venv source venv/bin/activate # Windows 下用 venv\Scripts\activate pip install -r requirements.txt5.3 中文编码问题Windows 下读 csv 乱码现象pd.read_csv(data/neg.csv)读出来全是乱码或者UnicodeDecodeError。原因csv 文件可能是 UTF-8 编码但 Windows 默认用 GBK 打开反之亦然。这是中文数据处理最常见的老坑。解决统一指定编码读取不要依赖系统默认。import pandas as pd df pd.read_csv(data/neg.csv, encodingutf-8)如果这样还报错就用encodinggbk试一下总有一个是对的。实在不行的用记事本或 VS Code 打开文件另存为 UTF-8 再去处理。5.4 模型文件版本和代码不一致现象load_model(lstm_new.h5)提示结构不匹配或者预测结果全是一类。原因项目里同时存在lstm_three.h5、lstm_new.h5两个模型文件可能是不同训练轮次保存的。代码里model_test.py默认加载的是哪一个需要仔细看代码不要凭文件名猜。解决打开model_test.py确认模型加载路径再对比训练脚本里model.save的路径保持二者一致。如果加载的模型类别数是 3但你的测试数据只有两类softmax 输出就会异常这也是预测结果「全是一类」的常见原因。提示运行测试脚本时记得先确认模型是「三分类」还是「二分类」项目里有neutral.csv说明是分了三类。如果不想处理中评可以把 neutral 数据并到差评里重新训练效果不好说但流程能跑通。6. 把模型真正用起来GUI 封装与单条评论预测的落地技巧GUI/main_page.py把训练好的模型封装成了可视化界面你可以在文本框里输入一条评论点击按钮立刻得到情感分类结果。这在答辩演示时很有存在感——评委看到的不只是训练日志而是「能用的程序」。模型推理的关键在文本预处理要和训练时完全一致。很多人预测效果差不是模型问题而是推理时的预处理流程和训练时对不上——训练时清洗了标点、过滤了停用词预测时没清洗特征空间就错位了。def predict_single(text): text clean_comment(text) # 同一套清洗逻辑 tokens tokenize(text) # 同一套分词逻辑 seq [word_index.get(w, 0) for w in tokens] # 不在词表里的词用 0 填充 seq_padded pad_sequences([seq], maxlen100, paddingpost, truncatingpost) prob model.predict(seq_padded)[0] label int(np.argmax(prob)) return [负面, 中性, 正面][label], dict(zip([负面, 中性, 正面], prob))word_index.get(w, 0)这个兜底值得单独讲预测时遇到训练词表里没有的词如果直接忽略句子会残缺如果默认映射 0 号索引Embedding 层会把它当内部词处理模型不会崩。这是最稳妥的处理方式。验证模型效果时我习惯做一个小测试找 20 条没参与训练的真实评论10 条明显正面、10 条明显负面逐条预测。如果 20 条里错 3 条以上先别急着调模型回头检查预处理是否一致如果错的都是「中性」误判那大概率是数据标注的边界问题不属于 bug。批量验证可以用项目里的test_set.csv这是一份独立于训练集的验证数据跑通之后你对模型的泛化能力会有更直观的认知。这种「拿一批没见过的数据过一遍」的做法比盯着一屏训练日志踏实得多。从那以后我每次拿到类似的文本分类项目都强制自己先写一个预测脚本、走一遍单条推理再碰训练代码——能落地的模型胜过只停留在训练曲线里的高分。希望这些细节能帮你在复现这套项目的时候少绕几个弯子。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑