fasttext是facebook开源的一个词向量与文本分类工具,在开源,典型应用场景是“带监督的文本分类问题”。在当时,它的性能比肩深度学习而且速度更快。Fasttext方法包含三部分,模型架构,层次SoftMax和N-gram子词特征。模型架构fastText的架构和word2vec中的CBOW的架构类似,可能因为它们的作者之一都有Facebook的科学家Tomas Mikolov,有意思的一点是在发表word2vec论文时Tomas Mikolov在谷歌工作。下图是CBOW的模型架构:
CBOW的思路是用上下文词语来预测当前词,从而拿到模型最终的W矩阵得到词向量,而Fasttext的思路是使用模型进行文本分类操作。
Fasttext的模型架构如下:
其中x1,x2,...,xN−1,xNx1,x2,...,xN−1,xN表示一个文本中的n-gram向量,每个特征是词向量的平均值。什么是n-gram呢?
如果n为3,也叫作trigram,最小切分单位为字,则“欢迎关注数据科学杂谈”这个句子的3-gram为{“欢迎关”,“迎关注”,“关注数”,“注数据”,“数据科”,“据科学”,“科学杂”,“学杂谈”}。n-gram除了获取上下文信息,还能将语言的局部顺序保持住,想想看“羊吃草”,如果不考虑顺序,可能会有“草吃羊”的语义不正确问题。
因为每个字有字向量,例如之前CBOW得到的每个词的词向量,当我们使用n-gram时,我们将n个字向量取平均,例如我们将“欢”、“迎”、“关”三个字的向量平均后得到“欢迎关”这个词的向量。然后在隐藏层将得到的所有n-gram的词向量求平均,得到最终的一个向量。此时的情况有点像CBOW中得到的向量,和CBOW相似,此时的向量要经过一个softmax层,只是不同于CBOW的普通softmax,Fasttext中使用分层Softmax分类。分层Softmax分类作为其输出层。你可能要问,为什么要使用分层的softmax呢?
在标准的softmax中,计算一个类别的softmax概率时,我们需要对所有类别概率做归一化,在这类别很大情况下非常耗时,因此提出了分层softmax,思想是根据类别的频率构造哈夫曼树来代替标准softmax,通过分层softmax可以将复杂度从N降低到logN,下图给出分层softmax示例:
哈夫曼树中的每个叶子节点代表一种类别,在每一个非叶子节点处都要做一次二分类,走左边子树的概率为p,走右边子树的概率为1-p,这里的二分类都可以用逻辑回归表示。每一种分类都会有一条路径,也就是说,每个中间节点都是一个逻辑回归二分类器,而每个类别的概率为中间若干逻辑回归单元输出概率的连乘积。至此,我们还剩下两个问题,一是如何构造每个逻辑回归单元的输入,另一个是如何建立这棵用于判断的树形结构。首先聊聊如何构建每个逻辑单元
每个逻辑回归单元中,sigmoid函数所需的输入由三项构成,如下公式所示:
其中的含义为:⟦x⟧是一个特殊的函数,如果下一步需要向左走其值为1,向右则为-1。在训练时,我们知道最终输出叶子结点,并且从根结点到叶子结点的每一步的路径也是确定的。v' 是每个逻辑回归内部节点对应的一个向量,这个向量可以在训练过程中学习和更新。h 是网络中隐藏层的输出向量。因此,我们以隐藏层的输出向量、中间结点对应向量以及路径取向取值为输入,相乘后为一个标量,然后经过sigmoid函数,可以得到每个逻辑回归的输出值。然后计算输出值和真实值的误差反传,调节逻辑回归的单元向量v',这也就是训练的过程了。因此,我们以隐藏层的输出向量、中间结点对应向量以及路径取向取值为输入,相乘后为一个标量,然后经过sigmoid函数,可以得到每个逻辑回归的输出值。然后计算输出值和真实值的误差反传,调节逻辑回归的单元向量v' ,这也就是训练的过程了。如何建立这棵用于判断的树形结构?哈夫曼树构造是按照所有数据的类别个数统计作为每个叶子节点的权重。我们让越频繁的类别离根结点越近,使得最终的softmax经过的路径最短。
如果大家不了解哈夫曼树,以后可以写一篇原理加代码实战的文章。下面说说N-gram子词特征在英文中,还可以对单词进行子词的N-gram特征提取例如“where are you”使用3-gram后:“<wh”、“whe”、“her”、“ere”、“re>”、“<ar”、“are”、“re>”、“<yo”、“you”、“ou>”在英文中使用字词N-gram可以获取更细致的特征,例如“ed>”可能代表过去时,“ly>”可能代表副词等等。