news 2026/10/10 8:44:54

新闻标题分类实战:从数据清洗到模型部署的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
新闻标题分类实战:从数据清洗到模型部署的完整指南

简介:基于机器学习的新闻标题分类系统,是一套面向毕业设计场景的完整可运行项目,整合系统源码、分类数据集、预训练模型与项目文档。资源从环境配置到模型部署形成完整链路:在 Python 3.8 与 sklearn 技术栈下,借助 preprocess.ipynb 完成中文分词、数据预处理与模型训练,自动生成 pkl 格式模型文件;Flask 搭建 Web 服务,运行 main.py 后即可在页面中对新闻标题进行实时分类预测。压缩包共含62个文件、约10.94MB:16个html与13个css支撑前端界面,8个js处理交互逻辑,7个py实现后端核心流程,sql文件用于 MySQL 数据导入,txt词典涵盖哈工大停用词表、四川大学机器智能实验室停用词库与敏感词表等,ipynb为训练主脚本。已有217人学习下载,读者可直接运行获得可用模型,配合说明文档节省环境配置与调参时间;依托清晰的目录结构和完整注释,也便于在用户管理、分类策略等方面做二次开发。

1. 一个毕业设计就能暴露的坑:新闻标题分类,模型效果居然卡在数据上

如果你是第一次拿到“基于机器学习的新闻标题分类系统源码+数据集+模型+项目说明(毕业设计).zip”,大概率会先去找模型文件,把训练好的分类器加载出来跑个预测。但我见过太多人卡在一个环节:直接跑源码时准确率还像样,一旦自己换数据或重新训练,效果就崩得一塌糊涂。这个毕设标题看起来是“分类系统”,真正决定能不能完成的,是数据怎么清洗、标签怎么对齐、特征怎么提取、模型怎么选。我会按一条完整落地的路线讲清楚:从数据集构造到模型训练,再到避坑和部署,让你拿到源码也能从零复现,而不是只当个黑匣子用。适合正在做文本分类毕设或想入门的从业者。

2. 先把数据和标签理顺:新闻标题数据集的构造、清洗与标注

拿到zip包,第一件事不是解压找模型,而是检查目录结构。一个能跑完整个流程的新闻标题分类项目,至少得有三个数据文件:训练集、验证集、测试集。常见格式是CSV或JSON,每行一条标题和对应的类别标签。如果只有原始抓取数据,没有标注文件,就要自己造标签;如果已有标签,要检查类别体系是否完整。这章把数据这层做扎实,后面模型训练才不会翻车。

2.1 标题数据长什么样:类别体系与标注文件结构

通常新闻标题分类的类别是像“体育”“财经”“科技”“娱乐”“社会”这种粗粒度标签。类别数量10个左右比较合适,既有区分度又不至于太细。数据文件一般长这样:

title,label "梅西梅开二度 巴萨客场逆转",体育 "A股三大指数集体收涨 成交额破万亿",财经 "量子计算再突破:新算法降低错误率",科技

注意,标题里会有双引号包裹,因为标题本身可能包含逗号。CSV读取时要用quoting=csv.QUOTE_ALL或直接让 pandas 处理。类别编码建议直接用字符串标签,不要先转成数字,方便排查错误。

拿到数据后第一件事是统计类别分布。常见做法是读入DataFrame后value_counts()看各类别数量。如果某一个类别只有几十条,另一个有几千条,后面就要做采样或换评估指标。我一般会画一个简单的柱状图,不画图也至少把数字打出来:

import pandas as pd df = pd.read_csv('news_title.csv', encoding='utf-8') print(df.shape) print(df['label'].value_counts(normalize=True))

这里normalize=True直接看占比,能帮你判断是不是存在极端不均衡。如果比例超过10:1,后面评估指标就得用宏平均F1,而不是准确率。这一步在毕设里特别重要,答辩时老师第一眼就会看数据分布。

2.2 清洗标题文本:去噪声、去空白、统一中文标点

新闻标题是网页抓下来的,经常混着空格、全角标点、HTML实体、甚至是“原标题:”这类前缀。清洗的目标是保留中文、英文和数字,去掉对分类没帮助的噪声。但要注意:不要过度清洗,标题里的冒号、问号、引号有时能表达情绪(比如“?”代表质疑),是否保留要看你的类别体系。

