本文分別整合 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()
運行結果