我正在使用尝试将一些文档分为两个类,其中我使用TfidfVectorizer作为特征提取技术。
输入数据由包含大约十几个浮点数据字段、标签和文档正文的文本斑点的数据行组成。按照使用正文的顺序,我应用了 TfidfVectorizer 并得到了一个稀疏矩阵(我可以通过 toarray() 转换为数组来检查它)。这个矩阵通常非常大,数千乘数千维 - 我们称之为大小为 1000 x 15000 的 F。
要在Scikit中使用分类器,我给它一个输入矩阵X,即(行数*特征数)。如果我不使用身体,我可能会有一个尺寸为 1000 x 15 的 X。
问题是,假设我把这个 F 水平堆叠到 X,所以 X 会变成 1000 x 15015,这就引入了几个问题:1)前15个功能现在的作用很小;2)内存不足;
Scikit提供了一个仅使用TfidfVectorizer输入的示例,但没有说明如何在元数据旁边使用它。
我的问题是:如何使用 TfidfVectorizer 输出以及元数据来适应分类器进行训练?
谢谢。
-
提取词袋(tf-idf)功能,称这些
X_tfidf
。 -
提取元数据特征,调用这些
X_metadata
。 -
将它们堆叠在一起:
X = scipy.sparse.hstack([X_tfidf, X_metadata])
-
如果它没有按预期工作,请尝试重新规范化:
from sklearn.preprocessing import normalize X = normalize(X, copy=False)
如果你使用线性估计器,如LinearSVC
、LogisticRegression
或SGDClassifier
,你不应该担心特征在分类中扮演的角色;这是估计器的工作。线性估计器为每个单独的特征分配一个权重,告诉特征的信息量,即他们为您解决这个问题。
(非参数的、基于距离/相似性的模型,如核 SVM 或 k-NN 在此类数据集上可能更难。
没有将 tf-idf 描述符与其他类型的数据合并的通用方法,一切都取决于您的特定模型和数据:
- 一些模型旨在处理任意尺度的数据,因此 - 它们使用最强的预测因子,无论它们是否仅占整个特征向量的 1%。一些决策树信息标准可以成为此类方法的一个很好的例子
- 某些模型允许您直接"加权"特征,使它们比其他模型更重要,因此您可以包含一些专业知识,以便使用大型非元部分对元数据进行加权,例如N_not_meta/N_meta 尺度,其中N_x是 x 型特征维度的数量。SVM 允许您执行此类操作,因为它们是与比例相关的线性模型,因此简单的特征重新缩放可以产生这样的效果。同样在像朴素贝叶斯这样的概率模型中,您可以通过将它们各自的"概率估计"乘以一些预定义的因子来强制某些预测因子变得"强"。
- 更高级的方法是创建一个分类器的集合 - 一个用于元数据,一个用于 tfidf 和一些元分类器(因为 2 个模型的投票方案相当无用)在其输出上训练
- 您也可以通过执行一些降维方法(例如。PCA)
特定方法的选择非常特定于问题,但如您所见 - 有很多可能性,不可能简单地选择"最佳方法"。
对于内存不足的问题,您应该考虑稀疏表示,这在scikit-learn中可用。它是 NLP 数据的一个不错的选择,因为文档往往具有非常稀疏的特征向量。
一个可能的解决方案是使用主题模型(如sklearn.decomposition.NMF)执行X_tfidf
的语义投影。
这允许输入稀疏矩阵,并输出一组非稀疏和小维的特征。因此,这克服了上述答案中提到的两个问题(稀疏输入和内存有限)。
将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)的主题模型在文本分类中很常见。