scikit-learn:将数据拟合为块与一次性拟合

问题描述

这取决于您使用的矢量化器。

对文档中单词的 次数进行计数。它为每个文档输出一个(n_words, 1)向量,其中每个单词出现在文档中的次数n_words是 的 (又称词汇量)。 它还适合词汇表,以便您可以对模型进行内部检查(请参阅重要的单词等)。您可以使用查看它vectorizer.get_feature_names()

当您将其放入您的前500个文档中时,词汇表将仅由500个文档中的单词组成。假设其中有30k,则fit_transform输出一个500x30k稀疏矩阵。 现在,您fit_transform又获得了500个下一个文档,但是它们仅包含29k个单词,因此您得到了一个500x29k矩阵… 现在,如何对齐矩阵以确保所有文档都具有一致的表示形式? 我目前无法想到一种简单的方法

使用 您还有另一个问题,那就是文档频率的倒数:要计算文档频率,您需要一次查看所有文档。 但是TfidfVectorizer,aCountVectorizer后面是aTfIdfTransformer,因此,如果您设法获得CountVectorizer正确的输出,则可以TfIdfTransformer在数据上应用a 。

使用 情况有所不同:这里没有词汇。

In [51]: hvect = HashingVectorizer() 
In [52]: hvect.fit_transform(X[:1000])       
<1000x1048576 sparse matrix of type '<class 'numpy.float64'>'
 with 156733 stored elements in Compressed Sparse Row format>

这里的前1000个文档中没有1M +个不同的单词,但是我们得到的矩阵有1M +个列。 在HashingVectorizer不字存储在内存中。这样可以提高内存效率,并确保返回的矩阵 。因此,您不会遇到与CountVectorizer这里相同的问题。

这可能是您描述的批处理的最佳解决方案。有两个缺点,即您无法获得idf权重,并且您不知道单词与功能间的映射。

HashingVectorizer文件的引用,做一个例子文本数据外的核心分类。可能有点混乱,但是可以完成您想做的事情。

希望这可以帮助。

:如果您有太多的数据,HashingVectorizer是要走的路。如果仍要使用CountVectorizer,可能的解决方法是自己调整词汇表的大小,然后将其传递给矢量化器,以便只需要调用即可tranform

这是您可以适应的示例:

import re
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

news = fetch_20newsgroups()
X, y = news.data, news.target

现在,这种方法行不通:

# Fitting directly:
vect = CountVectorizer()
vect.fit_transform(X[:1000])
<1000x27953 sparse matrix of type '<class 'numpy.int64'>'
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 '<class 'numpy.int64'>'
#   with 149624 stored elements in Compressed Sparse Row format>
#   
X_tfidf = tfidf.transform(X_counts)

在您的示例中,您需要先构建 矩阵X_counts(用于所有文档),然后再应用tfidf转换。

解决方法

我正在使用scikit-learn来构建分类器,该分类器适用于(较大)文本文件。目前,我需要一个简单的词袋功能,因此我尝试使用TfidfVectorizer
/ HashingVectorizer / CountVectorizer获得特征向量。

但是,一次处理整个火车数据以获得特征向量会导致numpy / scipy中的存储错误(取决于我使用的矢量化器)。所以我的问题是:

从原始文本提取文本特征时:如果我将数据按块拟合到矢量化器中,那是否与一次拟合整个数据相同?

为了用代码说明这一点,如下:

vectoriser = CountVectorizer() # or TfidfVectorizer/HashingVectorizer
train_vectors = vectoriser.fit_transform(train_data)

不同于以下内容:

vectoriser = CountVectorizer() # or TfidfVectorizer/HashingVectorizer


start = 0
while start < len(train_data):
    vectoriser.fit(train_data[start:(start+500)])
    start += 500

train_vectors = vectoriser.transform(train_data)

在此先感谢,如果这个问题完全不对,对不起。