from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer、HashingVectorizer
你再次贴出了同一行代码:
from sklearn.feature_extraction.text import CountVectorizer
这行代码本身是 scikit-learn 的文本特征提取模块导入语句,作用是引入 CountVectorizer 这个类,用于把文本转换成词频矩阵(词袋模型)。
如果你是想问关于它的具体问题,可以告诉我方向,比如:
-
这行代码报错(如
ModuleNotFoundError)→ 需要先安装 scikit-learn:pip install scikit-learn -
想知道怎么用 → 参考上一条回复的完整示例。
-
想结合极客时间那篇文章的具体上下文 → 把文章里相关的代码段或疑问贴出来,我帮你对照分析。
-
想对比其他向量化方法 → 可以聊
TfidfVectorizer、HashingVectorizer的区别。
你具体想了解哪方面?
TfidfVectorizer vs HashingVectorizer 详解
两者都是 scikit-learn 中把文本转成数值向量的工具,但设计目标和适用场景差别很大。下面从原理、用法、优缺点三个维度对比。
一、TfidfVectorizer
原理
TF-IDF = 词频(TF)× 逆文档频率(IDF)
- TF:某个词在当前文档中出现的次数(或频率)
- IDF:
log(总文档数 / 包含该词的文档数),用来降低常见词的权重
最终每个词的权重 = TF × IDF。一个词在当前文档出现越多、但在其他文档出现越少,权重越高,越有区分度。
基本用法
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
'我 爱 北京 天安门',
'天安门 上 太阳 升',
'我 爱 北京',
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names_out())
print(X.toarray()) # 每行是一个文档的 TF-IDF 向量
中文场景
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
def cut(text):
return jieba.lcut(text)
vectorizer = TfidfVectorizer(tokenizer=cut)
X = vectorizer.fit_transform(corpus)
常用参数
| 参数 | 说明 |
|---|---|
tokenizer |
自定义分词器(中文必用) |
ngram_range=(1,2) |
提取 1-gram 和 2-gram |
stop_words |
停用词 |
max_features |
只保留权重最高的 N 个词 |
min_df / max_df |
忽略过少/过多出现的词 |
norm='l2' |
向量归一化方式(默认 L2) |
use_idf=True |
是否启用 IDF(设为 False 就退化成 CountVectorizer) |
smooth_idf=True |
IDF 平滑,避免除零 |
特点
- ✅ 可解释性强:能拿到词汇表,知道每列对应哪个词
- ✅ 权重合理:自动压低"的、了、是"这类高频无意义词
- ✅ 适合小到中等规模语料
- ❌ 需要先 fit 建立词汇表,再 transform,无法处理训练时没见过的词(OOV)
- ❌ 词汇表要存在内存里,语料极大时内存压力大
- ❌ 不支持在线学习(增量 fit 受限)
二、HashingVectorizer
原理
不建立词汇表,而是用一个哈希函数把每个词直接映射到固定维度的向量某一列:
词 → hash(词) % n_features → 列索引
词频直接累加到对应列上。因为不需要维护"词→索引"的映射表,所以内存占用恒定。
基本用法
from sklearn.feature_extraction.text import HashingVectorizer
corpus = [
'我 爱 北京 天安门',
'天安门 上 太阳 升',
'我 爱 北京',
]
vectorizer = HashingVectorizer(n_features=2**10) # 1024 维
X = vectorizer.transform(corpus) # 注意:只有 transform,没有 fit!
print(X.shape) # (3, 1024)
关键点:HashingVectorizer 没有 fit 方法(或说 fit 是空操作),因为哈希映射是固定的,不需要学习。所以通常直接 transform。
常用参数
| 参数 | 说明 |
|---|---|
n_features |
哈希空间维度,默认 2**20,越大冲突越少 |
alternate_sign=True |
哈希符号随机化,减少冲突带来的偏差 |
norm='l2' |
归一化 |
ngram_range |
n-gram 范围 |
stop_words |
停用词 |
特点
- ✅ 内存恒定:不管语料多大,内存占用只取决于
n_features - ✅ 支持流式/在线学习:可以配合
SGDClassifier做增量训练,适合大规模、无法一次性载入内存的数据 - ✅ 训练和预测解耦:新文档直接 transform,不怕 OOV
- ✅ 速度快:无需构建词汇表
- ❌ 不可解释:拿不到"第 5 列是哪个词",无法反向映射
- ❌ 哈希冲突:不同词可能映射到同一列,造成信息损失(
n_features越大冲突越少) - ❌ 无法做特征选择:没有
get_feature_names_out()
三、核心对比表
| 维度 | TfidfVectorizer | HashingVectorizer |
|---|---|---|
| 是否建词汇表 | ✅ 建 | ❌ 不建 |
| 是否有 fit | ✅ 有 | ❌ 无(fit 是空操作) |
| 内存占用 | 随词汇表增长 | 恒定(取决于 n_features) |
| 可解释性 | ✅ 知道每列对应词 | ❌ 无法反查 |
| 哈希冲突 | 无 | 有(n_features 越大越少) |
| OOV 新词 | ❌ 忽略 | ✅ 直接哈希 |
| 在线/增量学习 | 受限 | ✅ 天然支持 |
| 适用规模 | 小~中等 | 大~超大 / 流式 |
| 典型搭档 | 朴素贝叶斯、SVM、LR | SGDClassifier、在线学习 |
四、怎么选?
语料能否一次性载入内存?
├─ 能 → 需要解释特征 / 做特征分析?
│ ├─ 是 → TfidfVectorizer
│ └─ 否 → 两者都行,Tfidf 更常见
└─ 不能 / 流式数据 → HashingVectorizer + SGDClassifier
经验法则:
- 做实验、调参、需要看特征重要性 → TfidfVectorizer
- 工业级大规模、在线训练、内存受限 → HashingVectorizer
- 想要 TF-IDF 效果又想要哈希的内存优势 → 可以用
HashingVectorizer+TfidfTransformer组合(先哈希计数,再手动 TF-IDF)
五、三兄弟横向对比(含 CountVectorizer)
| CountVectorizer | TfidfVectorizer | HashingVectorizer | |
|---|---|---|---|
| 输出 | 原始词频 | TF-IDF 权重 | 哈希后的词频(或符号化) |
| 建词汇表 | ✅ | ✅ | ❌ |
| 内存 | 中 | 中 | 低且恒定 |
| 可解释 | ✅ | ✅ | ❌ |
| 在线学习 | 差 | 差 | ✅ |
| 常见用途 | 词袋基线 | 文本分类主力 | 大规模/流式 |
如果你有具体场景(比如数据量多大、要不要在线学习、是否要做特征分析),我可以帮你选一个更合适的方案。
本文来自博客园,作者:AceFenix,转载请注明原文链接:https://www.cnblogs.com/ukzq/p/23120631

浙公网安备 33010602011771号