我常用的清洗函数长这样:

import re def clean_title(text: str) -> str: # 去掉常见抓取噪声 text = text.replace('\\u3000', ' ').replace(' ', ' ') # 去掉“原标题:”等前缀 text = re.sub(r'^.*?[::]\s*', '', text) # 仅在标题很短时考虑 # 全角转半角,统一标点 text = text.replace(',', ',').replace('。', '.').replace('!', '!') # 去掉连续空白 text = re.sub(r'\s+', ' ', text).strip() return text

这段代码里有三个值得细说的点。第一,\\u3000是全角空格,网页抓下来的中文文本很常见,不先替换会导致后面分词时出现奇怪的词。第二,正则^.*?[::]用来去掉“快讯:”“标题:”这类前缀,但如果标题本身以“专访:”开头并且这个前缀有信息量,就别用这个正则。我一般会看看被去掉的内容再决定。第三,全角转半角我上面只写了三个例子,实际要写一整个映射表,或者直接用str.maketrans,但核心思想是让同样的标点只有一种形式,否则同一句话会变成两套特征。

清洗完要验证效果,别急着往下走。随机打印20条清洗后的标题,确认没有被误删内容。这一步是典型的血泪经验,我见过有人把“中国男篮战胜日本”里的“日本”当成噪声过滤掉,结果体育类全乱了。所以清洗函数要尽量保守,能用白名单过滤就别写大开大合的正则。

2.3 切分训练验证测试集:按类别分层采样

项目里既要有训练集又要有验证集和测试集,不能直接从头拿数据打乱。新闻标题往往来自同一时间段,如果整体随机切分,同一条新闻的不同转载标题可能会同时出现在训练和测试里,产生数据泄露。正确做法是按类别分层采样,并且最好保证同一新闻事件的相似标题只出现在一个集合里。

常见做法是先把标题文本去重,再分层切分。去重标准不能只去完全相同的字符串,还要去掉只剩标点数字差异的“兄弟标题”。这里用最保险的精确去重起步,后续再考虑模糊去重。

from sklearn.model_selection import train_test_split # 先按标题精确去重,注意保留标签 df_dedup = df.drop_duplicates(subset='title', keep='first') # 分层切分:70%训练,15%验证,15%测试 train_val, test = train_test_split( df_dedup, test_size=0.15, stratify=df_dedup['label'], random_state=42 ) train, val = train_test_split( train_val, test_size=0.15 / 0.85, stratify=train_val['label'], random_state=42 )

这里有个容易翻车的地方:先用test_size=0.15分出测试集,再在剩余集合里用test_size=0.15/0.85分出验证集。为什么要这么算?因为第一次切分后剩余占85%,要在85%里再切出总体的15%,比例应该是0.15/0.85 ≈ 0.1765,这样最后训练、验证、测试的比例才严格是 0.7、0.15、0.15。如果你直接在train_val上再用0.15,实际验证集只占总体的12.75%,测试集15%,训练72.25%,比例不规整,论文里不好写。

stratify参数按标签分层,保证每个类别在三份数据里的比例和原始分布一致。这个在类别不均衡时尤其关键,否则可能某个类别全部进了测试集,训练集里根本没见过这个标签。这一步做完,后面的模型效果才真正可信。

3. 特征工程与模型选型:从TF-IDF到词向量,决定分类效果的上限

数据准备好了,接下来是选特征和模型。新闻标题很短,一般二三十个字,和长文本不一样,很多在长文本上好用的做法在这里反而会翻车。比如直接用BERT,效果不一定比TF-IDF+SVM高多少,而且训练慢、显存占用大,除非你有词表和预训练模型资源。先讲清楚为什么要从TF-IDF入手。

3.1 TF-IDF与n-gram为什么是新闻标题分类的默认选择

TF-IDF把每一条标题变成一个稀疏向量,每个维度是某个词或词组在标题里的重要程度。新闻标题本身短,词数有限,产生的特征维度不会像长文本那么爆炸,训练速度非常快,而且结果可解释性强:某个类别最依赖的Top特征词可以直接输出给答辩看。

