假新闻检测NN模型因过度填充致精度下降,求可行解决方案
假新闻分类模型预测精度异常问题的解决方案
问题背景
训练了一个假新闻二分类神经网络FakeNewsDetectionModelV0,使用CountVectorizer将文本转换为特征张量。训练数据集包含9000余条数据,模型输入维度约12万。但单句预测时,单句特征维度远小于模型输入,即使填充后使用mask机制,预测精度仍仅约43%,远低于训练/评估阶段的精度水平。
核心问题分析
预测代码中错误地在每次预测时重新初始化并训练了新的CountVectorizer,导致预测时的词汇表与训练阶段完全不一致:训练时的CountVectorizer基于全量训练数据构建了12万维度的词汇表,而预测时每次仅针对单句构建词汇表,维度仅为单句的词数,填充后的向量中,真正对应训练词汇表的特征完全错位——这才是精度暴跌的根本原因,和填充操作本身无关。
解决方案
1. 复用训练阶段的CountVectorizer
训练完成后,将训练时的vectorizer保存下来(比如用joblib),预测时直接加载复用,绝对不能重新调用fit方法。通过vectorizer.transform()处理单句文本,会直接生成与训练时维度一致的特征向量,不存在维度不匹配问题,无需手动填充。
2. 简化预测流程,移除冗余填充逻辑
使用训练好的vectorizer处理文本后,输出的特征向量维度天然匹配模型输入,不需要手动填充和mask(如果保留mask,也只需针对vectorizer生成的向量中为0的位置,但实际CountVectorizer生成的向量本身就是稀疏的,mask在这里作用不大)。
3. 可选优化方向
- 改用
TfidfVectorizer替代CountVectorizer,能更好地衡量词的重要性,提升模型效果 - 对高维度特征进行降维(比如
PCA),减少模型输入维度,降低计算成本 - 替换为基于预训练词嵌入的模型(比如BERT、Word2Vec),更适合文本语义理解
修改后的预测代码示例
import torch import re import nltk from sklearn.feature_extraction.text import CountVectorizer import joblib # 训练阶段执行:保存训练好的vectorizer # joblib.dump(vectorizer, "fake_news_vectorizer.pkl") try: nltk.download('punkt') except: print("下载punkt失败") def normalise_text(text): text = text.lower() text = text.replace(r"\#", "") text = text.replace(r"http\S+", "URL") text = text.replace(r"@", "") text = text.replace(r"[^A-Za-z0-9()!?\'\`\"]", " ") text = text.replace("\s{2,}", " ") text = re.sub(r'[^\w\s]', '', text) return text def fake_news_detection(df, model): predictions = [] # 加载训练好的vectorizer vectorizer = joblib.load("fake_news_vectorizer.pkl") model.eval() for prediction_data in df['text'][:4000]: prediction_data = normalise_text(prediction_data) # 用训练好的vectorizer转换,直接得到匹配模型输入维度的特征 prediction_data_array = vectorizer.transform([prediction_data]).toarray() prediction_data_tensor = torch.tensor(prediction_data_array, dtype=torch.float32) with torch.inference_mode(): # 这里mask可以直接传None,因为vectorizer生成的向量已经是正确维度,0值本身就是未出现的词 prediction = torch.round(torch.sigmoid(model(prediction_data_tensor, None))).squeeze() predictions.append(round(prediction.item())) return torch.FloatTensor(predictions)
训练阶段代码优化
训练阶段需避免重复调用fit,优化后代码:
from sklearn.feature_extraction.text import CountVectorizer import joblib # 只fit一次即可 vectorizer = CountVectorizer(min_df=0, lowercase=False) X = vectorizer.fit_transform(df['text']).toarray() # 保存vectorizer供预测使用 joblib.dump(vectorizer, "fake_news_vectorizer.pkl")
内容的提问来源于stack exchange,提问作者Antonis Gantzos
相关产品推荐
相关产品推荐

