文本表示:从one-hot到word2vec
词袋模型:one-hot编码
one-hot编码,又称独热编码、一位有效编码。其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。
考虑一下的三个特征:
[“male”, “female”]
[“from Europe”, “from US”, “from Asia”]
[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]将它换成独热编码后,应该是:
feature1=[01,10]
feature2=[001,010,100]
feature3=[0001,0010,0100,1000]
优点:
- 解决了分类器不好处理离散数据的问题
- 在一定程度上也起到了扩充特征的作用
缺点:
- 属于词袋模型,不考虑词与词之间的顺序
- 假设词与词相互独立
- 得到的特征是离散稀疏的
比如如果将世界所有城市名称作为语料库的话,那这个向量会过于稀疏,并且会造成维度灾难。
杭州 [0,0,0,0,0,0,0,1,0,……,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,1,0,0,0,0,0,……,0,0,0,0,0,0,0]
北京 [0,0,0,0,0,0,0,0,0,……,1,0,0,0,0,0,0]
分布式表示
Dristributed representation可以解决One hot representation的问题,它的思路是通过训练,将每个词都映射到一个较短的词向量上来。所有的这些词向量就构成了向量空间,进而可以用普通的统计学的方法来研究词与词之间的关系。
将词从一个可能非常稀疏的向量坐在的空间,映射到低维向量所在的空间,必须满足以下性质:
- 这个映射是单设(不懂的概念自行搜索)
- 映射之后的向量不会丢失之前的那种向量所含的信息
这个过程称为word embedding(词嵌入),即将高维词向量嵌入到一个低维空间。
word2vec
word2vec模型其实就是简单化的神经网络。
输入是One-Hot Vector,Hidden Layer没有激活函数,也就是线性的单元。Output Layer维度跟Input Layer的维度一样,用的是Softmax回归。当这个模型训练好以后,我们并不会用这个训练好的模型处理新的任务,我们真正需要的是这个模型通过训练数据所学得的参数,例如隐层的权重矩阵。
模型定义数据的输入和输出一般分为CBOW(Continuous Bag-of-Words) 与Skip-Gram两种模型。
CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。
Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。
CBOW对小型数据库比较合适,而Skip-Gram在大型语料中表现更好。
CBOW(Continuous Bag-of-Words)
CBOW的训练模型如图所示:
- 输入层:上下文单词的one-hot。(假设单词向量空间$dim$为$V$,上下文单词个数为$C$)
- 所有one-hot分别乘以共享的输入权重矩阵$W$。 ($V*N$矩阵,$N$为自己设定的数,初始化权重矩阵$W$)
- 所得的向量 (因为是one-hot所以为向量)相加求平均作为隐层向量,size为$1*N$。
- 乘以输出权重矩阵$W’$($N*V$)
- 得到向量 ($1*V$) 激活函数处理得到$V-dim$概率分布(PS: 因为是one-hot嘛,其中的每一维都代表着一个单词)
- 概率最大的index所指示的单词为预测出的中间词(target word)与true label的one-hot做比较,误差越小越好(根据误差更新权重矩阵)
需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新$W$和$W’$。训练完毕后,输入层的每个单词与矩阵$W$相乘得到的向量的就是我们想要的词向量(word embedding),这个矩阵(所有单词的word embedding)也叫做look up table(这个look up table就是矩阵$W$自身)。任何一个单词的one-hot乘以这个矩阵都将得到自己的词向量。有了look up table就可以免去训练过程直接查表得到单词的词向量了。
Skip-Gram
直观上理解,Skip-Gram是给定input word来预测上下文。
假如我们有一个句子,首先选择句子中间的一个词作为输入词 input word;有了input word以后,再定义一个叫做 skip_window 的参数,代表从当前 input word 的一侧(左边或右边)选取词的数量。另一个参数叫 num_skips,代表从整个窗口(包括input word在内)中选取多少个不同的词作为 output word,当skip_window=2,num_skips=2时,我们将会得到两组 (input word, output word) 形式的训练数据,即 (‘dog’, ‘barked’),(‘dog’, ‘the’)。
神经网络基于这些训练数据将会输出一个概率分布,这个概率代表词典中的每个词是 output word 的可能性。模型的输出概率代表词典中每个词有多大可能性跟 input word 同时出现。通过给神经网络输入文本中成对的单词来训练它完成概率计算。
下面的图中给出了一些我们的训练样本的例子。选定句子“The quick brown fox jumps over lazy dog”,设定窗口大小为2(window_size=2),即仅选输入词前后各两个词和输入词进行组合。下图中,蓝色代表input word,方框内代表位于窗口内的单词。
模型将会从每对单词出现的次数中习得统计结果。最终我们需要的是训练出来的权重矩阵。
走进FastText
Fasttext是facebook开源的一个词向量与文本分类工具,在2016年开源,典型应用场景是“带监督的文本分类问题”。提供简单而高效的文本分类和表征学习的方法,性能比肩深度学习而且速度更快。fastText的代码整体结构如下图所示。
FastText的原理
fastText方法包含三部分,模型架构、层次SoftMax 和 N-gram子词特征。
fastText在输入时,将单词的字符级别的n-gram向量作为额外的特征;在输出时,fastText采用了分层Softmax,大大降低了模型训练时间。
fastText的核心思想就是:将整篇文档的词及n-gram向量叠加平均得到文档向量,然后使用文档向量做softmax多分类。
模型架构
fastText的架构和word2vec中的CBOW的架构类似,因为它们的作者都是Facebook的科学家Tomas Mikolov,而且确实fastText也算是word2vec所衍生出来的。fastText模型架构如图,其中$x_1,x_2,\dots ,x_{N−1},x_N$表示一个文本中的n-gram向量,每个特征是词向量的平均值。这和前文中提到的CBOW相似,CBOW用上下文去预测中心词,而此处用全部的n-gram去预测指定类别。
层次SoftMax
对于有大量类别的数据集,fastText使用了一个分层分类器(而非扁平式架构)。不同的类别被整合进树形结构中(想象下二叉树而非 list)。在某些文本分类任务中类别很多,计算线性分类器的复杂度高。为了改善运行时间,fastText 模型使用了层次Softmax 技巧。层次Softmax 技巧建立在哈弗曼编码的基础上,对标签进行编码,能够极大地缩小模型预测目标的数量。
fastText 也利用了类别不均衡这个事实(一些类别出现次数比其他的更多),通过使用 Huffman算法建立用于表征类别的树形结构。因此,频繁出现类别的树形结构的深度要比不频繁出现类别的树形结构的深度要小,这也使得进一步的计算效率更高。
N-gram子词特征
fastText 可以用于文本分类和句子分类。不管是文本分类还是句子分类,常用的特征是词袋模型。但词袋模型不能考虑词之间的顺序,因此 fastText 还加入了 N-gram 特征。在 fasttext 中,每个词被看做是 n-gram字母串包。为了区分前后缀情况,”<”, “>”符号被加到了词的前后端。除了词的子串外,词本身也被包含进了 n-gram字母串包。以 where 为例,n=3的情况下,其子串分别为
fastText 和 word2vec 的区别
相似处:
- 图模型结构很像,都是采用 embedding 向量的形式,得到 word 的隐向量表达。
- 都采用很多相似的优化方法,比如使用 Hierarchical softmax 优化训练和预测中的打分速度。
不同处:
- 模型的输出层: word2vec 的输出层,对应的是每一个term,计算某term的概率最大;而fasttext的输出层对应的是分类的label。不过不管输出层对应的是什么内容,起对应的vector都不会被保留和使用。
- 模型的输入层: word2vec 的输出层,是 context window 内的term;而fasttext 对应的整个sentence的内容,包括term,也包括 n-gram的内容。
两者本质的不同,体现在 h-softmax的使用:
Word2vec的目的是得到词向量,该词向量最终是在输入层得到,输出层对应的 h-softmax 也会生成一系列的向量,但最终都被抛弃,不会使用。fastText则充分利用了 h-softmax 的分类功能,遍历分类树的所有叶节点,找到概率最大的label(一个或者N个)。fastText适合类别特别多的分类问题,如果类别比较少,容易过拟合。