1. 程式人生 > >CountVectorize和TfidVectorizer例項及引數詳解

CountVectorize和TfidVectorizer例項及引數詳解

一:

CountVectorizer 類會將文字中的詞語轉換為詞頻矩陣。也就是通過分詞後將所有的文件中的全部詞作為一個字典(就是類似於新華字典這種)。然後將每一行的詞用0,1矩陣來表示。並且每一行的長度相同,長度為字典的長度,在詞典中存在,置為1,否則,為0。

程式碼如下:

from sklearn.feature_extraction.text import CountVectorizer
 
vectorizer = CountVectorizer(min_df=1)
 
corpus = [      'This is the first document.',
    		'This is the second second document.',
    		'And the third one.',
		'Is this the first document?',
		]
X = vectorizer.fit_transform(corpus)
feature_name = vectorizer.get_feature_names()
 
print (X)
print (feature_name)
print (X.toarray())

輸出結果為:

   (0, 1)        1
  (0, 2)        1
  (0, 6)        1
  (0, 3)        1
  (0, 8)        1
  (1, 5)        2
  (1, 1)        1
  (1, 6)        1
  (1, 3)        1
  (1, 8)        1
  (2, 4)        1
  (2, 7)        1
  (2, 0)        1
  (2, 6)        1
  (3, 1)        1
  (3, 2)        1
  (3, 6)        1
  (3, 3)        1
  (3, 8)        1
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
[[0 1 1 ..., 1 0 1]
 [0 1 0 ..., 1 0 1]
 [1 0 0 ..., 1 1 0]
 [0 1 1 ..., 1 0 1]]

由於大部分文字都只會用詞彙表中很少一部分的詞,因此詞向量中有大量的0,也就是說詞向量是稀疏的。因此在實際應用中一般使用稀疏矩陣來儲存。

二:

TfidfVectorizer()類

TF-IDF的主要思想是:如果某個詞或短語在一篇文章中出現的頻率TF高,並且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類。TF-IDF實際上是:TF * IDF。

 第一種方法是在用 CountVectorizer 類向量化之後再呼叫 TfidfTransformer 類進行預處理。第二種方法是直接用 TfidfVectorizer 完成向量化與 TF-IDF 預處理。

1 CountVectorizer 結合 TfidfTransformer

依舊用上面的文字,實現如下:

from sklearn.feature_extraction.text import TfidfTransformer 
from sklearn.feature_extraction.text import CountVectorizer 
 
 
corpus = [          'This is the first document.',
		'This is the second second document.',
		'And the third one.',
		'Is this the first document?',
		]
 
 
vectorizer=CountVectorizer()
 
 
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)) 
print (tfidf)

輸出結果為:

  (0, 8)        0.438776742859
  (0, 3)        0.438776742859
  (0, 6)        0.358728738248
  (0, 2)        0.541976569726
  (0, 1)        0.438776742859
  (1, 8)        0.272301467523
  (1, 3)        0.272301467523
  (1, 6)        0.222624292325
  (1, 1)        0.272301467523
  (1, 5)        0.853225736145
  (2, 6)        0.28847674875
  (2, 0)        0.552805319991
  (2, 7)        0.552805319991
  (2, 4)        0.552805319991
  (3, 8)        0.438776742859
  (3, 3)        0.438776742859
  (3, 6)        0.358728738248
  (3, 2)        0.541976569726
  (3, 1)        0.438776742859

2 用 TfidfVectorizer

實現程式碼如下:

from sklearn.feature_extraction.text import TfidfVectorizer
tfidf2 = TfidfVectorizer()
re = tfidf2.fit_transform(corpus)
print (re)

輸出結果為:

  (0, 8)        0.438776742859
  (0, 3)        0.438776742859
  (0, 6)        0.358728738248
  (0, 2)        0.541976569726
  (0, 1)        0.438776742859
  (1, 8)        0.272301467523
  (1, 3)        0.272301467523
  (1, 6)        0.222624292325
  (1, 1)        0.272301467523
  (1, 5)        0.853225736145
  (2, 6)        0.28847674875
  (2, 0)        0.552805319991
  (2, 7)        0.552805319991
  (2, 4)        0.552805319991
  (3, 8)        0.438776742859
  (3, 3)        0.438776742859
  (3, 6)        0.358728738248
  (3, 2)        0.541976569726
  (3, 1)        0.438776742859

(1)CountVectorizer

