6

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

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

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

这就是问题所在,假设我将这个 F 水平叠加到 X 上,所以 X 将变为 1000 x 15015,这引入了一些问题: 1)现在前 15 个特征将发挥很小的作用;2)内存不足;

Scikit 提供了一个示例,其中仅使用 TfidfVectorizer 输入,但没有说明如何将它与元数据一起使用。

我的问题是:如何将 TfidfVectorizer 输出与元数据一起用于训练分类器?

谢谢你。

4

3 回答 3

8
  1. 提取词袋 (tf-idf) 特征,调用这些X_tfidf.

  2. 提取元数据特征,调用这些X_metadata.

  3. 将它们堆叠在一起:

    X = scipy.sparse.hstack([X_tfidf, X_metadata])
    
  4. 如果它没有按预期工作,请尝试重新规范化:

    from sklearn.preprocessing import normalize
    X = normalize(X, copy=False)
    

LinearSVC如果您使用线性估计器,例如LogisticRegressionSGDClassifier,则不必担心特征在分类中所起的作用;这是估算员的工作。线性估计器为每个单独的特征分配一个权重,以说明该特征的信息量,即他们为您计算出来。

(非参数、基于距离/相似性的模型,例如内核 SVM 或 k-NN 可能在此类数据集上比较困难。)

于 2013-10-19T17:26:29.970 回答
3

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

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

特定方法的选择是针对特定问题的,但正如您所见 - 有很多可能性,并且不可能简单地选择“最佳方法”。

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

于 2013-10-19T16:47:04.110 回答
0

一种可能的解决方案是X_tfidf使用诸如sklearn.decomposition.NMF之类的主题模型执行语义投影。

这允许输入稀疏矩阵,并输出一组非稀疏小维的特征。因此,这克服了上面答案中提到的两个问题(稀疏输入和有限的内存)

将向量投影X_tfidf到 20-D 特征向量的示例:

nmf = NMF(n_components=20)
nmf.fit(data)
X_transformed = nmf.transform(X_tf_idf)

这里的“数据”是为适合分解模型而给出的任何一组特征(理想情况下,一组保留的特征)。

然后您可以安全地将其与其他功能合并

X = scipy.sparse.hstack([X_transfored, X_metadata])

其他投影是可能的,例如 PCA,但通过矩阵分解(例如 NMF 或SVD )的主题模型在文本分类中很常见。

于 2016-04-28T12:49:33.230 回答