ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

中文谣言检测毕设实战:jieba分词+tfidf+logistic回归全流程

中文谣言检测毕设实战:jieba分词+tfidf+logistic回归全流程 简介这份本科毕业设计论文资源包聚焦中文谣言检测这一自然语言处理课题面向计算机、人工智能方向的高年级本科生与NLP入门研究者帮助读者理解如何用机器学习与深度学习算法构建谣言识别系统应对社交媒体虚假信息传播的识别难题。压缩包共26个文件约4.93MB包含12个Python脚本、9个txt文本、4个json数据文件及1个md说明文档脚本覆盖数据预处理、分词、停用词处理、TF-IDF特征提取、聚类与逻辑回归建模等完整流程json与txt则承载语料、标签、词表等数据。目前已有125人学习下载。读者可从中获取从数据集构建、特征工程到模型训练评估的完整实现思路并参考谣言演化分析与实时检测机制的设计为同类课题的复现与二次开发提供可落地的代码与文档支撑。1. 中文谣言检测毕设拆解从 jieba 分词到 logistic 分类的完整落地路径拿到「Chinese Rumor Recognition 本科毕业设计论文-中文谣言检测.zip」这个标题很多人第一反应是去搜现成代码包但真正决定这份毕设能不能跑通、能不能过答辩的是背后那条从原始中文文本到二分类结果的流水线。中文谣言检测本质上是一个文本二分类任务输入一条待判定的中文陈述输出「谣言 / 非谣言」标签。它和英文谣言检测最大的差别在于中文没有天然空格分隔必须先过 jieba 分词再用 tfidf 把词变成向量最后交给 logistic 回归做分类。这套组合是本科毕设里最常见、也最容易复现的方案适合有一定 Python 基础、但不想在深度学习上耗太多时间的同学。热搜里频繁出现的 spyder 安装 jieba 库、pip 命令安装 jieba 超时、logistic 回归和 sigmoid 函数恰好对应了这条流水线上最容易卡住的三个环节环境、分词、分类器。下面按「数据怎么来 → 特征怎么造 → 模型怎么训 → 坑怎么避」的顺序把这条链路拆开讲透。2. 数据准备与 jieba 分词中文谣言检测的第一道工序2.1 谣言数据集从哪来、怎么划分本科毕设阶段数据集通常有两个来源一是公开的中文谣言数据集二是自己从社交平台按关键词爬取后人工标注。公开数据集的好处是标注质量相对可靠坏处是类别分布可能不均衡。自己爬取的好处是数据新鲜坏处是标注工作量大而且容易引入主观偏差。我一般建议的做法是先用公开数据集跑通全流程确认模型能出结果再考虑要不要补充自采数据。数据划分上训练集、验证集、测试集按 7:1.5:1.5 或 8:1:1 切分。注意验证集的作用是调参和早停测试集只在最后评估时用一次不要反复在测试集上调参否则报告里的准确率会虚高。数据格式建议统一成两列text和label。label用 0 表示非谣言1 表示谣言。如果原始数据是「谣言 / 真实」这种字符串标签先做映射不然后面 sklearn 的LogisticRegression会报类型错误。import pandas as pd # 读取原始数据假设是 csv 格式两列text, label df pd.read_csv(rumor_data.csv, encodingutf-8) # 标签映射把字符串标签转成 0/1 label_map {非谣言: 0, 谣言: 1, 真实: 0, 虚假: 1} df[label] df[label].map(label_map) # 去掉空文本和标签缺失的行 df df.dropna(subset[text, label]) df df[df[text].str.strip() ! ] # 按 8:1:1 划分 from sklearn.model_selection import train_test_split train_df, temp_df train_test_split( df, test_size0.2, random_state42, stratifydf[label] ) val_df, test_df train_test_split( temp_df, test_size0.5, random_state42, stratifytemp_df[label] ) print(f训练集 {len(train_df)} 条验证集 {len(val_df)} 条测试集 {len(test_df)} 条)这段代码的关键点有三个stratifydf[label]保证切分后各类别比例一致避免某一类在验证集里消失random_state42保证结果可复现答辩时老师让你再跑一遍不会出岔子dropna和空文本过滤是防止后面 jieba 分词时报空输入错误。2.2 jieba 分词的三种模式和停用词处理jieba 有三种分词模式精确模式、全模式和搜索引擎模式。谣言检测里我一般用精确模式因为全模式会把「北京大学」切成「北京」「大学」「北京大学」这种冗余组合搜索引擎模式则更适合召回场景。精确模式的调用是jieba.lcut(text)返回一个词列表。停用词处理是很多人忽略的一步。中文里的「的」「了」「是」「在」这些词几乎每条文本都有tfidf 虽然会自动降低高频词权重但停用词表能进一步减少噪声维度。停用词表可以用哈工大停用词表或百度停用词表也可以自己根据语料统计补充。import jieba # 加载停用词表一行一个词 def load_stopwords(pathstopwords.txt): with open(path, r, encodingutf-8) as f: return set(line.strip() for line in f if line.strip()) stopwords load_stopwords() def cut_text(text): # 精确模式分词 words jieba.lcut(text) # 过滤停用词、单字、纯数字和空白 words [ w for w in words if w not in stopwords and len(w) 1 and not w.isdigit() and w.strip() ! ] return .join(words) # 对训练集、验证集、测试集分别处理 train_df[cut] train_df[text].apply(cut_text) val_df[cut] val_df[text].apply(cut_text) test_df[cut] test_df[text].apply(cut_text) print(train_df[[text, cut]].head(3))这里len(w) 1过滤单字是因为单字在谣言检测里信息量低且容易造成维度爆炸。not w.isdigit()过滤纯数字但要注意如果谣言里数字本身是特征比如「某地发生 8.0 级地震」这个过滤会损失信息。我的做法是保留数字但把连续数字归一化成NUM占位符这样既保留「有数字」这个信号又不让具体数值成为过拟合来源。提示jieba 首次运行会构建前缀词典缓存如果卡在Building prefix dict很久是正常现象等它跑完即可。后续运行会快很多。3. tfidf 特征工程把分词结果变成 logistic 回归能吃的矩阵3.1 tfidf 的计算逻辑与参数选择tfidf 的核心思想是一个词在当前文档里出现越多tf 高同时在所有文档里出现越少idf 高它就越有区分度。sklearn 的TfidfVectorizer把分词、词表构建、tfidf 计算打包在一起但前提是输入已经是空格分隔的词串——这正是上一步cut_text返回的格式。关键参数有四个max_features控制词表大小本科毕设数据量通常几千到几万条设 5000 到 10000 比较合适ngram_range控制是否加入二元词组(1,2)能捕捉「地震 谣言」这种搭配但维度会翻倍min_df和max_df分别过滤太少出现和太多出现的词一般设min_df2、max_df0.95sublinear_tfTrue对 tf 做对数平滑防止某个词重复太多主导权重。from sklearn.feature_extraction.text import TfidfVectorizer vectorizer TfidfVectorizer( max_features8000, ngram_range(1, 2), min_df2, max_df0.95, sublinear_tfTrue ) # 注意vectorizer 只能在训练集上 fit然后 transform 验证集和测试集 X_train vectorizer.fit_transform(train_df[cut]) X_val vectorizer.transform(val_df[cut]) X_test vectorizer.transform(test_df[cut]) y_train train_df[label].values y_val val_df[label].values y_test test_df[label].values print(f训练集特征矩阵形状{X_train.shape}) print(f验证集特征矩阵形状{X_val.shape})这里最容易翻车的地方是对验证集和测试集用了fit_transform而不是transform。fit_transform会重新构建词表导致训练集和测试集的词表不一致模型在测试集上的表现完全不可信。记住一个原则任何特征工程步骤只能在训练集上 fit然后 transform 其他集合。3.2 词表持久化与线上单条预测毕设答辩时老师经常会问「给你一条新文本你怎么判断」这时候需要把 vectorizer 和模型一起保存下来预测时先加载 vectorizer 做 transform再送进模型。用 joblib 保存比 pickle 更稳定尤其是 sklearn 版本变化时。import joblib # 保存 vectorizer 和后续训练好的模型 joblib.dump(vectorizer, tfidf_vectorizer.pkl) # 线上单条预测的流程 def predict_single(text, vectorizer, model): cut cut_text(text) vec vectorizer.transform([cut]) pred model.predict(vec)[0] prob model.predict_proba(vec)[0][1] return (谣言 if pred 1 else 非谣言), prob # 示例 # label, prob predict_single(某地昨晚发生强烈地震, vectorizer, model) # print(label, prob)predict_proba返回的是概率比单纯的 0/1 标签更有说服力。答辩时你可以说「这条文本被判为谣言的概率是 0.87」比「模型说是谣言」听起来专业得多。注意transform接收的是列表[cut]不是单个字符串这是 sklearn 的接口约定。4. logistic 回归训练与评估sigmoid 函数背后的调参细节4.1 logistic 回归在谣言检测里为什么够用logistic 回归的本质是把线性组合w·x b通过 sigmoid 函数映射到 (0,1) 区间作为正类概率。sigmoid 函数是1 / (1 exp(-z))当 z 趋近正无穷时输出趋近 1z 趋近负无穷时输出趋近 0。这个性质让 logistic 回归天然适合二分类而且输出有概率解释。在中文谣言检测里tfidf 特征维度高但样本量通常不大logistic 回归配合 L2 正则化能有效防止过拟合训练速度快可解释性也好——你可以直接看哪些词的权重最高作为「模型学到了什么」的证据。相比之下深度学习方案在本科毕设的数据量下未必能拉开明显差距反而增加调参和调试成本。from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score model LogisticRegression( C1.0, penaltyl2, solverliblinear, max_iter1000, class_weightbalanced ) model.fit(X_train, y_train) # 验证集评估 y_val_pred model.predict(X_val) y_val_prob model.predict_proba(X_val)[:, 1] print(classification_report(y_val, y_val_pred, target_names[非谣言, 谣言])) print(AUC:, roc_auc_score(y_val, y_val_prob)) print(confusion_matrix(y_val, y_val_pred))参数说明C是正则化强度的倒数C 越小正则化越强一般从 0.1、1、10 里选solverliblinear适合小数据集和 L2 正则max_iter1000防止迭代不够导致收敛警告class_weightbalanced在类别不均衡时自动调整权重如果数据本身均衡可以去掉。4.2 评估指标怎么读、怎么在论文里写准确率accuracy在类别不均衡时会骗人。假设 90% 是非谣言模型全猜非谣言也有 90% 准确率但谣言一条都抓不到。所以论文里至少要报精确率precision、召回率recall和 F1。谣言检测里我更关注召回率——漏掉一条真谣言的代价通常比误判一条非谣言高。AUC 衡量的是模型把正样本排在负样本前面的能力0.5 是随机猜1.0 是完美。本科毕设里 AUC 能到 0.85 以上就算不错。混淆矩阵能直观看出模型在哪一类上错得多如果谣言类的假阴性特别多说明模型偏向预测非谣言可以调class_weight或降低分类阈值。# 调整分类阈值观察召回率变化 import numpy as np from sklearn.metrics import precision_recall_curve precision, recall, thresholds precision_recall_curve(y_val, y_val_prob) # 找到召回率 0.9 时对应的阈值 idx np.where(recall 0.9)[0] if len(idx) 0: best_threshold thresholds[idx[0]] print(f召回率0.9 时阈值约为 {best_threshold:.3f})默认阈值是 0.5但你可以根据业务需求调整。如果答辩时被问到「怎么权衡误判和漏判」这段代码就是现成的回答素材。5. 避坑与排查jieba、tfidf、logistic 三个环节的常见翻车记录5.1 jieba 安装超时与 Spyder 环境错乱现象在 Spyder 里import jieba报ModuleNotFoundError但明明在命令行里pip install jieba成功了。原因Spyder 可能用的是另一个 Python 解释器或虚拟环境命令行 pip 装到了系统环境Spyder 用的是 conda 环境。解决在 Spyder 的 IPython 控制台里执行import sys; print(sys.executable)确认解释器路径然后用!pip install jieba -i https://pypi.tuna.tsinghua.edu.cn/simple指定镜像源安装。如果 pip 超时换清华源或阿里源不要反复重试默认源。5.2 tfidf 在测试集上重新 fit 导致指标虚高现象验证集准确率 0.95测试集只有 0.6。原因对验证集或测试集调用了fit_transform词表被重新构建模型看到的特征和训练时不一致。解决全局搜索代码里的fit_transform确保只有训练集用fit_transform其他集合一律用transform。这个坑我见过不止一次血泪经验是把 vectorizer 的 fit 和 transform 分成两行写不要图省事。5.3 logistic 回归不收敛的 RuntimeWarning现象训练时出现ConvergenceWarning: lbfgs failed to converge或Increase the number of iterations。原因max_iter默认值太小或者特征没有归一化导致优化困难。解决先把max_iter调到 1000 或 2000如果还不行检查 tfidf 矩阵是否有全零行全零行会让模型无法学习。另外solver换成liblinear或saga有时能解决。注意saga支持 L1 正则适合做特征选择。5.4 类别不均衡导致模型只会猜多数类现象准确率 0.9但谣言类的召回率只有 0.1。原因训练数据里非谣言远多于谣言模型学到「全猜非谣言」就能拿高准确率。解决LogisticRegression里设class_weightbalanced或者在切分数据时对少数类做欠采样、对多数类做欠采样再或者用imblearn的 SMOTE 做过采样。本科毕设里class_weightbalanced通常就够了不需要引入额外库。5.5 停用词表编码错误导致分词结果为空现象cut_text返回空字符串tfidf 矩阵全是零。原因停用词表文件是 GBK 编码用 UTF-8 读取时报错或被静默跳过导致停用词集合为空或异常。解决用chardet检测文件编码或者统一把停用词表转成 UTF-8。另外检查cut_text里的过滤条件是否过严比如len(w) 1加上停用词过滤后短文本可能一个词都不剩。6. 从毕设到可演示系统用 cluster 做谣言聚类的进阶技巧毕设如果只做到「输入一条文本输出标签」答辩时容易被问「能不能发现新出现的谣言」。这时候可以加一个无监督的 cluster 环节对所有文本的 tfidf 向量做 KMeans 聚类看看谣言是否自然聚成几类。热搜里出现的nxp partial network cluster 1145和runtimeerror: cluster is not available after multiple attempts虽然来自其他领域但聚类不稳定这个问题在文本聚类里同样存在——KMeans 对初始中心敏感跑一次结果可能不可复现。我的做法是固定random_state用n_init10让 KMeans 跑 10 次取最优再用轮廓系数选 K。代码不长但能让论文多一章「谣言主题发现」。from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score # 用 SVD 降维后再聚类效果通常比直接在高维 tfidf 上聚好 from sklearn.decomposition import TruncatedSVD svd TruncatedSVD(n_components100, random_state42) X_svd svd.fit_transform(X_train) best_k, best_score 2, -1 for k in range(2, 8): km KMeans(n_clustersk, random_state42, n_init10) labels km.fit_predict(X_svd) score silhouette_score(X_svd, labels) print(fK{k}, 轮廓系数{score:.3f}) if score best_score: best_k, best_score k, score print(f最佳聚类数{best_k})TruncatedSVD把稀疏的 tfidf 矩阵降到 100 维稠密向量既加速聚类又缓解高维稀疏导致的距离失效。n_init10是解决聚类结果不稳定的关键sklearn 新版本默认就是 10但老版本默认 1显式写出来更保险。轮廓系数越接近 1 越好但文本聚类通常到 0.1 到 0.3 就算合理不要期待像图像聚类那么高。聚类完之后你可以取每个簇的中心词tfidf 权重最高的几个词作为该簇的主题标签比如「地震」「食品安全」「名人去世」等。这样答辩演示时你可以先展示分类器的单条预测再展示聚类发现的谣言主题分布整个系统的完整度就上来了。最后说一个我自己的习惯每次跑完实验把random_state、max_features、C这三个参数和对应的评估指标记在一个表格里不要只存代码。答辩前翻这个表比翻代码快得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表