這取決于您使用的矢量器。在
CountVectorizer統計文檔中單詞的出現次數。
它為每個文檔輸出一個(n_words, 1)向量,其中包含每個單詞在文檔中出現的次數。n_words是文檔中的單詞總數(也就是詞匯表的大小)。
它也適合詞匯表,這樣您就可以反省模型(看看哪個詞是重要的,等等)。您可以使用vectorizer.get_feature_names()查看它。在
當你把它放在前500個文檔中時,詞匯表將只由500個文檔中的單詞組成。假設有30k個這樣的矩陣,fit_transform輸出一個500x30k稀疏矩陣。
現在您再次使用接下來的500個文檔fit_transform,但是它們只包含29k個單詞,所以您得到了一個500x29k矩陣…
現在,如何調整矩陣以確保所有文檔都具有一致的表示形式?
我現在想不出一個簡單的辦法來做這件事。在
對于TfidfVectorizer您還有另一個問題,那就是文檔頻率的倒數:為了能夠計算文檔頻率,您需要一次查看所有文檔。
但是TfidfVectorizer只是一個CountVectorizer,后面跟著一個TfIdfTransformer,因此,如果您設法獲得CountVectorizer的輸出,那么您可以對數據應用TfIdfTransformer。在
使用HashingVectorizer,情況有所不同:這里沒有詞匯表。在In [51]: hvect = HashingVectorizer()
In [52]: hvect.fit_transform(X[:1000])
<1000x1048576 sparse matrix of type ''
with 156733 stored elements in Compressed Sparse Row format>
在這里,前1000個文檔中沒有1M+個不同的單詞,但是我們得到的矩陣有1M+列。
HashingVectorizer不在內存中存儲單詞。這樣可以提高內存效率,并確保返回的矩陣始終具有相同的列數。
所以您不會遇到與CountVectorizer相同的問題。在
這可能是您所描述的批處理的最佳解決方案。有兩個缺點,即你不能得到idf權重,你不知道單詞和你的特征之間的映射。在
希望這有幫助。在
編輯:
如果您有太多的數據,HashingVectorizer是最好的選擇。
如果您仍然想使用CountVectorizer,一個可能的解決方法是自己調整詞匯表并將其傳遞給向量器,這樣您只需要調用tranform。在
下面是一個您可以修改的示例:
^{pr2}$
現在,不起作用的方法是:# Fitting directly:
vect = CountVectorizer()
vect.fit_transform(X[:1000])
<1000x27953 sparse matrix of type ''
with 156751 stored elements in Compressed Sparse Row format>
注意我們得到的矩陣的大小。
“手動”匹配詞匯:def tokenizer(doc):
# Using default pattern from CountVectorizer
token_pattern = re.compile('(?u)\\b\\w\\w+\\b')
return [t for t in token_pattern.findall(doc)]
stop_words = set() # Whatever you want to have as stop words.
vocabulary = set([word for doc in X for word in tokenizer(doc) if word not in stop_words])
vectorizer = CountVectorizer(vocabulary=vocabulary)
X_counts = vectorizer.transform(X[:1000])
# Now X_counts is:
# <1000x155448 sparse matrix of type ''
# with 149624 stored elements in Compressed Sparse Row format>
#
X_tfidf = tfidf.transform(X_counts)
在您的示例中,您需要在應用tfidf轉換之前首先構建整個矩陣X_計數(對于所有文檔)。在