scikit-learn - 关于HashingVectorizer的Tfidf

时间:2016-01-04 16:38:52

标签: python python-3.x scipy scikit-learn tf-idf

我正在使用SciKit Learn对大型数据集(+ - 34.000个文件)执行一些分析。现在我在想。 HashingVectorizer旨在降低内存使用率。是否可以首先将一堆文件转换为HashingVectorizer对象(使用pickle.dump),然后将所有这些文件一起加载并将它们转换为TfIdf功能?可以从HashingVectorizer计算这些功能,因为存储了计数并且可以推导出文档的数量。我现在有以下内容:

for text in texts:
    vectorizer = HashingVectorizer(norm=None, non_negative=True)
    features = vectorizer.fit_transform([text])
    with open(path, 'wb') as handle:
        pickle.dump(features, handle)

然后,加载文件是微不足道的:

data = []
for path in paths:
    with open(path, 'rb') as handle:
        data.append(pickle.load(handle))
tfidf = TfidfVectorizer()
tfidf.fit_transform(data)

但是,魔法不会发生。我怎么能让魔法发生呢?

2 个答案:

答案 0 :(得分:3)

似乎问题是你试图将文本两次矢量化。构建计数矩阵后,您应该能够使用sklearn.feature_extraction.text.TfidfTransformer而不是TfidfVectorizer将计数转换为tf-idf要素。

此外,您保存的数据似乎是稀疏矩阵。您应该使用scipy.sparse.vstack()堆叠加载的矩阵,而不是将矩阵列表传递给TfidfTransformer

答案 1 :(得分:0)

我非常担心你的循环

for text in texts:
    vectorizer = HashingVectorizer(norm=None, non_negative=True)
    features = vectorizer.fit_transform([text])

每次你重新适应你的矢量化器时,也许它会忘记它的词汇量,所以每个矢量中的条目都不会对应于相同的单词(不确定这个我猜它取决于它们是如何做的散列);为什么不把它放在整个语料库上,即

    features = vectorizer.fit_transform(texts)

对于您的实际问题,听起来您只是想通过IDF规范化data矩阵的列;您应该能够直接在阵列上执行此操作(我已经转换为numpy数组,因为我无法解决索引在scipy数组上的工作原理)。掩码DF != 0是必需的,因为您使用了具有2 ^ 20列的散列矢量化器:

import numpy as np
X = np.array(features.todense())
DF = (X != 0).sum(axis=0)
X_TFIDF = X[:,DF != 0]/DF[DF != 0]