整合 CountVectorizer 和 TfidfVectorizer 绘制词云图
本文分别整合 CountVectorizer 和 TfidfVectorizer 绘制词云图
✨ CountVectorizer
CountVectorizer
是 scikit-learn
中用于 文本特征提取 的一个工具,它的主要作用是将一组文本(文本集合)转换为词频向量(Bag-of-Words,词袋模型)。
简单来说:
CountVectorizer
会把文本中的每一个词(token)当作特征,然后统计每个词在每个文本中出现的次数,最终输出一个稀疏矩阵表示文本的“词频”。
🔧 作用与功能详解:
- 分词:自动将每个句子切分成词(默认以空格分割,也可以自定义分词器)。
- 构建词典:对整个语料中所有出现的词汇建立一个词汇表(字典)。
- 向量化:将每个文本表示为一个向量,每个维度是某个词在该文本中出现的次数。
📚 应用场景:
- 文本分类(如垃圾邮件识别、情感分析)
- 文本聚类
- 信息检索
- 自然语言处理(NLP)中的特征工程
⚠️ 注意:
CountVectorizer
不考虑词语顺序,即是典型的“词袋模型”。- 它也不考虑语义(两个同义词视为不同词)。
- 你可以设置
max_features
、stop_words
、ngram_range
等参数来优化结果。
✨ TfidfVectorizer
TfidfVectorizer
是 scikit-learn 提供的一个类,用于将原始文本转化为TF-IDF 特征矩阵,常用于文本分类、聚类、信息检索等任务。
🧠 TF-IDF 是什么?
TF-IDF = Term Frequency - Inverse Document Frequency
它是一种权重计算方法,用来衡量某个词对某个文档的重要性。
📌 1. TF(词频)公式:
T F ( t , d ) = 词 t 在文档 d 中出现的次数 文档 d 中总词数 TF(t, d) = \frac{\text{词 } t \text{ 在文档 } d \text{ 中出现的次数}}{\text{文档 } d \text{ 中总词数}} TF(t,d)=文档 d 中总词数词 t 在文档 d 中出现的次数
表示某个词在文档中出现的频率。
📌 2. IDF(逆文档频率)公式:
I D F ( t ) = log ( 1 + N 1 + D F ( t ) ) + 1 IDF(t) = \log \left( \frac{1 + N}{1 + DF(t)} \right) + 1 IDF(t)=log(1+DF(t)1+N)+1
- ( N ):语料库中的总文档数
- ( DF(t) ):包含词 ( t ) 的文档数量
这个公式会让出现在越少文档中的词权重越高,因为它更能“区别”文档。
📌 3. TF-IDF 综合计算:
T F - I D F ( t , d ) = T F ( t , d ) × I D F ( t ) TF\text{-}IDF(t, d) = TF(t, d) \times IDF(t) TF-IDF(t,d)=TF(t,d)×IDF(t)
⚙️ 常用参数解释
参数名 | 含义 |
---|---|
ngram_range=(1, 2) | 提取 uni-gram 和 bi-gram |
max_df=0.85 | 忽略出现在超过85%文档中的词 |
min_df=2 | 忽略出现在少于2个文档中的词 |
stop_words='english' | 去除英文停用词(中文需自定义) |
tokenizer | 自定义分词函数(适用于中文,结合 jieba) |
use_idf=True | 是否使用逆文档频率 |
smooth_idf=True | 是否进行平滑(避免分母为0) |
🧪 中文处理建议
因为 TfidfVectorizer
默认不适合中文,需要配合 jieba
分词:
import jiebadef chinese_tokenizer(text):return jieba.lcut(text)vectorizer = TfidfVectorizer(tokenizer=chinese_tokenizer)
X = vectorizer.fit_transform(docs)
📊 输出样例
假设你有:
docs = ["我 爱 你", "你 爱 他", "他 爱 我"]
输出的 TF-IDF 词向量矩阵如下:
文档索引 | 我 | 爱 | 你 | 他 |
---|---|---|---|---|
Doc1 | 0.70 | 0.50 | 0.50 | 0 |
Doc2 | 0 | 0.50 | 0.50 | 0.70 |
Doc3 | 0.50 | 0.50 | 0 | 0.70 |
✨ CountVectorizer
vs TfidfVectorizer
特性 | CountVectorizer | TfidfVectorizer |
---|---|---|
核心思想 | 统计词频(TF) | 统计 TF × IDF |
向量值 | 每个词的出现次数 | 每个词的重要性权重 |
词频高是否意味着重要 | 是 | 不一定(可能是常见词) |
适用场景 | 适合简单建模(如朴素贝叶斯) | 更适合文本分类、信息检索等 |
是否考虑语料库整体信息 | ❌ 只考虑当前文档 | ✅ 考虑所有文档的分布 |
是否支持平滑 | ❌ | ✅ 支持平滑处理 |
✨ 什么是 n-gram?
n-gram 是指连续的 n 个词。例如:
- 输入句子:
"I love machine learning"
- 1-gram(unigram):
"I"
,"love"
,"machine"
,"learning"
- 2-gram(bigram):
"I love"
,"love machine"
,"machine learning"
- 3-gram(trigram):
"I love machine"
,"love machine learning"
🛠️ ngram_range=(min_n, max_n)
说明
ngram_range=(1, 1)
:只提取 1-gram(默认)ngram_range=(1, 2)
:提取 1-gram 和 2-gramngram_range=(2, 3)
:提取 2-gram 和 3-gram
✅ 示例代码
from sklearn.feature_extraction.text import CountVectorizertext = ["I love machine learning"]# 提取1-gram和2-gram
vectorizer = CountVectorizer(ngram_range=(1, 2))
X = vectorizer.fit_transform(text)print(vectorizer.get_feature_names_out())
print(X.toarray())
输出结果:
['i' 'i love' 'learning' 'love' 'love machine' 'machine' 'machine learning']
[[1 1 1 1 1 1 1]]
这表示:
- 单个词(unigram)和两个词组合(bigram)都被统计了。
🎯 使用场景建议
ngram_range=(1, 2)
:适合大多数 NLP 应用,可以捕捉常见词和短语搭配。ngram_range=(2, 2)
:适合挖掘关键词对(如“机器 学习”)ngram_range=(2, 3)
:更强调上下文结构,但维度较高,需要更多数据支持。
⚠️ 注意:
- 提取更多的 n-gram 会导致维度爆炸(特征太多),要结合
max_features
或min_df
限制特征数量。 - 高阶 n-gram 更稀疏,也更依赖大规模语料支持。
✨ 词云可视化
安装相关的依赖
pip install wordcloud scikit-learn matplotlib
代码
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
import matplotlib.pyplot as plt
from wordcloud import WordCloud# 示例文本
texts = ["Natural language processing is fun and exciting.","Machine learning and deep learning are key techniques in AI.","I love studying machine learning and natural language tasks.",
]# 初始化向量器,提取 1-gram 到 2-gram,可以使用CountVectorizer或TfidfVectorizer
vectorizer = CountVectorizer(ngram_range=(1, 2), stop_words='english')
# vectorizer = TfidfVectorizer(ngram_range=(1, 2), stop_words='english')X = vectorizer.fit_transform(texts)# 提取关键词和其对应的 分数值,对于 TF-IDF 是分数值,对于 CountVectorizer 是频率值
feature_names = vectorizer.get_feature_names_out()
print("Features:", feature_names)# 每个词语在所有文档中分数的总和
_scores = X.sum(axis=0).A1# 构建关键词:权重的字典
word_dict = dict(zip(feature_names, _scores))# 生成词云图
wordcloud = WordCloud(width=800, height=400, background_color='white').generate_from_frequencies(word_dict)# 显示图形
plt.figure(figsize=(12, 6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.title("TF-IDF Weighted WordCloud (1-2 gram)")
plt.show()
运行结果