文章目录
- 1. FastText 概述
- 2. FastText 分类模型
- 2.1 结构
- 2.2 n-gram
- 3. FastText 词嵌入模型
- 4. FastText的实现
- 4.1 gensim
- 4.2 fasttext
- 4.2.1 词向量训练
- 4.2.2 文本分类
1. FastText 概述
首先,我们得搞清楚,FastText 是什么?有的地方说是分类模型,有的地方又将其用于词向量,那么,FastText究竟指的是什么?我搜集资料时发现很多视频的up主都没弄清楚,其实,FastText 的指向有两个模型,一个就是指向的文本分类模型,首先在论文《Bag of Tricks for Efficient Text Classification》中提出,另一个自然就是词向量模型,首先在文章《Enriching Word Vectors with Subword Information》中提出,接下来我们将会介绍一下两种FastText模型,并将其复现。
2. FastText 分类模型
FastText的分类模型具有速度快、精度高的优点,其分类的准确率甚至不输于大型的深度学习模型,但是由于其模型简单,其训练的速度则要比后者快上好几个数量级。
2.1 结构
FastText在模型结构上采用了 模型的结构,结构如下:
- 预测的是中心词,FastText最后输出的是各个标签的概率;
- FastText 由于面向的是超多分类以及大量数据的情况,所以FastText 最后的输出采用了层级Softmax,大大优化了模型的运行速度
2.2 n-gram
首先要声明,在原论文中,n-gram并不是FastText必要的步骤,仅仅是一个锦上添花的步骤而已,没有n-gram它还是FastText。
引入n-gram首先是为了解决word2vec中的词序问题,比如两个句子“你礼貌吗”和“礼貌你吗”这两个句子仅仅词序不同,但是意思却天差地别,这种情况word2vec是检测不到词序的不同的,由此提出了n-gram。
注意,词分类模型的n-gram的是word级别的,并不是字符级别的,比如,有如下的句子
如果n-gram中的 时,那么输入其中的句子经过n-gram后被分为以下部分 三个部分,输入也是这三个部分。
尽管如此,还是需要注意一下几个方面:
- 分类模型的n-gram是word级别的,并非字符级别
- n-gram并不是FastText模型中必须的,仅仅是锦上添花
- 和 FastText都是用求和平均值来预测的
- 词向量初始化都是随机的,FastText 并没有在 word2vec 预训练词嵌入的基础上再训练
3. FastText 词嵌入模型
FastText 模型中也引入了n-gram,n-gram的引入其实是为了解决word2vec忽略词型的问题。比如单词 其实就是一个单词的不同时态,但是,在不同语境下,其词向量可能会相差特别大,而引入n-gram就是为了能够很好的解决词的形态学方面的问题。
例如一个单词 ,如果使用n-gram,当 时,可以将其分为 四个部分,在使用n-gram时一般会用一个尖括号将单词括起来,表示这个单词的开始和结束,如 变为 ,相应的n-gram也就分为 六个部分,其中每个部分又称为子词。
引入了n-gram后,接下来需要做的就是将n-gram后的部分输入模型,这里因为是根据word2vec改进的,所以依旧使用的是 模型,而这里输入的时候,因为我们有子词以及词,就又会有不同的选择了。
- 词
- 子词
- 词+子词
对于word2vec而言,其训练的有中心词以及周围词矩阵,设 为中心词矩阵, 为周围词矩阵,那么搭配就有很多种,这里FastText选择的是 ,即对中心词使用子词+词的输入来预测周围词。
2017 ACL 的 FastText展示提问环节,有人问过为什么不是 ,作者的回答是他们试过 ,发现效果并不好。
比如一个单词 ,我们将其输入到网络中时,输入的是 七个部分,并不仅是子词或是词,而 的词向量则是七个部分的总和并求平均。
对于未登录词,这里采用的方法是将 词按照n-gram进行拆解,然后将每一部分的词向量进行相加并求平均值,则得到 词的词向量。
当然,对于进行 n-gram 后没有的部分也是无法进行词向量的计算的,而且,这样做的前提是基于词的拼写、子词在形态学上是有意义的。因此,不同语言,不同效果,作者发现这种方法对阿拉伯语、德语和俄语就比对英语、法语和西班牙语效果好。
4. FastText的实现
实现FastText的过程与word2vec相差不大,唯一的差距就是word2vec使用的是一个单词来预测上下文,而FastText使用的是word+gram后的结果来进行上下文的预测,由于二者的相似性,这里就不再一步步的给大家进行实现了,如果要训练FastText模型,可以安装 fasttext
库或者使用 gensim.models
中的Fasttext模型,gensim
中的函数是生词词向量, fasttext
中既含有词向量的生成,也含有文本分类,具体使用方法如下。
4.1 gensim
-
训练模型
训练模型直接调用构造函数即可,该构造函数的参数如下:参数 描述 可选值 vector_size
词向量维度 整数 window
词向量窗口大小 整数 epochs
训练轮次 整数 negative
负采样个数 整数 sg
是否使用 skipgram
,1是使用,0是用cbow0,1 hs
是否使用层化softmax,1是使用,0是不使用 0,1 alpha
学习率 0-1 使用如下所示:
from gensim.models import FastText from gensim.models.word2vec import LineSentence model=FastText(LineSentence(open(r'../GloVe/data/test.txt', 'r', encoding='utf8')), vector_size=150, window=5, min_count=5, epochs=10, min_n=3, max_n=6, word_ngrams=1,workers=4)
-
常用API
API 描述 model.wv[word]
得到 word
的词向量"nights" in model.wv.vocab
判断词是否在词向量中 model.similarity("night", "nights")
计算两个词的相似度 model.most_similar(word, topn=n)
查找最相关的两个词 model.similarity("night", "nights")
计算两个词的相似度 -
保存模型
API 描述 model.wv.save_word2vec_format('fasttext.vector', binary=False)
保存词向量 model.save('fasttext_test.model')
保存模型 model = FastText.load('fasttext_test.model')
载入模型
4.2 fasttext
4.2.1 词向量训练
-
训练模型
这里我们以前面的预处理的文本做示例,文本处理如下。
参数 描述 可选参数 默认值 input
输入的文件 lr
学习率 0-1 0.1 dim
学习后词向量维度 整数 100 ws
背景词 整数 5 neg
负采样个数 整数 5 epoch
训练轮次 整数 5 model
训练的方式 skipgram,cbow
skipgram
wordNgrams
n-gram的值 整数 1 loss
损失函数 可选 ns, hs, softmax, ova
,hs
为层化softmax,ova
用于多标签分类softmax
model=fasttext.train_unsupervised(input='../GloVe/data/test.txt', model='skipgram')
-
常用API
API 描述 model.get_word_vector(word)
得到 word
的词向量model.get_nearest_neighbors(word)
得到距离 word
最近的10个词向量model.get_analogies(a,b,c)
类比,类比 a
和b
的关系,得到c
对应该关系的词 -
保存和加载模型
使用model.save_model(filename)
以及model.load_model(filename)
即可。
4.2.2 文本分类
-
训练模型
Fasttext用于分类使用的函数是train_unsupervised
,该函数对传入的文本数据有一定的要求,其要求传入的数据标签在前,语句在后,且标签前加上__label__
前缀,格式示例如下:__label__sauce __label__cheese How much does potato starch affect a cheese sauce recipe? __label__food-safety __label__acidity Dangerous pathogens capable of growing in acidic environments __label__cast-iron __label__stove How do I cover up the white spots on my cast iron stove? __label__restaurant Michelin Three Star Restaurant; but if the chef is not there __label__knife-skills __label__dicing Without knife skills, how can I quickly and accurately dice vegetables? __label__storage-method __label__equipment __label__bread What's the purpose of a bread box? __label__baking __label__food-safety __label__substitutions __label__peanuts how to seperate peanut oil from roasted peanuts at home? __label__chocolate American equivalent for British chocolate terms
比如上述的第一行,其标签就为
sauce, cheese
,句子为How much does potato starch affect a cheese sauce recipe?
,该函数的API如下:参数 描述 可选参数 默认值 input
输入的文件 lr
学习率 0-1 0.1 dim
学习后词向量维度 整数 100 ws
背景词 整数 5 neg
负采样个数 整数 5 epoch
训练轮次 整数 5 model
训练的方式 skipgram,cbow
skipgram
wordNgrams
n-gram的值 整数 1 loss
损失函数 可选 ns, hs, softmax, ova
,hs
为层化softmax,ova
用于多标签分类softmax
label
标签的前缀 字符串 __label__
-
常用API
API 描述 model.test(file)
对文件进行测试集的测试,返回三个参数,分别是 样本数,准确率,召回率
model.pridict(sentence,k=-1)
预测句子所属的类别,返回各个标签及概率, k=-1
表示返回全部标签及其概率 -
保存和加载模型
使用model.save_model(filename)
以及model.load_model(filename)
即可。
文章出处登录后可见!