使用Sklearn统计语料词频及提取N元组的高效实现问题
嘿,看起来你已经用CountVectorizer搭好基础框架了!针对你要提取高频词汇、N元组(bigram/trigram)还不想用zip追求高效的需求,我给你整理了几个实用的思路和代码优化方案:
一、提取高频词汇(基于现有CountVectorizer)
你已经通过fit_transform得到了稀疏矩阵vectors,完全可以借助numpy的向量化操作来高效统计高频词,不用依赖zip:
import numpy as np # 补全代码:计算每个词汇的总出现次数(稀疏矩阵sum操作本身就很高效) word_counts = vectors.sum(axis=0).A1 # A1把二维稀疏矩阵转为一维数组,避免循环遍历 vocab = vectorizer_words.get_feature_names_out() # 替代旧版get_feature_names,更规范兼容 # 提取Top N高频词(比如前20个) top_n = 20 # 用argsort获取降序索引,直接定位高频词位置 sorted_indices = np.argsort(word_counts)[::-1][:top_n] top_words = [(vocab[i], word_counts[i]) for i in sorted_indices] # 输出结果 print(f"Top {top_n} 高频词汇:") for word, count in top_words: print(f"{word}: {count}")
这里用numpy的向量化操作替代zip遍历,速度快得多——毕竟numpy底层是C实现的,处理大规模语料的时候优势特别明显,完全不用自己写循环或者zip去一个个配对。
二、提取Bigram/Trigram(无需zip,高效实现)
要提取N元组,直接借助CountVectorizer的ngram_range参数就能搞定,底层已经做了优化,完全不需要自己用zip拼接:
# 提取Bigram的配置(要Trigram就把ngram_range改成(3,3),要1-3元组就设为(1,3)) vectorizer_bigram = CountVectorizer( input='content', analyzer='word', lowercase=True, stop_words=cached_stopwords, strip_accents='unicode', ngram_range=(2, 2), # 限定只提取二元组 binary=False ) bigram_vectors = vectorizer_bigram.fit_transform(X) # 统计高频Bigram,逻辑和高频词一致 bigram_counts = bigram_vectors.sum(axis=0).A1 bigram_vocab = vectorizer_bigram.get_feature_names_out() top_bigrams = 20 sorted_bigram_indices = np.argsort(bigram_counts)[::-1][:top_bigrams] top_bigram_list = [(bigram_vocab[i], bigram_counts[i]) for i in sorted_bigram_indices] # 输出结果 print(f"\nTop {top_bigrams} 高频Bigram:") for bigram, count in top_bigram_list: print(f"{bigram}: {count}")
三、进一步优化效率的小技巧
- 处理超大规模语料时,可设置
max_features参数(比如max_features=10000),只保留出现次数最多的前N个词/元组,大幅减少内存占用 - 始终保留稀疏矩阵格式操作,不要轻易转成稠密矩阵(会浪费内存),CountVectorizer的输出和numpy的sum操作都支持稀疏矩阵
- 如果需要更灵活的N元组过滤,可以搭配
token_pattern参数自定义分词规则,避免无效的元组生成
内容的提问来源于stack exchange,提问作者Rodrigo Laguna
相关产品推荐
相关产品推荐

