如何用CountVectorizer提取最不常见的N元语法?含FeatureUnion场景
提取最不常见词/字符N元语法的实现方法
CountVectorizer本身没有直接参数支持提取最不常见的特征,不过可以通过自定义词汇表的方式实现需求,具体步骤如下:
1. 统计所有特征的词频
分别对词级N元语法和字符级N元语法,先拟合一个不限制特征数量的CountVectorizer,统计所有特征的出现频次:
from sklearn.feature_extraction.text import CountVectorizer from sklearn.pipeline import FeatureUnion # 处理词级N元语法 word_vec = CountVectorizer(ngram_range=(1, 3), analyzer='word') word_vec.fit(train_texts) # 计算每个词的总出现次数 word_total_counts = word_vec.transform(train_texts).sum(axis=0).A1 # 构建词-频次字典 word_freq_dict = dict(zip(word_vec.get_feature_names_out(), word_total_counts)) # 处理字符级N元语法 char_vec = CountVectorizer(ngram_range=(1, 4), analyzer='char') char_vec.fit(train_texts) char_total_counts = char_vec.transform(train_texts).sum(axis=0).A1 char_freq_dict = dict(zip(char_vec.get_feature_names_out(), char_total_counts))
2. 筛选最不常见的200个特征
对词频字典按频次升序排序,取前200个(频次最低的),并构建成CountVectorizer要求的词汇表格式:
# 筛选词级低频特征 # 按频次升序排序,取前200个 sorted_low_freq_words = sorted(word_freq_dict.items(), key=lambda x: x[1])[:200] # 转为{特征: 索引}的字典格式 low_freq_word_vocab = {word: idx for idx, (word, _) in enumerate(sorted_low_freq_words)} # 筛选字符级低频特征 sorted_low_freq_chars = sorted(char_freq_dict.items(), key=lambda x: x[1])[:200] low_freq_char_vocab = {char: idx for idx, (char, _) in enumerate(sorted_low_freq_chars)}
3. 用自定义词汇表构建CountVectorizer并整合到FeatureUnion
把筛选好的低频词汇表传入CountVectorizer,再整合到FeatureUnion中使用:
# 构建只保留低频词的CountVectorizer word_low_vec = CountVectorizer(ngram_range=(1, 3), analyzer='word', vocabulary=low_freq_word_vocab) char_low_vec = CountVectorizer(ngram_range=(1, 4), analyzer='char', vocabulary=low_freq_char_vocab) # 整合到FeatureUnion union = FeatureUnion([('words', word_low_vec), ('chars', char_low_vec)]) # 拟合转换数据 X_train = union.fit_transform(train_texts) X_test = union.transform(test_texts)
注意事项
- 如果总特征数不足200,代码会自动取所有特征,无需额外处理
- 若存在多个特征频次相同,排序结果可能不稳定,可在排序key中加入特征名称保证一致性,例如
key=lambda x: (x[1], x[0])
内容的提问来源于stack exchange,提问作者to-0
相关产品推荐
相关产品推荐

