这取决于您使用的矢量器。在
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_计数(对于所有文档)。在