用n-gram可以把相邻词组合起来,比如“新能源汽车”这种三个字的短语,如果只用单个词,会被拆成“新”“能源”“汽车”,语义就丢了。对中文来说,先分词再组合n-gram,效果比直接用字的n-gram更好。常见做法是jieba.cut分词,然后用TfidfVectorizer设置ngram_range=(1, 2)。

这里给出一个最小但完整的特征构建代码:

import jieba from sklearn.feature_extraction.text import TfidfVectorizer def tokenize(text: str): return jieba.lcut(text) # 精确模式分词 vectorizer = TfidfVectorizer( tokenizer=tokenize, token_pattern=None, ngram_range=(1, 2), min_df=2, max_features=50000, ) X_train = vectorizer.fit_transform(train['title']) X_val = vectorizer.transform(val['title'])

token_pattern=None是必须设置的,因为自定义tokenizer后默认的正则会把整句当成一个token,导致分词失效。min_df=2表示至少出现在2条标题里的词才保留,过滤掉只在一条标题里出现的噪声词;这个值需要调,对新闻标题这种短文本,取值在2~5之间比较合理。max_features=50000限制最大特征数,防止向量化器占太多内存,同时也能防止太稀疏的特征干扰训练。

另一个容易被忽视的点:fit_transform只用在训练集上,验证集和测试集只能调transform,不能再拟合。否则向量化器会从验证集里学到词表信息,造成数据泄露。很多初学源码的人在这里直接把训练和验证一起fit_transform,导致验证集效果虚高,换到真实新数据就崩了。

3.2 用词向量或预训练模型的时候要注意什么

如果你的毕设希望展示“我用了更深一点的模型”,可以尝试用词向量均值池化或者fastText。这类模型的好处是不需要SVM那样的稀疏向量,而是把标题映射为固定长度的稠密向量。但新闻标题分类的难度在于语义精炼,很多词是专有名词,比如“央行”“芯片”“元宇宙”,如果词表里没有这些词,词向量就退化成随机的unk向量,效果可能还不如TF-IDF。

如果真想用预训练模型,常见做法是用huggingface的bert-base-chinese或者更轻量的distilbert,标题前面加[CLS],取最后一层[CLS]向量做分类。但要注意:预训练模型对中文标点和繁体词比较敏感,新闻标题里的网络新词(比如“绝绝子”)如果没有出现在词表里,会被切成细碎的子词。一个办法是保留原始标题的同时,拼接TF-IDF特征,做特征融合,我试下来对短文本能稳定提升1到2个点的F1。

用词向量做均值池化的代码,我一般这样写:

import numpy as np from gensim.models import KeyedVectors # 假设已经加载了 word2vec 模型,wv 是 KeyedVectors def title_vector(text, wv, size=200): tokens = jieba.lcut(text) vecs = [] for tok in tokens: if tok in wv: vecs.append(wv[tok]) # 去掉停用词后没有向量,直接跳过 if not vecs: return np.zeros(size) return np.mean(vecs, axis=0)

这段代码里有个容易忽略的点:当一条标题分词后没有任何词命中词表,返回的是全零向量。全零向量对所有分类器来说都是一个“未知”信号,如果这类样本太多,模型会学到“看到全零就预测多数类”。我一般会把这些样本单独统计出来,看是分词太碎还是词表太小。毕设答辩时,这个细节能说明你对数据处理有深入理解,而不是只会调包。

3.3 模型对比:朴素贝叶斯、SVM、逻辑回归、fastText

新闻标题分类的基准模型,我建议至少做四个:朴素贝叶斯(MultinomialNB)、线性SVM(LinearSVC)、逻辑回归(LogisticRegression)和fastText。这样对比表里能覆盖不同算法思想,答辩时也有的聊。

先给一个用pipeline同时做向量化和分类的代码,方便后面做交叉验证:

from sklearn.pipeline import Pipeline from sklearn.linear_model import LogisticRegression from sklearn.svm import LinearSVC from sklearn.naive_bayes import MultinomialNB models = { 'mnb': Pipeline([('tfidf', vectorizer), ('clf', MultinomialNB(alpha=0.1))]), 'svm': Pipeline([('tfidf', vectorizer), ('clf', LinearSVC(C=1.0))]), 'lr': Pipeline([('tfidf', vectorizer), ('clf', LogisticRegression(C=1.0, max_iter=1000))]), }