class sklearn.feature_extraction.text.CountVectorizer(input='content', encoding='utf-8', decode_error='strict', strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, stop_words=None, token_pattern='(?u)\b\w\w+\b', ngram_range=(1, 1), analyzer='word', max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False, dtype=<class 'numpy.int64'>)
(分為三個處理步驟:preprocessing、tokenizing、n-grams generation)
引數:(一般要設定的引數是decode_error,stop_words='english',token_pattern='...'(重要引數),max_df,min_df,max_features)
input:一般使用預設即可,可以設定為"filename'或'file',尚不知道其用法
encodeing:使用預設的utf-8即可,分析器將會以utf-8解碼raw document
decode_error:預設為strict,遇到不能解碼的字元將報UnicodeDecodeError錯誤,設為ignore將會忽略解碼錯誤,還可以設為replace,作用尚不明確
strip_accents:預設為None,可設為ascii或unicode,將使用ascii或unicode編碼在預處理步驟去除raw document中的重音符號
analyzer:一般使用預設,可設定為string型別,如'word', 'char', 'char_wb',還可設定為callable型別,比如函式是一個callable型別
preprocessor:設為None或callable型別
tokenizer:設為None或callable型別
ngram_range:片語切分的長度範圍,詳細用法見http://scikit-learn.org/stable/modules/feature_extraction.html#text-feature-extraction中4.2.3.4上方第三個框
stop_words:設定停用詞,設為english將使用內建的英語停用詞,設為一個list可自定義停用詞,設為None不使用停用詞,設為None且max_df∈[0.7, 1.0)將自動根據當前的語料庫建立停用詞表
lowercase:將所有字元變成小寫
token_pattern:表示token的正則表示式,需要設定analyzer == 'word',預設的正則表示式選擇2個及以上的字母或數字作為token,標點符號預設當作token分隔符,而不會被當作token
max_df:可以設定為範圍在[0.0 1.0]的float,也可以設定為沒有範圍限制的int,預設為1.0。這個引數的作用是作為一個閾值,當構造語料庫的關鍵詞集的時候,如果某個詞的document frequence大於max_df,這個詞不會被當作關鍵詞。如果這個引數是float,則表示詞出現的次數與語料庫文件數的百分比,如果是int,則表示詞出現的次數。如果引數中已經給定了vocabulary,則這個引數無效
min_df:類似於max_df,不同之處在於如果某個詞的document frequence小於min_df,則這個詞不會被當作關鍵詞
max_features:預設為None,可設為int,對所有關鍵詞的term frequency進行降序排序,只取前max_features個作為關鍵詞集
vocabulary:預設為None,自動從輸入文件中構建關鍵詞集,也可以是一個字典或可迭代物件?
binary:預設為False,一個關鍵詞在一篇文件中可能出現n次,如果binary=True,非零的n將全部置為1,這對需要布林值輸入的離散概率模型的有用的
dtype:使用CountVectorizer類的fit_transform()或transform()將得到一個文件詞頻矩陣,dtype可以設定這個矩陣的數值型別

屬性:
vocabulary_:字典型別,key為關鍵詞,value是特徵索引,樣例如下:
com.furiousapps.haunt2: 57048
bale.yaowoo: 5025
asia.share.superayiconsumer: 4660
com.cooee.flakes: 38555
com.huahan.autopart: 67364
關鍵詞集被儲存為一個數組向量的形式,vocabulary_中的key是關鍵詞,value就是該關鍵詞在陣列向量中的索引,使用get_feature_names()方法可以返回該陣列向量。使用陣列向量可驗證上述關鍵詞,如下:
ipdb> count_vec.get_feature_names()[57048]
u'com.furiousapps.haunt2'
ipdb> count_vec.get_feature_names()[5025]
u'bale.yaowoo'

stop_words_:集合型別,官網的解釋十分到位,如下:
    Terms that were ignored because they either:
            occurred in too many documents (max_df)
            occurred in too few documents (min_df)
            were cut off by feature selection (max_features).
    This is only available if no vocabulary was given.
這個屬性一般用來程式設計師自我檢查停用詞是否正確,在pickling的時候可以設定stop_words_為None是安全的

(2)TfidfVectorizer

class sklearn.feature_extraction.text.TfidfVectorizer(input='content', encoding='utf-8', decode_error='strict', strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, analyzer='word', stop_words=None, token_pattern='(?u)\b\w\w+\b', ngram_range=(1, 1), max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False, dtype=<class 'numpy.int64'>, norm='l2', use_idf=True, smooth_idf=True, sublinear_tf=False)

TfidfVectorizer與CountVectorizer有很多相同的引數,下面只解釋不同的引數

binary:預設為False,tf-idf中每個詞的權值是tf*idf,如果binary設為True,所有出現的詞的tf將置為1,TfidfVectorizer計算得到的tf與CountVectorizer得到的tf是一樣的,就是詞頻,不是詞頻/該詞所在文件的總詞數。

norm:預設為'l2',可設為'l1'或None,計算得到tf-idf值後,如果norm='l2',則整行權值將歸一化,即整行權值向量為單位向量,如果norm=None,則不會進行歸一化。大多數情況下,使用歸一化是有必要的。

use_idf:預設為True,權值是tf*idf,如果設為False,將不使用idf,就是隻使用tf,相當於CountVectorizer了。

smooth_idf:idf平滑引數,預設為True,idf=ln((文件總數+1)/(包含該詞的文件數+1))+1,如果設為False,idf=ln(文件總數/包含該詞的文件數)+1

sublinear_tf:預設為False,如果設為True,則替換tf為1 + log(tf)。