NLP学习3-基于机器学习的文本分类
一,学习目标
1.学会TF-IDF的原理和使用
2. 使用sklearn的机器学习模型完成文本分类
二,文本表示方法
之前只接触过图像处理,对于语音信号的表示方法不了解,刚好借此机会了解。
在深度学习中,主要的两个分支主要是基于CNN的图像处理,和基于RNN的语音信号处理。在图像处理中,主要通过CNN的卷积操作,提取特征图,进行后续的识别和其他操作。但是在自然语言领域,由于文本是不定长的,文本通常是表示为数字或向量,将不定长的文本转化到定长的空间中。例如接下来的几种方法:
1.One-hot
这种方法是将每一个词都用一个离散的向量进行表示,存在大量的数据冗余。例子如下:
对于句子
句子1:我 爱 北 京 天 安 门
句子2:我 喜 欢 上 海
首先对所有句子的字进行索引,即将每个字确定一个编号:
'我': 1, '爱': 2, '北': 3, '京': 4, '天': 5,
'安': 6, '门': 7, '喜': 8, '欢': 9, '上': 10, '海': 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]
2.Bag of Words(词袋表示)
每个文档的字/词可以使用其出现次数来进行表示。
句子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来实现这一步骤
3.N-gram
N-gram是在Count Vectors的基础上增加了相邻单词合并成新的单词,同时N-gram中的N表示N个相邻词合并,例如当N取3时:
句子1:我爱北 北京天 天安门
句子2:我喜欢 欢上海
4.TF-IDF
TF-IDF 由两部分组成:第一部分是词语频率(Term Frequency),第二部分是逆文档频率(Inverse Document Frequency)
三,代码
Count Vectors + RidgeClassifier
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score
train_df = pd.read_csv('/home/jun/NLP/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'))
结果:
f1得分=0.7406241569237678
TF-IDF + RidgeClassifier
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score
train_df = pd.read_csv('/home/jun/NLP/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'))
结果:
f1得分=0.8721598830546126