注意,每个模型都用同一个vectorizer实例,这是可行的,因为Pipeline在fit时会对训练集重新fit向量化器。但不能在循环外已经用训练集fit过vectorizer后,又在Pipeline里fit另一份数据。更稳妥的做法是每个pipeline单独定义自己的向量化器,或者使用clone。上面代码用了同一个实例,前提是数据不变,不会出错。

朴素的MultinomialNB适合离散的TF-IDF特征,alpha是平滑系数,默认1.0。对新闻标题,alpha取0.1~0.3通常效果更好,因为标题词频很小,平滑太大等于把所有概率都拉平了。LinearSVC和LogisticRegression在文本分类上效果接近,但LinearSVC对特征缩放更敏感,TF-IDF是稀疏非负特征,一般还算稳定。逻辑回归有概率输出,方便后面看置信度,做产品化时更有用。

如果做fastText,常见做法是把分词后的标题写成“label__体育 梅西 梅开二度”这种格式,然后训练。fastText的优点是训练快,也能输出嵌入向量,但对中文依赖分词,效果和参数lr、epoch、wordNgrams有直接关系。我一般把wordNgrams设成2或3,lr用0.5,epoch25。这些参数具体多少还要看验证集,后面会讲。

4. 训练评估与参数调优:从准确率到F1,找到模型差在哪里

模型选好以后,不要急着看准确率。新闻标题分类往往存在类别不均衡,“科技”类占30%,“体育”类只占5%时,无脑预测全部是“科技”就能拿到70%准确率。所以必须看F1,尤其是宏平均F1。这章讲评估和调参。

4.1 评估指标怎么选:宏平均和微平均的区别

先明确概念。宏平均(macro)是先算每个类别的P、R、F1,再取算术平均;微平均(micro)是汇总所有预测正确数后算一个整体F1。类别不均衡时,宏平均能暴露小类别的表现,微平均会被大类别的数量优势掩盖。新闻标题分类这种短文本任务,我一般报告宏平均F1,同时给出准确率。

sklearn的classification_report能一次输出所有指标:

from sklearn.metrics import classification_report y_pred = best_model.predict(X_val) print(classification_report(val['label'], y_pred, digits=3))

输出里每个类别有precision、recall、f1-score和support。看报告时,重点看support很小的类别。如果“体育”类recall只有0.3,说明很多体育标题被分到别处去了。这时候不要急着调模型,先去看错误样例,往往能发现是分词问题或类别定义重叠(比如“电竞”算体育还是娱乐?)。严格来说,这需要数据标注规范来兜底,不能只靠调参。

4.2 必调的三个超参数:词频下限、n-gram范围、正则化强度

对TF-IDF+线性模型,第一优先级是调特征层的参数,而不是模型参数。min_df控制最小词频,ngram_range控制词组长度,max_df控制去除高频噪声词。max_df设为0.8或者0.9,可以去掉在几乎所有标题里都出现的词,比如“今日”“最新”这类对分类没有区分度的词,但要注意:某些类别里“今日”可能是信号,比如财经标题经常“今日A股”,所以max_df要谨慎。

第二优先级是正则化强度C。逻辑回归和SVM的C越小,正则越强,模型越简单。对高维稀疏的TF-IDF特征,C在0.1到1之间比较合适;C太大会过拟合,C太小会欠拟合。我建议用网格搜索,但不要全参数一起搜,时间会很长。常见做法是分两轮:先固定模型参数,搜索min_df和ngram_range;再固定特征参数,搜索C和alpha。代码如下:

from sklearn.model_selection import GridSearchCV param_grid = { 'tfidf__min_df': [1, 2, 3], 'tfidf__ngram_range': [(1, 1), (1, 2), (1, 3)], } base_pipeline = Pipeline([ ('tfidf', TfidfVectorizer(tokenizer=tokenize, token_pattern=None)), ('clf', LogisticRegression(C=1.0, max_iter=2000)), ]) search = GridSearchCV(base_pipeline, param_grid, cv=5, scoring='f1_macro', n_jobs=-1) search.fit(train['title'], train['label']) print(search.best_params_)

