☰
商品评论情感分析实战:从京东爬虫到机器学习模型全流程解析
2026/10/11 13:43:40 网站建设 项目流程

简介:围绕基于机器学习的商品评论情感分析,这份毕业设计压缩包面向计算机专业学生,可用于课程设计、毕设答辩或自然语言处理入门实战。项目涵盖评论爬取、数据清洗、分词、情感词典构建、词频-逆文档频率与词向量特征提取,以及朴素贝叶斯、支持向量机、极端梯度提升、长短期记忆网络等多种模型的训练与评估,并提供图形界面和可视化脚本,能展示完整的分析流程。

资源共43个文件、约66.66MB,以Python脚本、表格数据、模型文件及配置文档为主,包含14个Python程序、7个CSV数据文件、2个Excel表格和多个训练好的情感分类模型与词向量模型,适合直接运行和二次修改。目前已有167人学习下载。总体而言,这份压缩包覆盖从数据采集到报告撰写的完整环节,并补充了Git版本管理、超参数搜索等实践细节,是一份能支撑实际答辩和功能演示的毕业设计资料。

1. 情感分析不是看“好评/差评”那么简单:这个毕业设计到底在做什么

你可能以为“商品评论情感分析”就是把五星好评算正面、一星差评算负面,然后用机器学习算法跑一个准确率就完事。但真正动手抓过京东或淘宝评论的人都知道,评论区里充斥着“默认好评”的模板文本、和商品毫不相干的凑字评价、还有那种“物流很快但质量稀烂”的混合情感。这个基于机器学习的商品评论情感分析项目,核心不是模型有多深,而是你能不能把“用户到底对商品持什么态度”这件事,从一堆噪声里可靠地抽出来。它适合正在做机器学习课程设计或毕业设计的同学,也适合想入门 NLP 分类任务的从业者。本文把从爬虫、清洗、特征工程到模型调参与评估的完整链路拆开讲,给你一套能照着复现的落地方案。

2. 定技术路线:先想清楚数据从哪来、模型学到什么,再谈准确率

2.1 数据源选型:为什么“爬京东评论”是主流选择

这个项目的数据来源,常见做法是爬取京东商品评论。京东的评论区有一个半公开的 JSON 接口,比淘宝的反爬策略温和得多,返回字段结构化程度高,自带评分、追评时间、购买属性等元信息,非常适合做情感分析的初始数据集。而且京东评论区分“好评”“中评”“差评”三个标签页,方便你直接拿到标注数据做有监督学习。

爬虫的请求头里必须带上User-Agent和Referer,否则京东会返回 403。接口核心参数是productId(商品 ID)、score(0 全部 / 1 好评 / 2 中评 / 3 差评)、page和pageSize。要注意的是,京东这个接口单页最多返回 10 条评论,翻页超过一定深度会被风控拦截,所以做毕业设计的话,多换几个商品 ID 比死磕单商品翻页更稳妥。

当接口返回的commentsCount为 0 或code不为0时,说明被限流了,此时不要继续请求,退避 3 到 5 秒再试。代码里要保留原始响应文本,方便排查编码问题。抓下来的数据至少要有四个字段:评论内容、评分、点赞数、评论时间。评分是后文标注情感标签的基础,而点赞数可以作为“这条评论是否具有代表性”的辅助特征。

