You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多分类文本分类预处理后验证精度下降,求原因分析

问题

我正在开展一个多分类文本分类项目,将数据集划分为训练集和测试集后,对训练集执行了如下预处理函数:

STOPWORDS = set(stopwords.words('english'))

def clean_text(text):   
    # 转小写
    text = text.lower() 
    
    # 删除特殊符号
    text = re.sub(r"(@\[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)|^rt|http.+?", "", text)  
  
    # 删除停用词
    text = ' '.join(word for word in text.split() if word not in STOPWORDS) 

    # 词干提取
    text = ' '.join([stemmer.stem(word) for word in text.split()])
    
    return text

令我意外的是,执行预处理后验证精度(59%)远低于不做任何处理的情况(69%)。我仅注释掉以下代码中的预处理调用行,精度就回升了:

all_data = dataset.sample(frac=1).reset_index(drop=True)
train_df, valid = train_test_split(all_data, test_size=0.2)

train_df['text'] = train_df['text'].apply(clean_text)

我忽略了什么?为何预处理步骤会导致精度下降?

补充信息:
文本分词代码如下:

X_train = train.iloc[:, :-1]
y_train = train.iloc[:, -1:]
X_test = valid.iloc[:, :-1]
y_test = valid.iloc[:, -1:]

weights = class_weight.compute_class_weight(class_weight='balanced', classes=np.unique(y_train), 
                                            y=y_train.values.reshape(-1))
le = LabelEncoder()
le.fit(weights)
class_weights_dict = dict(zip(le.transform(list(le.classes_)), weights))


tokenizer = Tokenizer(num_words=vocab_size, oov_token='<OOV>')
tokenizer.fit_on_texts(X_train['text'])

train_seq = tokenizer.texts_to_sequences(X_train['text'])
train_padded = pad_sequences(train_seq, maxlen=max_length, padding=padding_type, truncating=trunc_type)

validation_seq = tokenizer.texts_to_sequences(X_test['text'])
validation_padded = pad_sequences(validation_seq, maxlen=max_length, padding=padding_type, truncating=trunc_type)

模型结构如下:

model = Sequential()
model.add(Embedding(vocab_size, embedding_dim, input_length=train_padded.shape[1]))

model.add(Conv1D(48, len(GROUPS), activation='relu', padding='valid'))
model.add(GlobalMaxPooling1D())
model.add(Dropout(0.5))

model.add(Flatten())
model.add(Dropout(0.5))

model.add(Dense(len(GROUPS), activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

epochs = 100
batch_size = 32

history = model.fit(train_padded, training_labels, shuffle=True ,
                    epochs=epochs, batch_size=batch_size,
                    class_weight=class_weights_dict,
                    validation_data=(validation_padded, validation_labels),
                    callbacks=[ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=0.0001), 
                               EarlyStopping(monitor='val_loss', mode='min', patience=2, verbose=1),
                               EarlyStopping(monitor='val_accuracy', mode='max', patience=5, verbose=1)])
分析与解决思路

预处理后精度下降,大概率是以下几个原因导致的,逐个排查即可:

  • 验证集未同步执行预处理
    这是最容易犯的错误:你只对训练集做了clean_text处理,但验证集完全是原始状态。模型训练时学习的是预处理后的文本特征,验证时却输入原始文本,两者数据分布完全不匹配,精度必然暴跌。
    解决:给验证集也执行完全相同的clean_text预处理,确保训练和验证数据的特征分布一致。

  • 停用词删除过度,丢失关键语义特征
    默认的英文停用词表包含很多功能性词汇(比如"not"这类否定词),但在分类任务中,这些词往往是区分类别的核心依据——删掉"not"会直接反转文本语义,让模型完全误解输入。
    解决:

    • 检查停用词表,手动移除对当前任务重要的词汇(比如否定词、特定领域的功能性词);
    • 单独测试"删除停用词"这一步的影响,确认是不是这步导致的精度下降。
  • 词干提取破坏了有效特征
    词干提取(比如Porter Stemmer)会粗暴地将单词简化到词根,容易把语义不同的词合并成同一个形式,或者错误提取词干,丢失文本的区分度。比如"organization"和"organ"会被处理成同一个词根,完全扭曲语义。
    解决:

    • 换成更温和的词形还原(Lemmatization)工具,比如WordNetLemmatizer,它会考虑单词的词性,保留更多语义信息;
    • 暂时去掉词干提取步骤,测试精度变化,确认是不是这步的问题。
  • 正则表达式过滤过度
    你的正则规则把所有非数字、字母的字符都删除了,但在某些场景(比如社交媒体文本)中,@用户、#话题这类符号本身就是重要的分类特征,直接删除会损失关键信息。另外,正则里的^rt只匹配开头的rt,若rt出现在文本中间也可能有语义价值。
    解决:

    • 调整正则表达式,只删除真正无意义的符号,保留对任务有价值的元素;
    • 单独测试正则过滤步骤的影响,定位是否删了不该删的内容。

另外,建议把预处理步骤拆解开,每一步单独测试(比如先只做小写,看精度;再加正则,再加停用词,最后加词干),这样能精准定位是哪一步导致的精度下降。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:31:08