这里cv=5对短文本分类来说够用,但注意GridSearchCV内部会用整个训练集做交叉验证,如果你的训练集很大(超过几万条),可以改成cv=3或者直接用手上的验证集,不交叉验证,省时间。另外scoring='f1_macro'比默认的accuracy更贴近目标。搜索结果里面,ngram_range偏大(比如(1,3))可能略微提升,但同时特征维度会快速膨胀,训练时间变长。我通常选(1,2)作为平衡点,(1,3)只有在数据量超过2万条时才敢用。

4.3 输出混淆矩阵和错误样例,定位bad case

调参后必须看混淆矩阵,光看F1数字很难知道模型错在哪里。对类别不均衡的情况,混淆矩阵能一眼看出哪些类别最容易互相混淆。用pandas可视化一下:

from sklearn.metrics import confusion_matrix cm = confusion_matrix(val['label'], y_pred, labels=model.classes_) print(pd.DataFrame(cm, index=model.classes_, columns=model.classes_))

打印出来是矩阵,行是真实标签,列是预测标签。对角线越深越大越好,非对角线大的格子就是混淆热点。比如“科技”和“财经”经常混,因为新闻标题里“数字人民币”“区块链”这类词同时出现在两个类别。看到这种混淆后,有两个思路:一是给样本打标签时,把“数字人民币”这类标题归为财经还是科技,标准要统一;二是加一类“产经”或合并类别,避免让模型去区分语义边界模糊的类。

定位bad case的代码很简单,但很管用:

val = val.copy() val['pred'] = y_pred val['proba'] = best_model.predict_proba(X_val).max(axis=1) bad = val[val['label'] != val['pred']].sort_values('proba', ascending=False) print(bad[['title', 'label', 'pred', 'proba']].head(20))

按预测概率排序,找到模型十分自信却分错的样本。这类样本往往暴露了标注错误或类别定义问题。我见过一条“CBA季后赛今晚打响:辽宁迎战广厦”被分到财经,原因是“辽宁”出现在财经新闻里。这种bad case很难靠调参解决,更好的方案是引入外部知识,比如维护一份实体关键词表,把球队名和“赛事”关联起来,或者干脆增加训练样本。

5. 避坑指南:新闻标题分类最常见的五个翻车现场

这章专门写我在复现这类毕设项目时实际踩过、也帮别人排查过的坑。每一条都按“现象→原因→解决”的顺序来,方便你对照排查。

5.1 现象:标签分布极不均衡,模型全部预测成多数类

现象是训练集里“社会”类占60%,“体育”只占4%,训练出的逻辑回归在验证集上准确率很高,但F1很低,而且“体育”类一个都没预测出来。

原因:模型在优化整体准确率时,把所有样本都预测成多数类损失最小;少数类的梯度被多数类稀释,模型根本没有机会学到少数类的特征。

解决:至少做三件事。第一,评估指标换成f1_macro;第二,训练时给少数类更高的样本权重,sklearn的LogisticRegression支持class_weight='balanced',它会按类别频率自动调整权重;第三,如果少数类实在太少,考虑用类别下采样或多类别合并。注意,做class_weight时不要动验证集,否则评估结果没有意义。

model = LogisticRegression(C=1.0, class_weight='balanced', max_iter=2000)

balanced对新闻标题分类的短文本非常有效,尤其当你的毕设数据集是自己抓的,类别量不太可能均衡。这个参数也是我排查“模型全预测成一个类”时的第一反应。

5.2 现象:数据泄露——测试集里混着训练集的重复标题

现象是模型在本地验证集F1达到0.93,但一到新标题预测就掉到0.7,答辩演示时一用一个不准。

原因:网络抓取的新闻标题经常有转载现象,同一事件在不同标题之间差异极小,例如“A股三大指数收涨”和“A股三大指数集体收涨”几乎是重复样本。如果不做相似度去重,这些样本会以不同的形态同时进入训练集和测试集,模型其实是靠记忆标题片段拿的高分。

解决:在切分之前先用文本相似度去重,不只是精确去重。常见做法是先用MD5去重,再用SimHash或者简单的Jaccard相似度阈值过滤。对毕设项目,可以用difflib或fuzz.partial_ratio处理,但数据量大时效率不够。我一般先用精确去重,再按来源URL去重,最后如果标题分词后的Jaccard相似度大于0.7,就把后出现的样本去掉。这段逻辑要写在项目说明里,因为它直接影响模型泛化能力的可信度。

5.3 现象:中文分词把“新冠”切成“新”和“冠”,类别全乱

