Facebook词向量工具FastText

FastText简介

fastText是Facebook于2016年开源的一个词向量计算和文本分类工具,在文本分类任务中,fastText(浅层网络)往往能取得和深度网络相媲美的精度,却在训练时间上比深度网络快许多数量级。在标准的多核CPU上, 能够训练10亿词级别语料库的词向量在10分钟之内,能够分类有着30万多类别的50多万句子在1分钟之内。

FastText与Word2Vec

fastText的其中的一个作者是Thomas Mikolov。也正是这个人在谷歌的时候,带领团队在2012年提出了word2vec代替了one-hot编码,将词表示为一个低维连续嵌入,极大促进了NLP的发展。14年她去了脸书,然后提出了word2vec的改进版:fasttext。所以fastText和word2vec在结构上很相似。

相同之处:

  • 图模型结构很像,都是采用 embedding 向量的形式,得到 word 的隐向量表达。
  • 采用很多相似的优化方法,比如使用 Hierarchical softmax 优化训练和预测中的打分速度。
  • 训练词向量时,两者都是无监督算法。输入层是 context window 内的 term。输出层对应的是每一个 term,计算某 term 的概率最大;
  • 在使用层次softmax的时候,huffman 树叶子节点处是训练语料里所有词的向量。

不同之处:

  • 模型的输出层:word2vec的输出层,对应的是每一个term,计算某term的概率最大;而fasttext的输出层对应的是分类的label。不过不管输出层对应的是什么内容,其对应的vector都不会被保留和使用;
  • 模型的输入层:word2vec的输入层,是 context window 内的term;而fasttext 对应的整个sentence的内容,包括term,也包括 n-gram的内容;
  • 两者本质的不同,体现在 Hierarchical softmax的使用。
    • Wordvec的目的是得到词向量,该词向量 最终是在输入层得到,输出层对应的Hierarchical softmax也会生成一系列的向量,但最终都被抛弃,不会使用。
    • fasttext则充分利用了Hierarchical softmax的分类功能,遍历分类树的所有叶节点,找到概率最大的label(一个或者N个)

FastText的优点:

  • 适合大型数据+高效的训练速度:能够训练模型“在使用标准多核CPU的情况下10分钟内处理超过10亿个词汇”,特别是与深度模型对比,fastText能将训练时间由数天缩短到几秒钟。使用一个标准多核 CPU,得到了在10分钟内训练完超过10亿词汇量模型的结果。此外, fastText还能在五分钟内将50万个句子分成超过30万个类别。
  • 支持多语言表达:利用其语言形态结构,fastText能够被设计用来支持包括英语、德语、西班牙语、法语以及捷克语等多种语言。它还使用了一种简单高效的纳入子字信息的方式,在用于像捷克语这样词态丰富的语言时,这种方式表现得非常好,这也证明了精心设计的字符 n-gram 特征是丰富词汇表征的重要来源。FastText的性能要比时下流行的word2vec工具明显好上不少,也比其他目前最先进的词态词汇表征要好。
  • fastText专注于文本分类,在许多标准问题上实现当下最好的表现(例如文本倾向性分析或标签预测)。
  • 比word2vec更考虑了相似性,比如 fastText 的词嵌入学习能够考虑 english-born 和 british-born 之间有相同的后缀,但 word2vec 却不能。

模型架构

fastText的架构和word2vec中的CBOW的架构类似,因为它们的作者Tomas Mikolov,而且确实fastText也算是word2vec所衍生出来的。

CBOW的架构

输入的是$w(t)$的上下文2d个词,经过隐藏层后,输出的是$w(t)$。word2vec将上下文关系转化为多分类任务,进而训练逻辑回归模型,这里的类别数量是$|V|$词库大小。通常的文本数据中,词库少则数万,多则百万,在训练中直接训练多分类逻辑回归并不现实。word2vec中提供了两种针对大规模多分类问题的优化手段,negative sampling 和 hierarchical softmax。在优化中,negative sampling 只更新少量负面类,从而减轻了计算量。hierarchical softmax 将词库表示成前缀树,从树根到叶子的路径可以表示为一系列二分类器,一次多分类计算的复杂度从$|V|$降低到了树的高度。

fastText模型架构

其中$x_1,x_2,…,x_{N-1},x_N$表示一个文本中的n-gram向量,每个特征是词向量的平均值。这和前文中提到的cbow相似,cbow用上下文去预测中心词,而此处用全部的n-gram去预测指定类别。注意:此架构图没有展示词向量的训练过程。可以看到,和CBOW一样,fastText模型也只有三层:输入层、隐含层、输出层(Hierarchical Softmax),输入都是多个经向量表示的单词,输出都是一个特定的target,隐含层都是对多个词向量的叠加平均。

