scikit-learn - HashingVectorizer 上的 Tfidf

Posted

技术标签:

【中文标题】scikit-learn - HashingVectorizer 上的 Tfidf【英文标题】:scikit-learn - Tfidf on HashingVectorizer 【发布时间】:2016-04-08 08:01:13 【问题描述】:

我正在使用 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)

但是,魔法并没有发生。我怎样才能让魔法发生?

【问题讨论】:

【参考方案1】:

看来问题是您尝试对文本进行两次矢量化。构建计数矩阵后,您应该能够使用 sklearn.feature_extraction.text.TfidfTransformer 而不是 TfidfVectorizer 将计数转换为 tf-idf 特征。

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

【讨论】:

【参考方案2】:

我很担心你的循环

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]

【讨论】:

特征散列的想法是你不存储词汇表。矢量化器应该是无状态的。

以上是关于scikit-learn - HashingVectorizer 上的 Tfidf的主要内容,如果未能解决你的问题,请参考以下文章

无法安装 scikit-learn

scikit-learn学习基础知识四

[机器学习与scikit-learn-3]:scikit-learn模型地图与模型选择

scikit-learn:如何使用拟合概率模型?

使用 yml 环境获取 scikit-learn 版本警告

sklearn (scikit-learn) 逻辑回归包——设置训练的分类系数。