现象是“新冠疫苗”被分词成“新”“冠疫苗”,甚至“新冠”被切成“新”“冠”两个单字,导致科技类和健康类标题特征混乱,模型权重里出现莫名其妙的词。

原因:jieba默认词典里没有“新冠”这个词,或者它的词频不够;分词是词级别的,遇到网络新词很容易切碎。

解决:动手维护一个自定义词典,把领域常见新闻词加进去,比如“新冠”“双减”“元宇宙”“数字经济”。在jieba加载时用jieba.load_userdict传入自定义词典文件。词典格式每行一个词,可以带词频和词性。

import jieba jieba.load_userdict('news_dict.txt') # 每行一个词,例如:新冠 1000 n

另一个做法是先用HMM识别新词,但对毕设来说,手动加词最可控。加载词典后重新训练,你会发现分类效果有可见提升,尤其对复合专有名词。这个坑几乎每个中文文本分类项目都会遇到,建议直接在数据预处理阶段处理好。

5.4 现象:正则表达式误伤标题,去HTML标签后句子断成碎片

现象是清洗后标题变成“中国 男篮 日本 比赛”,空格全没了,甚至出现“专访”被去掉一半的怪字符串。

原因:为了去除HTML标签,用了类似re.sub('<.*?>', '', text)的正则,把这个正则套到纯文本标题上,遇到“>”或“<”符号就把中间内容删掉;或者用了一大串字符替换,把正常中文标点也删了。

解决:清洗要分级。第一级是去掉网页噪声,比如CSS、脚本标签,这步只在原始HTML上做;第二级才是处理文本。在纯标题上,不要用*?>这种正则,直接去空白和统一标点就够。同时,每次清洗后要人工检查,可以统计清洗前后平均长度变化,如果长度骤降,说明有误删。更好的做法是只处理明确指出的噪声模式,不搞一刀切。

5.5 现象:模型打包后预测结果对不上,训练和推理预处理不一致

现象是训练时F1正常,但把模型导出后用Flask写接口,传入新标题预测,结果全乱,怀疑模型坏了。

原因:训练时对标题做了清洗和分词,但推理接口只调了模型,忘了调用向量化器,或者清洗步骤不一致;比如训练时把全角逗号转成半角,推理时没有转,导致词表里查不到。

解决:把整个流程(清洗→分词→向量化→分类)封装成一个类,里面保存清洗函数、vectorizer和model。推理时只调用这个类的一个方法,不允许单独调model。用joblib.dump把vectorizer和model打包到一起,能避免这类问题。另外在接口层做一次输入校验,长度过短的空标题直接返回默认类别,不要走模型。统一入口是唯一的后悔药,每次改预处理后,记住要同步改推理代码。

6. 把模型跑成可用系统:封装预测接口与持续迭代的进阶做法

如果你已经跑通了前面所有步骤,下一步是把零散的notebook整理成项目源码,并且让模型能对外提供稳定预测。这章讲一个可复用的封装方案,也是毕业设计里最容易被加分的部分。

6.1 用joblib保存模型和向量化器,写一个统一预测函数

保存时不要只保存模型,向量化器必须一起保存:

import joblib joblib.dump(vectorizer, 'model/tfidf_save.pkl') joblib.dump(model, 'model/clf_save.pkl')

恢复时用一个类封装所有前置步骤:

class NewsTitleClassifier: def __init__(self, vectorizer_path, model_path): self.vectorizer = joblib.load(vectorizer_path) self.model = joblib.load(model_path) def predict(self, raw_text): text = clean_title(raw_text) # 和训练时完全相同的清洗函数 X = self.vectorizer.transform([text]) # transform,不是fit proba = self.model.predict_proba(X)[0] pred = self.model.classes_[proba.argmax()] return pred, float(proba.max())

这个类把清洗、向量化、预测封装在一处,训练和推理只用同一个入口。注意,clean_title如果定义在notebook里,要把它的完整代码复制到模型服务模块中,不要靠“记得”保持一致。

6.2 在项目说明里记录实验矩阵,让毕设答辩有据可依

