【火爐煉AI】機器學習038-NLP建立詞袋模型

【火爐煉AI】機器學習038-NLP建立詞袋模型

(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3)git

詞袋模型(Bag Of Words, BOW)和詞向量(Word Embedding, 也叫詞嵌套等)是天然語言處理和文本分析的兩個最經常使用的模型。github

詞袋模型將一段文本當作一系列單詞的集合,因爲單詞不少,故而這段文本就至關於一個袋子,裏面裝着一系列單詞。故而計算機的NLP分析就是對這個袋子進行分析,可是計算機不認識文本,只認識數字,那麼咱們須要一種機制將袋子裏的文本轉換成數字,這種機制能夠是一種Dict映射(key爲數字,value爲文本等),或數組(索引爲數字,值爲文本),或者還能夠用HashCode來計算文本的數字表示,而NLP建模就是使用這些數字來建模。詞袋在學習以後,就能夠經過構建文檔中全部單詞的直方圖來對每篇文檔進行建模。數組

詞向量模型是將單個單詞映射到一個高維空間(維度能夠到幾千幾萬甚至幾十萬),這個高維空間就用數組,或者成爲向量來表示,故而創建一種單詞-向量的映射關係,因此成爲詞向量模型。可是這種模型能表示的僅僅是單個單詞,對於有多個單詞組成的一句話,那麼就須要作進一步處理,好比一個單詞就是一個向量,N個單詞組成的一句話就是N個一維向量了,故而能夠用N個一維向量組成的矩陣來表示一句話,只不過不一樣長度的句子,該矩陣的行數不同罷了。數據結構

下面咱們僅僅學習用NLP建立詞袋模型,建立過程主要是提取文本的特徵,構建特徵向量。有兩種方法能夠構建特徵向量,分別是CountVectorizer和TfidfVectorizer。機器學習


1. 用CountVectorizer提取文本特徵

sklearn模塊中的CountVectorizer方法能夠直接提取文本特徵,這個函數只考慮詞彙在文本中出現的頻率,這個函數有一個參數:stop_words,表示是否取出停用詞,所謂的停用詞是指爲了節省空間和提升效率而自動過濾到的詞語,好比 the, is, at, which等,對於不一樣的,默認的stop_words不去除停用詞。函數

# 數據集暫時用簡·奧斯丁的《愛瑪》中的文本
dataset=nltk.corpus.gutenberg.words('austen-emma.txt')
# print(len(dataset)) # 192427 表明讀入正常
chunks=split(" ".join(dataset[:10000]), 2000) # 將前面的10000個單詞分紅五個詞袋,每一個袋子裝2000個單詞

# 構建一個文檔-詞矩陣,該矩陣記錄了文檔中每一個單詞出現的頻次
# 用sk-learn的CountVectorizer函數來實現這種構建過程
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(min_df=4, max_df=.99)
# fit_transform函數須要輸入一維數組,且數組元素是用空格連起來的文本
chunks=[" ".join(chunk) for chunk in chunks] # 故而須要轉換一下
doc_term_matrix = vectorizer.fit_transform(chunks)
feature_names=vectorizer.get_feature_names() # 獲取
print(len(feature_names)) 
print(doc_term_matrix.shape) 
# print(doc_term_matrix.T.toarray())
複製代碼

上面將簡·奧斯丁的《愛瑪》中的前面10000個單詞分紅了五個詞袋,每一個詞袋包含2000個單詞,而後用CountVectorizer創建文本特徵向量,經過fit_transform後就在CountVectorizer對象內部創建了這種文檔-詞矩陣,經過print能夠看出結果。學習

爲了更加明確的看出裏面的文檔-詞矩陣,能夠用下面的代碼將其打印出來:spa

# 打印看看doc_term_matrix這個文檔-詞矩陣裏面的內容
print('Document Term Matrix------>>>>')
bag_names=['Bag_'+str(i) for i in range(5)] # 5個詞袋
formatted_row='{:>12}'*(1+len(bag_names)) # 每一行第一列是單詞,後面是每一個詞袋中的頻率
print(formatted_row.format('Word', *bag_names))
for word, freq in zip(feature_names,doc_term_matrix.T.toarray()): # 須要裝置矩陣
    # 此處的freq是csr_matrix數據結構
    output = [str(x) for x in freq.data]
    print(formatted_row.format(word,*output))
複製代碼

-----------------------輸---------出--------------------code

Document Term Matrix------>>>> Word Bag_0 Bag_1 Bag_2 Bag_3 Bag_4 about 3 4 0 1 1 among 1 1 1 1 0 because 1 1 0 1 1 believe 0 1 1 1 3 believed 0 1 1 1 2 best 1 2 1 1 0 better 0 3 1 1 2 beyond 1 0 1 2 3orm

...

-----------------------完--------------------------------

以上是部分結果,能夠看出about在Bag_0中出現了3次,在Bag_1中出現了4次,以此類推。

若是對這種矩陣的出現次數有疑惑,能夠看個人個人github中代碼,裏面有更詳細的解釋。

值得注意的是,CountVectorizer也能夠用於中文特徵的提取,可是須要對自定義的split函數進行修改,原來的函數用空格做爲分隔符,能夠很好的將英文分詞,但對中文無效,故而中文的狀況須要將split中的分詞方式改爲jieba分詞。


2. 用TfidfVectorizer提取文本特徵

TfidfVectorizer的主要特色是:除了考量某詞彙在文本出現的頻率,還關注包含這個詞彙的全部文本的數量,這個方法可以削減高頻沒有意義的詞彙帶來的影響,挖掘更有意義的特徵。通常的,當文本條目越多,這個方法的效果越顯著。

在代碼上,用TfidfVectorizer和上面的CountVectorizer幾乎同樣,只是將類名稱替換一下便可。

# 數據集暫時用簡·奧斯丁的《愛瑪》中的文本
dataset=nltk.corpus.gutenberg.words('austen-emma.txt')
# print(len(dataset)) # 192427 表明讀入正常
chunks=split(" ".join(dataset[:10000]), 2000) # 將前面的10000個單詞分紅五個詞袋,每一個袋子裝2000個單詞

from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
# fit_transform函數須要輸入一維數組,且數組元素是用空格連起來的文本
chunks=[" ".join(chunk) for chunk in chunks] # 故而須要轉換一下
doc_term_matrix = vectorizer.fit_transform(chunks)
feature_names=vectorizer.get_feature_names() # 獲取
print(len(feature_names)) 
print(doc_term_matrix.shape) 
複製代碼

打印出來的結果並非某個單詞在詞袋中出現的頻率,而是tf-idf權重,這個權重有個計算公式,tf-idf=tf*idf,也就是說tf與idf分別是兩個不一樣的東西。其中tf爲謀個訓練文本中,某個詞的出現次數,即詞頻(Term Frequency);idf爲逆文檔頻率(Inverse Document Frequency),對於詞頻的權重調整係數。

########################小**********結###############################

1,用於詞袋模型中提取文本特徵主要有兩種方法:CountVectorizer和TfidfVectorizer,其中CountVectorizer構建的文檔-詞矩陣裏面是單詞在某個詞袋中出現的頻率,而TfidfVectorizer構建的矩陣中是單詞的tf-idf權重。

2,通常狀況下,文檔的文本都比較長,故而使用TfidfVectorizer更好一些,推薦首選這個方法。

#################################################################


注:本部分代碼已經所有上傳到(個人github)上,歡迎下載。

參考資料:

1, Python機器學習經典實例,Prateek Joshi著,陶俊傑,陳小莉譯

相關文章
相關標籤/搜索