import requests import json import time def fetch_jd_comments(product_id, score=0, page=1, page_size=10): url = "https://club.jd.com/comment/productPageComments.action" params = { "productId": product_id, "score": score, "sortType": 5, # 按时间排序,保证每次抓取顺序稳定 "page": page, "pageSize": page_size, # 固定10,接口不接受更大的值 "isShadowSku": "0", "fold": "1", } headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Referer": f"https://item.jd.com/{product_id}.html", } resp = requests.get(url, params=params, headers=headers, timeout=15) data = resp.json() if data.get("code") != 0: print(f"page {page} 被限流,任务中止") return [] rows = [] for c in data.get("comments", []): rows.append({ "content": c.get("content", ""), "score": c.get("score"), "recommend": c.get("recommend", ""), "comment_date": c.get("creationTime", ""), "product_id": product_id, }) return rows if __name__ == "__main__": rows = fetch_jd_comments("100012043978", score=0, page=1) print(f"抓取到 {len(rows)} 条评论,示例内容: {rows[0]['content'][:30]}")

参数里sortType=5是按时间排序,如果不固定排序方式,翻页时可能拿到重复评论,影响后续去重统计。isShadowSku和fold这两个参数保持默认即可,基本不需要改动。建议把抓取结果实时落盘成 JSON 或 CSV,避免中途断网导致全部重跑。我一般会加一个断点续爬逻辑,用已抓取的文件行数作为下次抓取的起始页,但毕设规模的数据量通常不需要这么复杂,手动分段跑就够了。

2.2 分类粒度:二分类、三分类还是五分类

分类粒度决定了项目的工程复杂度和评估方式。最省事的是二分类:把评分 4 到 5 星视为正面,1 到 2 星视为负面,3 星直接丢弃。这样边界干净,类别均衡也好控制。但答辩时容易被老师追问“中评为什么不要”,所以如果你的数据量能支撑,建议做三分类:好评 / 中评 / 差评,对应评分 5 / 3 / 1,把 4 星和 2 星作为模糊地带并入相邻类别。

五分类看上去更细致,但负面样本通常不够,且 1 星和 2 星的文本差异极小——“一般般”和“很差”之间的边界,词向量根本分不开,模型容易在相邻类别上乱跳。我做这个项目时选了四分类:好评、差评、中评、默认好评(模板文本单独归一类)。这样既避免了模糊地带的标注噪声,也把京东特有的“此用户未填写评价内容”这类垃圾样本隔离出去,不污染正文模型。

标注映射关系建议做成配置文件或一个清晰的函数,不要散落在代码里。后续如果要换分类粒度,只改这一处映射即可,别的地方全部复用。

def score_to_label(score): if score in (5,): return "positive" elif score in (4, 3): return "neutral" elif score in (2, 1): return "negative" else: return "unknown" import pandas as pd df = pd.read_csv("jd_comments.csv") df["label"] = df["score"].apply(score_to_label) print(df["label"].value_counts())

这个映射有个细节:京东评分是离散的 1 到 5,但不同商品的评分分布差异很大,有的商品 4 星偏多,有的 3 星偏多。直接用评分映射会产生类别不均衡,后面的处理章节会详细讲。在这个阶段,你要关心的是每个类别的样本量是否能撑起训练,我一般要求每个类别不少于 3000 条,否则模型学不到可靠模式。

2.3 技术栈与评估口径:先定标准,再谈调参

技术栈的选择要匹配你的运行环境。如果只有 CPU,就不要一上来就上 BERT,训练一个 epoch 可能要几小时,答辩前很容易翻车。最稳的组合是:Python + pandas + jieba + scikit-learn,模型用朴素贝叶斯或逻辑回归打底,时间充足再试试 LSTM。BERT 或者transformers这类深度模型可以作为加分项写在“后续工作”里,不用强行跑通。

评估口径要提前想清楚。类别不均衡时,准确率是骗人的——如果负面样本只占 5%,全部预测成正面也有 95% 的准确率。正确的评估指标是宏平均 F1(macro-F1)和混淆矩阵。宏平均 F1 把每个类别的 F1 单独算再取平均,能真实反映小类别的表现。这个口径从第一篇实验开始就固定下来,中途不要换,否则前后对比没有意义。

from sklearn.metrics import classification_report, f1_score y_true = [...] # 真实标签 y_pred = [...] # 模型预测标签 report = classification_report(y_true, y_pred, target_names=["negative", "neutral", "positive"]) print(report) # 重点看 macro avg 那一行的 f1-score

如果你用的是 scikit-learn 的接口,classification_report会一次性给出每个类别的精确率、召回率、F1 和样本数。我一般要求宏平均 F1 稳定在 0.80 以上才算及格,0.85 以上是良好,0.90 以上需要比较干净的语料才能达到。数据噪声很高的情况下,0.80 就是很好的结果了,不要盲目追求高指标。

3. 把京东评论变成干净的训练集:清洗、去重与标注修正

3.1 清洗:去掉模板文本、HTML 标签和超长噪声

京东评论区有大量非自然语言的文本。最常见的三类:一是“此商品太棒了,我很喜欢”之类的系统默认好评提示;二是用户粘贴的商品参数或活动链接;三是纯表情或“哈哈哈哈”这类无信息量文本。清洗的目标不是把文本变漂亮,而是把模型不需要学的噪声去掉,否则模型会把“默认好评”学成一个独立类别,而不是学到真实的情感表达。

清洗顺序很关键。先处理 HTML 实体和解码问题,再做长度过滤,最后做关键词去噪。如果先做长度过滤,含大量标签但正文很短的文本会被误删。我一般用正则把&[a-zA-Z]+;这类 HTML 实体替换成空格,再把http[s]?://\S+替换成空字符串。长度过滤的阈值设在 2 到 100 字之间,低于 2 字的没有信息量,高于 100 字的可能是复制粘贴的评测文章,对情感分类没有帮助。

import re import pandas as pd html_pattern = re.compile(r"&[a-zA-Z]+;") url_pattern = re.compile(r"https?://\S+") def clean_text(text): if not isinstance(text, str): return "" text = html_pattern.sub(" ", text) text = url_pattern.sub(" ", text) text = re.sub(r"\s+", " ", text).strip() return text df = pd.read_csv("jd_comments.csv") df["clean"] = df["content"].apply(clean_text) df["len"] = df["clean"].apply(len) df = df[df["len"] >= 2]

这一步要输出一个清洗后可读的 CSV,并肉眼抽样检查 200 条左右。检查的目的不是看清洗规则对不对,而是看有没有漏网的异常文本。如果发现某种噪声频繁出现,就把它对应的正则或规则补进去。清洗是迭代的过程,不要指望一次到位。常见的漏网之鱼是“此用户很懒,什么都没有留下”这类半模板文本,它包含真实情感吗?不包含,需要单独过滤。

3.2 去重:同一个用户在不同商品下的重复评论

京东用户会在多个商品下复制粘贴同一条评论,尤其是参与返京豆活动的用户。这类重复评论如果不处理,模型会严重过拟合到重复文本上,导致验证集准确率高但真实场景表现差。去重不能只做字符串完全匹配,因为用户可能只改一个标点或加一个空格,我一般用归一化后的文本做去重:去掉所有空格和标点,再比较是否相等。

更狠一点的做法是算文本之间的编辑距离,但毕设数据量在小万级别时,直接跑difflib会慢到怀疑人生。折中方案是先用文本哈希粗筛,再对哈希相同的分组做两两编辑距离验证。我实践下来,归一化完全匹配已经能解决大部分问题,编辑距离留给极端情况。

import re def normalize_for_dedup(text): return re.sub(r"[\s\W_]+", "", text) df["norm"] = df["clean"].apply(normalize_for_dedup) df = df.drop_duplicates(subset=["norm"], keep="first") print(f"去重后剩余 {len(df)} 条评论")

去重后会改变类别分布,所以去重要在清洗之后、划分训练测试集之前完成。顺序错了的话,测试集里可能混着训练集见过的重复文本,评估结果虚高。我踩过这个坑:第一次实验没去重,测试集准确率 0.91,去掉重复后直接掉到 0.83,这才意识到测试集泄漏了。

3.3 标注修正:评分不等于情感,怎么处理“阴阳怪气”

评分与真实情感并不总是对齐。有人给 1 星但评论内容是“东西还行,就是快递太慢了”,也有人给 5 星但写的是“帮朋友买的,不知道质量如何”。如果完全信任评分做标签,模型会学到错误模式。但手工重标上万条不现实,我一般用规则加抽检来修正:先标记出“评分与文本情感冲突”的候选样本,再抽 10% 人工确认。

候选标记的规则很简单:文本里出现明确的矛盾信号词,比如“快递慢”“质量差”“客服不理人”的同时评分大于等于 4,或者出现“好评”但评分小于等于 2。这类样本通常只占总量 5% 左右,人工处理成本可控。也可以在标注修正后直接丢弃这些冲突样本,因为它们属于标注噪声,保留会让模型的决策边界更模糊。

conflict_keywords = ["快递慢", "质量差", "客服", "退货", "垃圾", "差评"] def flag_conflict(row): text = row["clean"] if any(k in text for k in conflict_keywords) and row["score"] >= 4: return True return False df["conflict"] = df.apply(flag_conflict, axis=1) print(f"发现疑似冲突样本 {df['conflict'].sum()} 条") df_core = df[~df["conflict"]].copy()

这一步的意义在于:你辛辛苦苦用规则修正的每一个标签,都在告诉模型“评分只是弱信号,文本才是强信号”。我见过很多情感分析项目,分数很高,但把测试集里的冲突样本挑出来看,模型几乎全错。核验方式很简单:训练完成后,单独抽出冲突样本子集看分类准确率,如果低于 0.5,说明模型过度依赖评分风格而非文本语义,需要加强清洗或调整特征。

4. 让中文变成机器能读的数字:分词、停用词与向量化

4.1 分词:为什么不直接用 jieba 默认词典

中文文本没有天然空格,分词是特征工程的起点。jieba 是最常见的工具,自带词典覆盖多数通用词汇,但在商品评论领域,会出现“入股不亏”“避雷”“YYDS”这类网络新词,默认词典分不出来就会被切碎成单字,丢失语义信息。解决方法是先对语料做一次词频统计,找出被切碎的高频词,手动加入自定义词典。

自定义词典的格式很简单,每行一个词,可以带词频和词性。词频不要拍脑袋,我一般按语料规模估算:如果总词数是 50 万,一个出现 200 次以上的词,词频给 5 就够。词频给太高会影响 jieba 对其他词的分词判断,反而引入噪声。分词之后做一次验证:打印 50 条随机文本的分词结果,看看品牌名、商品名、情感词是否正确切开。

import jieba # user_dict.txt 每行: 词 词频 词性 # YYDS 500 nz # 避雷 300 v jieba.load_userdict("user_dict.txt") def tokenize(text): return [w for w in jieba.cut(text) if w.strip()] df_core["tokens"] = df_core["clean"].apply(tokenize) print(df_core["tokens"].head(10).tolist())

分词结果要保存下来,后续 TF-IDF 和 Word2Vec 都要复用,不要每次训练都重新分词。分词参数里唯一需要调的其实是词典,jieba.cut的HMM参数默认开,对未登录词有补充识别效果,但也会把一些英文混着中文的文本切乱。如果语料里英文占比较高,可以把HMM=False试一试,对比一下前后效果再决定。

4.2 TF-IDF向量化:三个必调参数

TF-IDF 是把分词结果转成向量最直接的方法。sklearn 的TfidfVectorizer有三个参数对最终效果影响最大:max_features、min_df和ngram_range。max_features控制特征数量,商品评论文本量级在 1 万条左右时,5000 到 10000 个特征就够用;设太大内存容易爆,设太小信息量不够。min_df是文档频率下限,默认 1 会把只出现一次的生僻词也纳入特征,我一般设 5,让至少出现在 5 条评论里的词才进入词表。

ngram_range是容易被忽略的点。二元词组((1, 2))能捕捉“质量+好”“物流+慢”这类组合情感,比单个词更稳定,但特征维度会翻几倍。我建议先跑(1, 1)做基线,再试(1, 2),对比 F1 有没有提升。如果提升不到 1 个百分点,就留在(1, 1),因为特征维度过高会导致训练时间变长,逻辑回归还好,换成其他模型就吃力了。

from sklearn.feature_extraction.text import TfidfVectorizer df_core["text"] = df_core["tokens"].apply(lambda x: " ".join(x)) vectorizer = TfidfVectorizer( max_features=8000, min_df=5, ngram_range=(1, 2), sublinear_tf=True, # 用 1+log(tf) 代替原始词频,缓解高频词主导 ) X = vectorizer.fit_transform(df_core["text"]) y = df_core["label"] print(f"特征矩阵形状: {X.shape}")

sublinear_tf是我觉得最值得开的一个参数。京东评论区“的”“了”“就”这类虚词即使加了停用词表也未必清干净,开了sublinear_tf之后,词频差异被压缩,模型不再被高频无义词带偏。特征矩阵是稀疏矩阵,保存时直接用scipy.sparse.save_npz存成.npz文件,下次加载不重复计算,能省不少时间。

4.3 词向量与序列模型:Word2Vec 到底该自己训练还是下载现成的

如果你想尝试 LSTM 这类序列模型,就得把文本转成词向量序列。有两个选择:用现成的中文词向量,或者用 gensim 在自己的语料上训练 Word2Vec。毕设层面我更推荐自己在语料上训练,因为中文通用词向量是在新闻、百科等正式语料上训练的,对“便宜大碗”“踩雷”这类电商口语词覆盖很差。自训练只需设置维度、窗口、最小词频三个参数。

维度通常设 100 到 200,太小表达不了语义差异,太大在小语料上容易过拟合。窗口设 5 是默认值,处理短文本评论够用。min_count设 5,出现次数少于 5 的词直接丢弃,否则向量质量会被稀有词的噪声拖垮。训练完成后一定要做一次相似词测试,比如查“质量”的 top 10 相似词,如果出来一堆不相关的词,说明语料量不够或参数不合适。

from gensim.models import Word2Vec from gensim.models.word2vec import LineSentence # 把分词结果写入文件,每行一条评论,词与词用空格分隔 with open("corpus.txt", "w", encoding="utf-8") as f: for tokens in df_core["tokens"]: f.write(" ".join(tokens) + "\n") model = Word2Vec( sentences=LineSentence("corpus.txt"), vector_size=150, window=5, min_count=5, workers=4, epochs=10, ) print(model.wv.most_similar("质量", topn=10))

epochs=10在短文本语料上比默认的 5 效果更好,因为每条评论太短,单次遍历学不到足够的共现信息。这里要注意一个常见翻车点:Word2Vec在 gensim 4.0 之后把size参数改名成了vector_size,网上老教程抄过来会直接报 TypeError。词向量训练好后要保存为word2vec.model和word2vec.kv两个文件,模型给后续微调用,kv 给快速加载用。

5. 模型评估与避坑清单:准确率虚高、样本不均衡和过拟合的血泪记录

5.1 基线模型对比:朴素贝叶斯、逻辑回归、LSTM 的取舍

不要一上来就训深度学习模型。我一般先跑两个传统机器学习基线:朴素贝叶斯和逻辑回归。朴素贝叶斯在短文本分类上很强,计算快,适合做下限参考;逻辑回归在 TF-IDF 特征上表现稳定,且系数可以直接当特征重要性看,答辩时解释起来很有说服力。如果这两个模型的宏平均 F1 已经到 0.82,那 LSTM 至少要超过 0.84 才有继续调的必要,不然直接交付传统方案更划算。

from sklearn.naive_bayes import MultinomialNB from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import f1_score X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y ) nb = MultinomialNB(alpha=1.0) nb.fit(X_train, y_train) y_pred_nb = nb.predict(X_test) print(f"MultinomialNB macro-F1: {f1_score(y_test, y_pred_nb, average='macro'):.4f}") lr = LogisticRegression(max_iter=1000, C=1.0, class_weight="balanced") lr.fit(X_train, y_train) y_pred_lr = lr.predict(X_test) print(f"LogisticRegression macro-F1: {f1_score(y_test, y_pred_lr, average='macro'):.4f}")

class_weight="balanced"是处理类别不均衡最省事的办法,它会按类别频率反向加权,让少数类别在损失函数里的占比提升。注意逻辑回归的max_iter默认 100,TF-IDF 特征维度高时经常不收敛,要调到 1000 以上。至于 LSTM,代码量比前两个大得多,我放到下一节讲。你还要记录每个模型的训练时间,答辩时这张“传统 vs 深度学习”的对比表非常加分。

5.2 避坑清单:五条必看的踩坑记录

5.2.1 准确率 0.93 但模型实际是废的

现象:测试集准确率看着很高,随手抽 20 条真实评论预测,错了一半。 原因:类别不均衡。负面样本只占 6%,模型全预测成正面也有 94% 的准确率。 解决:换成宏平均 F1 作为主指标,并在训练时使用class_weight="balanced"或过采样/欠采样。我常用imbalanced-learn库的RandomOverSampler,但要注意过采样会让验证集评估偏乐观,最好在过采样之前划分数据。

5.2.2 测试集泄漏:去重不彻底导致指标虚高

现象:模型在测试集上 F1 高达 0.92,部署到新数据上直接崩到 0.75。 原因:清洗后忘记去重,同一条评论同时出现在训练集和测试集。 解决:去重必须先于数据划分。更严格的做法是校验用户 ID,确保同一个用户的评论不会跨集合出现,因为同一个人的用语风格会让模型学到“人”而不是“情感”。

5.2.3 jieba 分词把“不”和“好”切开导致情感反转识别失败

现象:模型对“不好”“不行”“不喜欢”全部预测错误。 原因:默认词典没有把“不好”这类组合词切成一个整体,TF-IDF 把“不”和“好”当成独立特征,语义被割裂。 解决:建立否定词典,把“不好”“不行”“不满意”等加入自定义词典;或者在特征基础上叠加“否定词 + 相邻情感词”的组合特征。我实测这个操作能让负面类别 F1 提升 3 到 5 个百分点。

5.2.4 Word2Vec 训练后相似词一片混乱

现象:most_similar("质量")返回的全是数字、标点这类无意义 token。 原因:语料太小或者min_count太低,把噪声词也纳入了词表。 解决:把min_count从 5 提到 10,同时检查清洗环节是否把数字和标点全清干净了。如果语料只有几千条,不要强行用 Word2Vec,换 TF-IDF 更稳。

5.2.5 模型对“快递”相关评论集体误判为差评

现象:包含“快递”的评论大量被预测为负面,但实际上很多是好评。 原因:语料里“快递慢”“快递垃圾”等负面表达占比过高,模型学到“快递”这个词与负面的弱相关性。 解决:训练前做一次特征分析,把高频但与情感无关的强特征降权,或者直接用逻辑回归系数定位这类问题。真正的解法是扩充正面语料中“快递”出现的比例,让模型看到“快递很快”也能是正面的。

5.3 混淆矩阵与错误分析:指标准确不代表业务可靠

混淆矩阵能告诉你模型具体在哪些类别之间混淆。对于三分类情感分析,最常见的现象是“中评”与“好评”之间界限模糊,因为京东的 3 星用户常写“还行吧”,情感本身就不强烈。如果中评类别被大量分到好评,你可以选择调整中评的判定阈值,也可以在训练时给中评样本更高的权重。

from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay import matplotlib.pyplot as plt cm = confusion_matrix(y_test, y_pred_lr, labels=["negative", "neutral", "positive"]) disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=["negative", "neutral", "positive"]) disp.plot(cmap="Blues") plt.savefig("confusion_matrix.png", dpi=150, bbox_inches="tight")

