前言
- One-hot
- Bag of Words
- N-gram
- TF-IDF
都存在一定的问题:转换得到的向量维度很高,需要较长的训练实践;没有考虑单词与单词之间的关系,只是进行了统计。
与这些表示方法不同,深度学习也可以用于文本表示,还可以将其映射到一个低纬空间。其中比较典型的例子有:FastText、Word2Vec和Bert。在本章我们将介绍FastText。
FastText入门篇
定义
FastText是一种典型的深度学习词向量的表示方法,它非常简单通过Embedding层将单词映射到稠密空间,然后将句子中所有的单词在Embedding空间中进行平均,进而完成分类操作。
所以FastText是一个三层的神经网络,输入层、隐含层和输出层。
优点
FastText在文本分类任务上,是优于TF-IDF的:
- FastText用单词的Embedding叠加获得的文档向量,将相似的句子分为一类
- FastText学习到的Embedding空间维度比较低,可以快速进行训练
资料
models.fasttext – FastText model
论文Bag of Tricks for Efficient Text Classification
GitHub的官方文档
认识 fasttext 和 初步使用
安装
pip install fasttext
有报错的!!戳这里
FastText实战篇
参数详解
from fastText import train_unsupervised
model = train_unsupervised(input, model='skipgram', lr=0.05,
dim=100, ws=5, epoch=5, minCount=5,
wordNgrams=1, loss='ns', bucket=2000000,
thread=12, lrUpdateRate=100, t=0.0001,
label='__label__', verbose=2,
pretrainedVectors='')
以fastText中的无监督训练函数为例,详细介绍各个参数的含义:
- model: 首先是模型的选择,skip-gram 以及 CBOW。其中skip-gram是给定当前词汇预测上下文单词,而CBOW则是通过上下文预测当前单词。官方给的建议是 skip-gram比较快,但是CBOW虽然比较慢,但是精度会高一点。
- lr: 学习率的选择需要调试,一般会在0.1左右,太高会报错,太低会训练的比较慢。
- epoch: epoch 要与 lr 结合考虑,一般不需要超过50次。
- dim: 得到的向量的维度,语料比较大的话,设置为300,一般语料相应的降低,具体的多大规模设置多少维度,可以尝试50到300,step=50 测试。
- ws, window size, 表示当前词与预测词在一个句子中的最大距离是多少。context window,比如 ws=5,那么是只考虑前后各两个单词 + 当前单词=5, 还是前后各5个单词+当前=11个单词? 这个需要看源码确认一下。
- wordNgrams,默认是使用 1-gram,也就是单独的词,可以尝试 bi-gram(也就是wordNgrams=2),也就是每两个word作为一个unit,会导致词数增加。如果英文的可以考虑,因为英文的每个word就是一个单词,而**中文(建议是1)**的话则是再分好词的基础上进行训练,可以直接设置为1就好,当然可以测试 bi-gram 的情况。
- loss 默认是 negtive sample, 含义是普通的softmax方法,再输出层每次再保留目标单词的同时,不采用所有的词,而是仅激活其中的一部分(比如100个)单词同 目标单词 作为输出层维度(总词数)。这个可以进行测试,虽然默认的是 ns, 但是看网上demo,用hs的要更多一些,可以进行实验对比。
- bucket, 基本没有介绍,应该是最多处理多少个词,一般默认就好了。
- minCount, 这个有时候我们比较关心,就是词频处理,默认是5,也就是词频小于5的词汇我们都不考虑(直接删除掉),这里一般如果语料比较大的话,一般这是为1就好了,不用考虑,词频太低,基本学习不到。
举例
import pandas as pd
from sklearn.metrics import f1_score
# 转换为FastText需要的格式
train_df = pd.read_csv('../data/train_set.csv', sep='\t', nrows=15000)
train_df['label_ft'] = '__label__' + train_df['label'].astype(str)
train_df[['text','label_ft']].iloc[:-5000].to_csv('train.csv', index=None, header=None, sep='\t')
import fasttext
model = fasttext.train_supervised('train.csv', lr=1.0, wordNgrams=2,
verbose=2, minCount=1, epoch=25, loss="hs")
val_pred = [model.predict(x)[0][0].split('__')[-1] for x in train_df.iloc[-5000:]['text']]
print(f1_score(train_df['label'].values[-5000:].astype(str), val_pred, average='macro'))
FastText参数优化
-
loss function 选用 hs(hierarchical softmax)要比 ns(negative sampling)训练速度更快,准确率也更高
-
wordNgram 默认为1,建议设置为 2 或以上更好
-
如果词数不是很多,可以把 bucket 设置小一些,否则会预留太多的 bucket 使模型太大