使用 TF-IDF + TruncatedSVD+ LabelEncoder + LinearSVC 进行多分类文本预测


概述

最近在做一个基于小规模、样本不均衡的文本数据,预测多分类标签的小型项目,最终输出结果虽然不能说是非常让人满意,但考虑到先天条件,已经可以说是大致上过得去,故简单总结一下整体项目的技术路线。

相关模型

1. TF-IDF

参考文档 Sklearn text-feature-extraction

sklearn.feature_extraction.text.TfidfVectorizer

TF-IDF 可以将原始的文档集合,转换为 TF-IDF 特征矩阵,使计数特征重新加权为适合分类器使用的浮点值,这里面 TF 表示词频 Term Frequency,IDF 表示逆文本频率指数 Inverse Document Frequency。

TF-IDF 是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

在大型文本语料库中,某些单词会非常出现(例如英语中的“ the”,“ a”,“ is”),因此几乎没有关于文档实际内容的有意义的信息。如果我们将直接计数数据直接提供给分类器,那么那些非常频繁的术语会掩盖稀有但更有趣的术语的出现频率。

2. TruncatedSVD

参考文档 Truncated singular value decomposition and latent semantic analysis 参考文档 LSA(Latent semantic analysis)

sklearn.decomposition.TruncatedSVD

Truncated SVD 一种降维方式,aka LSA。之所以采用这种方式,而不是常用的 PCA 主要原因在于这种方式,可以直接作用与稀疏矩阵,而无需向把稀疏矩阵转换为 array(PCA需要)

对于一些文本特征,由于文本量巨大,导致特征数巨大,如果把稀疏矩阵转换为 dense,会直接导致内存溢出,而这种方法就没有这个问题,同时他的性能也更好。

In particular, truncated SVD works on term count/tf-idf matrices as returned by the vectorizers in sklearn.feature_extraction.text. In that context, it is known as latent semantic analysis (LSA).

When truncated SVD is applied to term-document matrices (as returned by CountVectorizer or TfidfVectorizer), this transformation is known as latent semantic analysis (LSA), because it transforms such matrices to a “semantic” space of low dimensionality. In particular, LSA is known to combat the effects of synonymy and polysemy (both of which roughly mean there are multiple meanings per word), which cause term-document matrices to be overly sparse and exhibit poor similarity under measures such as cosine similarity.

如官方文档所言,这种模型可以非常良好地作用于 tf-idf 的返回结果,在这种情况下,它被称为潜在的语义分析(LSA)

注:LSA(潜在语义分析),最初是用在语义检索上,为了解决一词多义和一义多词的问题,

原理:LSA潜在语义分析的目的,就是要找出词(terms)在文档和查询中真正的含义,也就是潜在语义,从而解决上节所描述的问题。具体说来就是对一个大型的文档集合使用一个合理的维度建模,并将词和文档都表示到该空间,比如有2000个文档,包含7000个索引词,LSA使用一个维度为100的向量空间将文档和词表示到该空间,进而在该空间进行信息检索。而将文档表示到此空间的过程就是SVD奇异值分解和降维的过程。降维是LSA分析中最重要的一步,通过降维,去除了文档中的“噪音”,也就是无关信息(比如词的误用或不相关的词偶尔出现在一起),语义结构逐渐呈现。相比传统向量空间,潜在语义空间的维度更小,语义关系更明确。

对于上述模型,需要注意的是,n_components 参数,对于 LSA 官方推荐使用的参数是 100.

3. LabelEncoder

使用 0 - n_classes-1 的值,来对目标标签进行编码。

这个转换器主要用于 y label 值的转换.

示例:

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
LabelEncoder()
list(le.classes_) # 注:classes_ 为编码结果从 0 开始按序排列
# ['amsterdam', 'paris', 'tokyo']
le.transform(["tokyo", "tokyo", "paris"]) # 对 label 进行转换
# array([2, 2, 1]...)
list(le.inverse_transform([2, 2, 1])) # 将编码值还原为 label
# ['tokyo', 'tokyo', 'paris']

4. LinearSVC

参考文档 svm-classification

sklearn.svm.LinearSVC

LinearSVC 即 Linear Support Vector Classification. 类似于带有 kernel='linear' 的 SVC。

注1:LinearSVC 通过 .decision_function 的方法给出了每个item的每个分类的置信度分数。

注2:LinearSVC 可以通过设置 class_weight = balanced 来应对样本不均衡问题,如果不设置 class_weight = balanced 则默认每个样本的权重都为1,balanced 模式下,会使用 y 值自动进行权重调整(调整后的权重为 y 中某值出现频率的反比 -> n_samples / (n_classes * np.bincount(y)))(np.bincount(y) 用于计算非负整数数组中每个值的出现次数)

注3:SVM 算法不是缩放不变的,因此强烈建立对数据进行缩放,例如:将输入向量 X 上的每个属性缩放到 [-1, 1] 或 [0, 1]

相关资料

  1. Classification of text documents using sparse features (使用稀疏矩阵进行文本分类)