Task3 基于机器学习的文本分类


1、TF-IDF的原理和使用
【Task3 基于机器学习的文本分类】2、sklearn的机器学习模型用于文本分类

文本表示方法
在机器学习算法的训练过程中,假设给定$N$个样本,每个样本有$M$个特征,这样组成了$N×M$的样本矩阵,然后完成算法的训练和预测。同样的在计算机视觉中可以将图片的像素看作特征,每张图片看作hight×width×3的特征图,一个三维的矩阵来进入计算机进行计算。
但是在自然语言领域,上述方法却不可行:文本是不定长度的。文本表示成计算机能够运算的数字或向量的方法一般称为词嵌入(Word Embedding)方法。词嵌入将不定长的文本转换到定长的空间内,是文本分类的第一步。
One-hot
这里的One-hot与数据挖掘任务中的操作是一致的,即将每一个单词使用一个离散的向量表示。具体将每个字/词编码一个索引,然后根据索引进行赋值。
One-hot表示方法的例子如下:

句子1:我 爱 北 京 天 安 门 句子2:我 喜 欢 上 海

首先对所有句子的字进行索引,即将每个字确定一个编号:
{ '我': 1, '爱': 2, '北': 3, '京': 4, '天': 5, '安': 6, '门': 7, '喜': 8, '欢': 9, '上': 10, '海': 11 }

在这里共包括11个字,因此每个字可以转换为一个11维度稀疏向量:
我:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 爱:[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] ... 海:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

Bag of Words
Bag of Words(词袋表示),也称为Count Vectors,每个文档的字/词可以使用其出现次数来进行表示。
句子1:我 爱 北 京 天 安 门 句子2:我 喜 欢 上 海

直接统计每个字出现的次数,并进行赋值:
句子1:我 爱 北 京 天 安 门 转换为 [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]句子2:我 喜 欢 上 海 转换为 [1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]

在sklearn中可以直接CountVectorizer来实现这一步骤:
from sklearn.feature_extraction.text import CountVectorizer corpus = [ 'This is the first document.', 'This document is the second document.', 'And this is the third one.', 'Is this the first document?', ] vectorizer = CountVectorizer() vectorizer.fit_transform(corpus).toarray()

N-gram
N-gram与Count Vectors类似,不过加入了相邻单词组合成为新的单词,并进行计数。
如果N取值为2,则句子1和句子2就变为:
句子1:我爱 爱北 北京 京天 天安 安门 句子2:我喜 喜欢 欢上 上海

TF-IDF
TF-IDF 分数由两部分组成:第一部分是词语频率(Term Frequency),第二部分是逆文档频率(Inverse Document Frequency)。其中计算语料库中文档总数除以含有该词语的文档数量,然后再取对数就是逆文档频率。
TF(t)= 该词语在当前文档出现的次数 / 当前文档中词语的总数 IDF(t)= log_e(文档总数 / 出现该词语的文档总数)

基于机器学习的文本分类
接下来我们将对比不同文本表示算法的精度,通过本地构建验证集计算F1得分。
Count Vectors + RidgeClassifier
import pandas as pdfrom sklearn.feature_extraction.text import CountVectorizer from sklearn.linear_model import RidgeClassifier from sklearn.metrics import f1_scoretrain_df = pd.read_csv('../input/train_set.csv', sep='\t', nrows=15000)vectorizer = CountVectorizer(max_features=3000) train_test = vectorizer.fit_transform(train_df['text'])clf = RidgeClassifier() clf.fit(train_test[:10000], train_df['label'].values[:10000])val_pred = clf.predict(train_test[10000:]) print(f1_score(train_df['label'].values[10000:], val_pred, average='macro')) # 0.74

TF-IDF + RidgeClassifier
import pandas as pdfrom sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import RidgeClassifier from sklearn.metrics import f1_scoretrain_df = pd.read_csv('../input/train_set.csv', sep='\t', nrows=15000)tfidf = TfidfVectorizer(ngram_range=(1,3), max_features=3000) train_test = tfidf.fit_transform(train_df['text'])clf = RidgeClassifier() clf.fit(train_test[:10000], train_df['label'].values[:10000])val_pred = clf.predict(train_test[10000:]) print(f1_score(train_df['label'].values[10000:], val_pred, average='macro')) # 0.87

    推荐阅读