詞袋模型的三部曲:分詞(tokenizing),統計修訂詞特徵值(counting)與標準化(normalizing)
詞袋模型:
詞袋模型(Bag of Words,簡稱BoW),所謂的詞袋模型是一種用機器學習算法對文本進行建模時表示文本數據的方法。
詞袋模型假設我們不考慮文本中詞與詞之間的上下文關係,僅僅只考慮所有詞的權重。而權重與詞在文本中出現的頻率有關。
與詞袋模型非常類似的一個模型是詞集模型(Set of Words,簡稱SoW),和詞袋模型唯一的不同是它僅僅考慮詞是否在文本中出現,而不考慮詞頻。也就是一個詞在文本在文本中出現1次和多次特徵處理是一樣的。在大多數時候,我們使用詞袋模型。
向量化
詞袋模型首先會進行分詞,在分詞之後,通過統計每個詞在文本中出現的次數,我們就可以得到該文本基於詞的特徵,如果將各個文本樣本的這些詞與對應的詞頻放在一起,就是我們常說的向量化。向量化完畢後一般也會使用TF-IDF進行特徵的權重修正,再將特徵進行標準化。 再進行一些其他的特徵工程後,就可以將數據帶入機器學習算法進行分類聚類了。
在詞袋模型的統計詞頻這一步,我們會得到該文本中所有詞的詞頻,有了詞頻,我們就可以用詞向量表示這個文本。這裏我們舉一個例子,例子直接用scikit-learn的CountVectorizer類來完成,這個類可以幫我們完成文本的詞頻統計與向量化,代碼如下:
from sklearn.feature_extraction.text import CountVectorizer
vectorizer=CountVectorizer()
corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"]
print vectorizer.fit_transform(corpus)
我們看看對於上面4個文本的處理輸出如下:
(0, 16) 1
(0, 3) 1
(0, 15) 2
(0, 4) 1
(1, 5) 1
(1, 9) 1
(1, 2) 1
(1, 6) 1
(1, 14) 1
(1, 3) 1
(2, 1) 1
(2, 0) 1
(2, 12) 1
(2, 7) 1
(3, 10) 1
(3, 8) 1
(3, 11) 1
(3, 18) 1
(3, 17) 1
(3, 13) 1
(3, 5) 1
(3, 6) 1
(3, 15) 1
可以看出4個文本的詞頻已經統計出,在輸出中,左邊的括號中的第一個數字是文本的序號,第2個數字是詞的序號,注意詞的序號是基於所有的文檔的。第三個數字就是我們的詞頻。
我們可以進一步看看每個文本的詞向量特徵和各個特徵代表的詞,代碼如下:
print vectorizer.fit_transform(corpus).toarray()
print vectorizer.get_feature_names()
輸出如下:
[[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0]
[0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0]
[1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]]
[u'and', u'apple', u'car', u'china', u'come', u'in', u'is', u'love', u'papers', u'polupar', u'science', u'some', u'tea', u'the', u'this', u'to', u'travel', u'work', u'write']
可以看到我們一共有19個詞,所以4個文本都是19維的特徵向量。而每一維的向量依次對應了下面的19個詞。另外由於詞"I"在英文中是停用詞,不參加詞頻的統計。
由於大部分的文本都只會使用詞彙表中的很少一部分的詞,因此我們的詞向量中會有大量的0。也就是說詞向量是稀疏的。在實際應用中一般使用稀疏矩陣來存儲。