你的zip包里已经有一份项目说明,建议在最后加一个实验记录表,至少包含四列:特征方案、模型、宏F1、备注。把TF-IDF+朴素贝叶斯、TF-IDF+SVM、TF-IDF+逻辑回归、词向量均值+逻辑回归这几组结果放进去。答辩时老师问你“为什么最后选这个模型”,你直接翻出对比表格,比空口说“效果好”有说服力得多。我当初做的时候,还在表格里加“是否用class_weight”和“是否加自定义词典”,这两个开关项能帮你解释很多bad case。

6.3 如果再往前走一步:用SimCSE或Longformer替换特征提取

如果你的毕设需要体现一点前沿感,可以尝试用中文预训练模型替换TF-IDF,但不要直接端到端微调大模型,成本太大。常见做法是用SimCSE生成句向量,然后用逻辑回归分类。Longformer虽然能处理长文档,但新闻标题很短,没必要;SimCSE倒是更匹配,它专门做句向量,输出固定维度,再接一个线性分类器。唯一要注意的是SimCSE的句子最大长度和分词方式,标题太短时要加padding,不然向量不稳定。这个方向可以作为项目说明里的“未来工作”写一两段,不需要真跑通,但能显示你看到了模型边界。

最后说一句我的教训:以前我把清洗函数写在notebook的不同单元格里,后来自以为记住了,换数据时没跑清洗,直接向量化,结果F1掉了将近10个点。后来我养成一个习惯,把所有预处理都收敛到一个独立模块里,无论是训练还是预测,只调用同一个入口。这样才真正让这个毕设从“能跑”变成了“能交付”。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 6:04:35

JSP+MySQL网上书店系统实战:从源码导入到二次开发全解析

简介&#xff1a;这是一套基于JSPMySQL的JavaWeb图书销售管理系统&#xff08;网上书店&#xff09;完整项目源码与数据库&#xff0c;面向计算机相关专业正在准备期末大作业、课程设计的学生&#xff0c;以及需要项目实战练习的JavaWeb学习者。项目经导师指导并认可通过&#…

作者头像 李华
网站建设 2026/10/9 6:03:44

任务管理系统APP毕业设计避坑指南:状态流转与循环提醒实现

做毕业设计选“个人任务管理系统APP”这类题目时&#xff0c;很多同学一开始会觉得简单&#xff1a;不就是一个TodoList加个数据库&#xff0c;再加个手机页面吗&#xff1f;等真正动手才发现&#xff0c;任务管理的业务逻辑远不止“增删改查”。状态怎么流转、循环任务怎么处理…

作者头像 李华
网站建设 2026/10/9 6:01:27

MCP模型上下文协议实战:从原理到代码,打通AI工具调用链路

MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;最近几乎成了 AI 从业者绕不开的词。它相当于给 AI 大模型配了一套统一的“工具箱接口”&#xff0c;让模型不再只是聊天框里的文本生成器&#xff0c;而是能真正调用外部数据、运行工具、驱动业务…

作者头像 李华
网站建设 2026/10/9 6:00:35

Java后端对接大模型实战:从裸调API到JBoltAI智能数据中心

做Java后端的这两年&#xff0c;我越来越觉得“接大模型”这事被低估了。团队里大部分人一开始都以为&#xff1a;无非就是封装一个HTTP接口&#xff0c;把用户问题拼到Prompt里&#xff0c;然后解析返回的JSON。真正上手之后才发现&#xff0c;模型调用只是最表层的需求&#…

作者头像 李华
网站建设 2026/10/9 6:00:19

ADK+opensandbox:从零构建安全的Agent沙盒测试环境

做 agent 开发的人可能都有过这种经历&#xff1a;代码在本地调试时一切正常&#xff0c;模型也老老实实按指令调用工具&#xff0c;可一旦把同样的 prompt 放到一个隔离环境里&#xff0c;各种“权限不足”“找不到文件”“工具没有响应”的问题就全都冒出来了。我最近用 open…

作者头像 李华
网站建设 2026/10/9 5:59:57

保险理赔大文件秒传与版本对比:Java实现方案

做保险理赔系统的同僚应该都有过这种体会&#xff1a;理赔材料上传是整个链路里最容易挨骂的环节。报案人在手机端拍几十张单据、导出PDF版体检报告&#xff0c;动辄几十上百MB&#xff0c;网络稍差就是转圈圈、传一半失败、重新传一次。到了理赔员那边&#xff0c;同一张发票客…

作者头像 李华