fastText与CBOW的不同点:

  • CBOW的输入是目标单词的上下文,fastText的输入是多个单词及其n-gram特征,这些特征用来表示单个文档
  • CBOW的输入单词被one-hot编码过,fastText的输入特征是被embedding过
  • CBOW的输出是目标词汇,fastText的输出是文档对应的类标

值得注意的是,fastText在输入时,将单词的字符级别的n-gram向量作为额外的特征;在输出时,fastText采用了分层Softmax,大大降低了模型训练时间。

Hierarchical softmax

Softmax回归(Softmax Regression)又被称作多项逻辑回归(multinomial logistic regression),它是逻辑回归在处理多类别任务上的推广。

在逻辑回归中,我们有m个被标注的样本:$\{(x^{(1)}, y^{(1)}), \ldots, (x^{(m)}, y^{(m)}) \}$,其中$x^{(i)}\in R^n$。因为类标是二元的,所以我们有$y^{(i)}\in \{0,1\}$。我们的假设(hypothesis)有如下形式:$h_{\theta}(x)=\frac{1}{1+e^{-\theta^{T} x}}$

代价函数(cost function)如下:

$$J(\theta)=-[\sum_{i=1}^{m} y^{(i)} \log h_{\theta}(x^{(i)})+(1-y^{(i)}) \log (1-h_{\theta}(x^{(i)}))]$$

在Softmax回归中,类标是大于2的,因此在我们的训练集$\{(x^{(1)}, y^{(1)}), \ldots, t(x^{(m)}, y^{(m)})\}$中,。给定一个测试输入x,我们的假设应该输出一个K维的向量,向量内每个元素的值表示x属于当前类别的概率。具体地,假设$h_{\theta}$形式如下:

$$h_{\theta}(x)=[\begin{array}{c}{P(y=1 | x ; \theta)} \\ {P(y=2 | x ; \theta)} \\ {\vdots} \\ {P(y=K | x ; \theta)}\end{array}]=\frac{1}{\sum_{j=1}^{K} e^{\theta(j)^{T} x}}[\begin{array}{c}{e^{\theta^{(1)} x} x} \\ {e^{\theta(2)^{T} x}} \\ {\vdots} \\ {e^{\theta^{(K)^{T}} x}}\end{array}]$$

代价函数如下:

$$J(\theta)=-[\sum_{i=1}^{m} \sum_{k=1}^{K} 1\{y^{(i)}=k\} \log \frac{e^{\theta^{(k) T} x^{(i)}}}{\sum_{j=1}^{K} e^{\theta(j) T_{x^{(i)}}}}]$$

其中$1\{\cdot \}$是指示函数,即$1\{true\}=1,1\{false\}=0$

既然我们说Softmax回归是逻辑回归的推广,那我们是否能够在代价函数上推导出它们的一致性呢?当然可以,于是:

$$\begin{aligned} J(\theta) &=-[\sum_{i=1}^{m} y^{(i)} \log h_{\theta}(x^{(i)})+(1-y^{(i)}) \log (1-h_{\theta}(x^{(i)}))] \\ &=-\sum_{i=1}^{m} \sum_{k=0}^{1} 1\{y^{(i)}=k\} \log P(y^{(i)}=k | x^{(i)} ; \theta) \\ &=-\sum_{i=1}^{m} \sum_{k=0}^{1} 1\{y^{(i)}=k\} \log \frac{e^{\theta^{(k) T} x^{(i)}}}{\sum_{j=1}^{K} e^{\theta(j) T_{x}(i)}} \end{aligned}$$

可以看到,逻辑回归是softmax回归在K=2时的特例。你可能也发现了,标准的Softmax回归中,要计算y=j时的Softmax概率:$P(y=j)$,我们需要对所有的K个概率做归一化,这在$|y|$很大时非常耗时。于是,分层Softmax诞生了,它的基本思想是使用树的层级结构替代扁平化的标准Softmax,使得在计算$P(y=j)$时,只需计算一条路径上的所有节点的概率值,无需在意其它的节点。

下图是一个分层Softmax示例:

树的结构是根据类标的频数构造的霍夫曼树。K个不同的类标组成所有的叶子节点,K-1个内部节点作为内部参数,从根节点到某个叶子节点经过的节点和边形成一条路径,路径长度被表示为$L(y_j)$。于是$P(y_j)$就可以被写成:

$$\mathrm{P}(y_{j})=\prod_{i=1}^{L(y_{j})-1} \sigma(\left \| n(y_{j}, l+1)=L C(n(y_{j}, l))\right \| \cdot \theta_{n(y_{j}, l)}^{T} X)$$

其中:$\sigma (\cdot )$表示sigmoid函数;$LC(n)$表示n节点的左孩子;$\left \| x \right \|$是一个特殊的函数,被定义为:$\left \| x \right \| =\{\begin{aligned} 1 & \text { if } x==\text { true } \\-1 & \text { otherwise } \end{aligned}$;$\theta_{n(y_{j}, l)}$是中间节点$n(y_{j}, l)$的参数;X是Softmax层的输入。

上图中,高亮的节点和边是从根节点到$y_2$的路径,路径长度$L(y_2)=4$,$P(y_2)$可以被表示为:

$$\begin{aligned} \mathrm{P}(y_{2}) &=\mathrm{P}(n(y_{2}, 1), \text { left }) \cdot \mathrm{P}(n(y_{2}, 2), \text { left }) \cdot \mathrm{P}(n(y_{2}, 3), \text { right }) \\ &=\sigma(\theta_{n(y_{2}, 1)}^{T} X) \cdot \sigma(\theta_{n(y_{2}, 2)}^{T} X) \cdot \sigma(-\theta_{n(y_{2}, 3)}^{T} X) \end{aligned}$$

于是,从根节点走到叶子节点$y_2$,实际上是在做了3次二分类的逻辑回归。通过分层的Softmax,计算复杂度一下从$|K|$降低到$\log |K|$。

N-gram

word2vec把语料库中的每个单词当成原子的,它会为每个单词生成一个向量。这忽略了单词内部的形态特征,比如:“book” 和“books”, “apple” 和“apples”,这两个例子中,两个单词都有较多公共字符,即它们的内部形态类似,但是在传统的word2vec中,这种单词内部形态信息因为它们被转换成不同的id丢失了。

为了克服这个问题,fastText使用了字符级别的n-grams来表示一个单词。对于单词“apple”,假设n的取值为3,则它的trigram有

其中,<表示前缀,>表示后缀。于是,我们可以用这些trigram来表示“apple”这个单词,进一步,我们可以用这5个trigram的向量叠加来表示“apple”的词向量。

这带来两点好处:

  • 对于低频词生成的词向量效果会更好。因为它们的n-gram可以和其它词共享。
  • 对于训练词库之外的单词,仍然可以构建它们的词向量。我们可以叠加它们的字符级n-gram向量。

fastText的优化

子空间量化

product quantization是一种保存数据间距离的压缩技术。PQ 用一个码本来近似数据,与传统的 keams 训练码本不同的是, PQ 将数据空间划分为 k 个子空间,并分别用 kmeans 学习子空间码本。数据的近似和重建均在子空间完成,最终拼接成结果。在 fasttext 中,子空间码本大小为 256,可以用 1 byte 表示。子空间的数量在 [2, d/2] 间取值。除了用 PQ 对数据进行量化压缩,fasttext 还提供了对分类系数的 PQ 量化选项。PQ 的优化能够在不影响分类其表现的情况下,将分类模型压缩为原大小的 $\frac{1}{10}$。

裁剪字典内容

fasttext 提供了一个诱导式裁剪字典的算法,保证裁剪后的字典内容覆盖了所有的文章。具体而言,fasttext 存有一个保留字典,并在线处理文章,如果新的文章没有被保留字典涵盖,则从该文章中提取一个 norm 最大的词和其子串加入字典中。字典裁剪能够有效将模型的数量减少,甚至到原有的 $\frac{1}{100}$。

FastText的使用

使用FastText训练词向量

备注:不要使用 pip install FastText 进行安装,否则会出现如下报错:

安装流程:

使用FastText进行文本分类

另外,还可以使用gensim来使用FastText,如: from gensim.models import FastText

参考链接:

微信支付标点符 wechat qrcode
支付宝标点符 alipay qrcode

分层时间记忆HTM学习笔记

分层时间记忆算法(Hierarchical Temporal Memory),全称HTM Cortical L

Expedia异常检测项目Adaptive Alerting

Adaptive Alerting(AA)是Expedia开源的异常检测项目,整个项目也是完整一套监控体系,包

格兰杰因果关系检验学习笔记

格兰杰因果关系检验简介 格兰杰因果关系检验(英语:Granger causality test)是一种假设检定

发表评论

电子邮件地址不会被公开。 必填项已用*标注