如何在实践中使用TfidfVectorizer和元数据进行分类?

log*_*og0 4 classification machine-learning tf-idf scikit-learn

我正在尝试将一些文档分类为两个类,其中我使用TfidfVectorizer作为特征提取技术.

输入数据由包含大约十几个浮点数据字段,标签和文档正文的文本blob的数据行组成.为了使用正文,我应用了TfidfVectorizer并得到了一个稀疏矩阵(我可以通过toarray()转换为数组来检查).这个矩阵通常非常大,数千个维度 - 让我们称这个F的大小为1000 x 15000.

要在Scikit中使用分类器,我给它一个输入矩阵X,即(行数*特征数).如果我不使用身体,我可能有一个1000 x 15的X.

这是问题所在,假设我将这个F水平叠加到X,所以X将变成1000 x 15015,这会引入一些问题:1)前15个特征现在扮演的角色很小; 2)内存不足;

Scikit提供了一个仅使用TfidfVectorizer输入的示例,但没有说明如何在元数据旁边使用它.

我的问题是:你如何使用TfidfVectorizer输出和元数据来适应训练的分类器?

谢谢.

Fre*_*Foo 8

  1. 提取词袋(tf-idf)功能,调用这些X_tfidf.

  2. 提取元数据功能,调用它们X_metadata.

  3. 把它们叠在一起:

    X = scipy.sparse.hstack([X_tfidf, X_metadata])
    
    Run Code Online (Sandbox Code Playgroud)
  4. 如果它不能按预期工作,请尝试重新规范化:

    from sklearn.preprocessing import normalize
    X = normalize(X, copy=False)
    
    Run Code Online (Sandbox Code Playgroud)

如果你使用线性估算器LinearSVC,LogisticRegression或者SGDClassifier,你不应该担心特征在分类中扮演的角色; 这是估算师的工作.线性估计器为每个单独的特征赋予权重,告诉他们该特征的信息量,即他们为您解决这个问题.

(非参数,基于距离/相似性的模型,如内核SVM或k-NN,可能会在这些数据集上花费更多时间.)


lej*_*lot 3

没有将 tf-idf 描述符与其他类型的数据合并的通用方法,一切都取决于您的特定模型和数据:

  • 有些模型旨在处理任意规模的数据,因此它们使用最强的预测变量,无论它们是否只是整个特征向量的 1%。一些决策树信息标准可以是此类方法的一个很好的例子
  • 有些模型允许您直接“加权”特征,使它们比其他特征更重要,因此您可以包含一些专业知识,以便用较大的非元部分对元数据进行加权,例如通过 N_not_meta/N_meta 比例,其中 N_x是 x 类型特征维度的数量。SVM 可以让你做这样的事情,因为它们是尺度相关的线性模型,所以简单的特征重新缩放就可以产生这样的效果。此外,在朴素贝叶斯等概率模型中,您可以通过将某些预测变量各自的“概率估计”乘以某个预定义因子来强制它们变得“强”。
  • 更先进的方法是创建一组分类器 - 一个用于元数据,一个用于 tfidf 和一些元分类器(因为 2 个模型的投票方案相当无用)根据其输出进行训练
  • 您还可以通过执行某种降维方法(例如 PCA)来简单地降低第二部分的维度

特定方法的选择与具体问题密切相关,但正如您所看到的,有很多可能性,不可能简单地选择“最好的方法”。

对于内存不足问题,您应该考虑scikit-learn 中可用的稀疏表示。对于 NLP 数据来说,这是一个不错的选择,因为文档往往具有非常稀疏的特征向量。