2014-02-20 56 views
3

我正在嘗試使用scikit-learn的伯努利樸素貝葉斯分類器。我使用CountVectorizo​​r使分類器在小數據集上正常工作,但當我嘗試使用HashingVectorizo​​r處理更大的數據集時遇到了麻煩。保持所有其他參數(培訓文檔,測試文檔,分類器&特徵提取器設置)不變,僅從CountVectorizo​​r切換到HashingVectorizo​​r導致我的分類器始終爲所有文檔吐出相同的標籤。爲什麼我的scikit學習HashingVectorizo​​r給我浮動二進制=真集?

我寫了下面的腳本來調查這將是兩個特徵提取之間的不同:

from sklearn.feature_extraction.text import HashingVectorizer, CountVectorizer 

cv = CountVectorizer(binary=True, decode_error='ignore') 
h = HashingVectorizer(binary=True, decode_error='ignore') 

with open('moby_dick.txt') as fp: 
    doc = fp.read() 

cv_result = cv.fit_transform([doc]) 
h_result = h.transform([doc]) 

print cv_result 
print repr(cv_result) 
print h_result 
print repr(h_result) 

(其中「moby_dick.txt」是白鯨迪克的Project Gutenberg的複印件)

的(冷凝)結果:

(0, 17319) 1 
    (0, 17320) 1 
    (0, 17321) 1 
<1x17322 sparse matrix of type '<type 'numpy.int64'>' 
    with 17322 stored elements in Compressed Sparse Column format> 

    (0, 1048456) 0.00763203138591 
    (0, 1048503) 0.00763203138591 
    (0, 1048519) 0.00763203138591 
<1x1048576 sparse matrix of type '<type 'numpy.float64'>' 
    with 17168 stored elements in Compressed Sparse Row format> 

正如你所看到的,CountVectorizo​​r,以二進制模式,返回每個功能的價值整數1(我們只希望看到1,因爲只有一個文件);另一方面HashVectorizo​​r正在返回浮動(全部相同,但不同的文檔產生不同的值)。我懷疑我的問題源於將這些花車傳遞到BernoulliNB上。

理想情況下,我希望有一種方法可以從CountVectorizo​​r中獲取與HashingVectorizo​​r相同的二進制格式數據;否則,我可以使用BernoulliNB二進制參數,如果我知道一個合理的閾值來設置這些數據,但我不清楚這些浮點數代表什麼(它們顯然不是標記計數,因爲它們都是相同的,比1)。

任何幫助,將不勝感激。

回答

5

在默認的設置,HashingVectorizer標準化您的特徵向量單元歐幾里德長度:

>>> text = "foo bar baz quux bla" 
>>> X = HashingVectorizer(n_features=8).transform([text]) 
>>> X.toarray() 
array([[-0.57735027, 0.  , 0.  , 0.  , 0.57735027, 
     0.  , -0.57735027, 0.  ]]) 
>>> scipy.linalg.norm(np.abs(X.toarray())) 
1.0 

設置binary=True只是推遲這種歸一化,直到二進制化的特徵,即,所有的非零那些設置爲1之後。您還可以設置norm=None將其關閉:

>>> X = HashingVectorizer(n_features=8, binary=True).transform([text]) 
>>> X.toarray() 
array([[ 0.5, 0. , 0. , 0. , 0.5, 0.5, 0.5, 0. ]]) 
>>> scipy.linalg.norm(X.toarray()) 
1.0 
>>> X = HashingVectorizer(n_features=8, binary=True, norm=None).transform([text]) 
>>> X.toarray() 
array([[ 1., 0., 0., 0., 1., 1., 1., 0.]]) 

這也是爲什麼它返回float陣列:標準化需要他們。雖然向量化器可能被裝備返回另一個dtype,那麼需要在transform方法內進行轉換,並且可能需要將一個返回浮動到下一個估計器中。

+0

爲什麼會有減號? –