画混淆矩阵是给答辩看的,但更重要的是从矩阵读出下一步行动。如果中评和好评的混淆数占了总误差的 60%,说明分类粒度本身可能不合理,与其调参不如回到 2.2 节改分类定义。模型评估做到这个深度,在一众只看准确率的毕设里已经能拉开差距了。

6. 把模型从“能跑”变成“能答辩”:验证细节、可解释性与交付技巧

6.1 交叉验证:别让随机种子决定你的成绩

单次划分训练测试集,结果受随机种子影响很大。我做实验时固定用 5 折交叉验证,取宏平均 F1 的均值和标准差。标准差能反映模型的稳定性,如果五折之间 F1 波动超过 0.03,说明数据分布不均匀或模型过拟合了某一类样本。交叉验证的结果写进论文里比单次结果有说服力得多。

from sklearn.model_selection import cross_val_score scores = cross_val_score(lr, X, y, cv=5, scoring="f1_macro") print(f"5-fold macro-F1: {scores.mean():.4f} ± {scores.std():.4f}")

6.2 可解释性:用逻辑回归系数讲清楚“模型为什么这么判”

毕业设计答辩时,老师最常问的问题是“你的模型依据什么做出判断”。用深度学习模型很难回答,但逻辑回归的系数可以直接对应到词特征。把系数绝对值 top 20 的词打印出来,正系数是正面词,负系数是负面词,这就是一个朴素但直观的解释。如果要展示单条评论的预测理由,可以用 LIME 库生成局部解释,我在项目里对每类随机抽 5 条评论做了解释,放在论文附录里。

6.3 交付物清单与验收标准

交付时不要只给一个训练好的模型文件,要包含完整的四件套:清洗与爬虫脚本、特征与训练代码、模型文件、评估报告。评估报告里至少有三张图:类别分布图、混淆矩阵、宏平均 F1 的折线对比图。验收标准不是模型跑通,而是新抓的 1000 条评论经过你的推理链路后,宏平均 F1 不低于训练时的 95%。

我自己做这类项目养成的习惯是:每次改完数据或模型,先把结果记录在一个 Markdown 文件里,再继续下一步。没有记录的实验等于没做。这个习惯让后面写论文时省了大量回头补实验的时间。希望帮到你,少踩一些我踩过的坑。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询