如何使用词袋模型(BoW)处理词汇表外词并避免数据泄露问题
核心问题说明
- 错误1:分别在训练集、测试集上拟合CountVectorizer,既导致词汇表不一致,也违背了测试集不能参与特征拟合的防泄露要求
- 错误2:最后一行列过滤的pandas语法调用逻辑错误
- 效率冗余:无需手动对齐列,CountVectorizer本身支持基于训练集词汇表直接转换测试集,不在词汇表的OOV词会被自动忽略,输出维度和训练集完全一致,不需要额外编写填充逻辑
修正后的实现代码
import nltk import pandas as pd from sklearn.feature_extraction.text import CountVectorizer # 仅用训练集拟合词袋模型,无数据泄露风险 train_tokens = train['text'].apply(nltk.word_tokenize) cvec = CountVectorizer(min_df = .01, max_df = .99, ngram_range=(1,2), tokenizer=lambda doc:doc, lowercase=False) cvec.fit(train_tokens) # 分别转换训练集、测试集,输出特征维度自动对齐 X_train = pd.DataFrame(cvec.transform(train_tokens).toarray(), columns=cvec.get_feature_names_out()) test_tokens = test['text'].apply(nltk.word_tokenize) X_test = pd.DataFrame(cvec.transform(test_tokens).toarray(), columns=cvec.get_feature_names_out())
原代码冗余/错误补充说明
原有自定义bow函数每次调用都会重新拟合CountVectorizer,是导致特征维度不一致的核心原因。最后一行的列过滤逻辑即使修正语法为X_test = X_test[[col for col in X_test.columns if col in vocab]],也依然存在性能损耗,且会丢失训练集存在但测试集未出现的特征列,反而需要额外补全0值列,远不如直接用训练集拟合好的向量器转换测试集高效。
内容的提问来源于stack exchange,提问作者Kim S.
相关产品推荐
相关产品推荐

