文本处理是NLP领域的一个重要分支,其细分领域又包括文本聚类、分类、机器翻译、人机交互等等,而这一切的前提都是将文本表示成计算机可以理解和易于处理的数据。
经过成千上万年的进化,人类的语言本身变得十分抽象和复杂,要搞懂一段文字,那么要理解词本身的意义、语义关系、上下文关系(苹果好吃/苹果公司),如何将文字用计算机语言表达出来,并尽量减少编码过程中造成的信息损失,一直是一个业界难题和很重要的研究方向。本文总结一下目前热门的Word Embedding表示方法的历史和原理,以供参考。
1. Word Embedding的基本概念
1.1 什么是Word Embedding?
现有的机器学习方法往往无法直接处理文本数据,因此需要找到合适的方法,将文本数据转换为数值型数据,由此引出了Word Embedding的概念。如果将word看作文本的最小单元,可以将Word Embedding理解为一种映射,其过程是:将文本空间中的某个word,通过一定的方法,映射或者说嵌入(embedding)到另一个数值向量空间(之所以称之为embedding,是因为这种表示方法往往伴随着一种降维的意思,详见下文的讨论)。
1.2 Word Embedding的输入
Word Embedding的输入是原始文本中的一组不重叠的词汇,假设有句子:apple on a apple tree。那么为了便于处理,我们可以将这些词汇放置到一个dictionary里,例如:[“apple”, “on”, “a”, “tree”],这个dictionary就可以看作是Word Embedding的一个输入。
1.3 Word Embedding的输出
Word Embedding的输出就是每个word的向量表示。对于上文中的原始输入,假设使用最简单的one hot编码方式,那么每个word都对应了一种数值表示。例如,apple对应的vector就是**[1, 0, 0, 0],a对应的vector就是[0, 0, 1, 0],各种机器学习应用可以基于这种word的数值表示来构建各自的模型。当然,这是一种最简单的映射方法,但却足以阐述Word Embedding的意义。下文将介绍常见的Word Embedding**的方法和优缺点。
2 Word Embedding的类型
Word Embedding也是有流派的,主流有以下两种:
- 基于频率的Word Embedding(Frequency based embedding)
- 基于预测的Word Embedding(Prediction based embedding)
下面分别介绍之。
2.1 基于频率的Word Embedding
基于频率的Word Embedding又可细分为如下几种:
- Count Vector
- TF-IDF Vector
- Co-Occurence Vector
其本质都是基于one-hot表示法的,以频率为主旨的加权方法改进,下面逐一介绍。
2.1.1 Count Vector
假设有一个语料库C,其中有D个文档:{d1, d2, …, dD},C中一共有N个word。这N个word构成了原始输入的dictionary,我们据此可以生成一个矩阵M,其规模是D X N。
假设语料库内容如下:
D1: He is a boy.
D2: She is a girl, good girl.
那么可以构建如下2 × 7维的矩阵。
该矩阵便是一个counter vector matrix。每个文档用词向量的组合来表示,每个词的权重用其出现的次数来表示。
当然,如果语料库十分庞大,那么dictionary的规模亦会十分庞大,因此上述矩阵必然是稀疏的,会给后续运算带来很大的麻烦。通常的做法是选取出现次数最频繁的那些词来构建dictionary(例如,top 10,000个词),这样会有效缩减上述矩阵的规模。
2.1.2 TF-IDF
上一小节中,在构建词的权重时,只考虑了词频TF(Term Frequncy),也就是词在单个文档中出现的频率。直觉上来看,TF越大,说明词在本文档中的重要性越高,对应的权重也就越高。这个思路大体上来说是对的,例如,对于一个主题是Cat的文档,显然Cat这个词汇在本文档中的出现频率会相对高。
但如果我们把视野扩展到整个语料库,会发现,像is,a等通用词汇,几乎在每个文档里出现的频率都很高。由此,我们可以得到这样的结论:对于一个word,如果在特定文档里出现的频率高,而在整个语料库里出现的频率低,那么这个word对于该文档的重要性就比较高。因此我们可以引入逆文档频率IDF(Inverse Document Frequency)的概念:IDF=log(N/n)。其中,N代表语料库中文档的总数,n代表某个word在几个文档中出现过;当一个word出现地越频繁,那么IDF就越小。显然,IDF用于惩罚那些常用词汇,而TF用于奖励那些在特定文档中出现频繁的词汇。二者的乘积TF X IDF用来表示词汇的权重,显然合理性大大增强。
举例:
语料库中共有2个文档,其中有一个文档名为d。
共有1个文档出现了cat这个词汇;且在特定文档d中,共有8个词汇,cat出现了4次。
共有2个文档出现了is这个词汇;且在特定文档d中,共有8个词汇,is出现了4次。
那么根据定义,可以得到:
TF("cat", d)=4/8=0.5
TF("is", d)=4/8=0.5
IDF("cat", d) = log2(2/1)=0.301
IDF("is", d) = log2(2/2)=0
TFIDF("cat", d)=TF("cat", d)*IDF("cat", d)=0.5*0.301=0.15
TFIDF("is", d)=TF("is", d)*IDF("is", d)=0.5*0=0
可见,TFIDF算法极大地惩罚了is这个词汇,从而增加了权重设置的合理性。
2.1.3 Co-Occurence Vector
本文最开头有所提及,自然语言一大特色是语义和上下文。有如下著名的研究结果:相似的单词趋向于有相似的上下文(context)。举例:
- 那个人是个男孩。
- 那个人是个女孩。
男孩和女孩从概念上来说相似,他们也具有相似的上下文。
根据如上思想,我们可以构建一套算法,来实现基于上下文的特征构建。
这里需要引入两个概念:
- Context Window:
上面我们提到了context,但context的长度需要有一个界定,也就是说,对于一个给定的word,需要有一个Context Window大小的概念。
如上图所示,如果指定Context Window大小为2,范围为前后两个word,那么对于such这个词,它的Context Window如上图所示。
- Co-Occurence(共现):
有了Context Window的概念,Co-Occurence就好理解了。对于such这个单词来说,在其上下文窗口内,它分别与**[she, is, a, beautiful]这四个单词各出现了一次共现。如果我们在语料库中所有such出现的地方,计算其共现的单词,并按次数累加,那么我们就可以利用其上下文范围内的单词来表示such这个词,这就是Co-Occurence Vector**的计算方法。.
假设有如下语料库:
He is not lazy. He is intelligent. He is smart.
如果Context Window大小为2,那么可以得到如下的共现矩阵:
我们可以看看He和is的共现次数4是如何计算出来的:
显然地,直接使用共现矩阵,也会存在维数过大的问题,通常可以采取矩阵分解等手段来进行降维优化,在此不做深入讨论。
共现矩阵最大的优势是这种表示方法保留了语义信息,例如,通过这种表示,就可以知道,man和woman是更加接近的,而man和apple是相对远的。相比前述的两种方法,更具有智能的味道。
2.2 基于预测的Word Embedding
从上文2.1.3节中已经得知,词的表示中如果蕴含了上下文信息,那么将会更加接近自然语言的本质;并且,由于相似的词有相似的表示方法,甚至可以进行一些运算,例如:人类-男人=女人。但是,上述讨论中,有一个很大的缺陷,那就是词的向量表示维度过大,一个词要用大量其余的词来表示,为后续运算带来了很大的麻烦。因此,我们需要找到一种更好的表示方法,这种方法需要满足如下两点要求:
- 携带上下文信息
- 词的表示是稠密的
事实证明,通过神经网络来进行建模,可以满足这两点要求。主流的建模方法又有两种:CBOW和Skip – Gram,下面分别介绍其思想。
2.2.1 CBOW(continues bag of words)
CBOW的全称是continuous bag of words。其本质是通过context来预测word。
如上图所示,首先语料库内的每个word都可以用one-hot的方式编码。假设选取Context Window为2,那么模型中的一对input和target就是:
- input:He和is的one-hot编码
- target:a的one-hot编码
接着通过一个浅层神经网络来拟合该结果,如下图所示:
过程简单介绍如下(实际算法会用到哈夫曼编码等降维技巧,这里仅以理解为目的简介基本原理):
- 输入为C个V维的vector。其中C为上下文窗口的大小,V为原始编码空间的规模。例如,示例中的C=2,V=4.两个vector分别为4维的He和is的one-hot编码形式;
- 激活函数相当简单,在输入层和隐藏层之间,每个input vector分别乘以一个VxN维度的矩阵,得到后的向量各个维度做平均,得到隐藏层的权重。隐藏层乘以一个NxV维度的矩阵,得到output layer的权重;
- 隐藏层的维度设置为理想中压缩后的词向量维度。示例中假设我们想把原始的4维的原始one-hot编码维度压缩到2维,那么N=2;
- 输出层是一个softmax层,用于组合输出概率。所谓的损失函数,就是这个output和target之间的的差(output的V维向量和input vector的one-hot编码向量的差),该神经网络的目的就是最小化这个loss;
- 优化结束后,隐藏层的N维向量就可以作为Word-Embedding的结果。
如此一来,便得到了既携带上下文信息,又经过压缩的稠密词向量。
2.2.2 Skip – Gram
Skip-Gram模型可以认为是CBOW的一个网络翻转。CBOW建模的出发点是利用context预测word。Skip-Gram模型的目的则是通过word来预测context。其目的都是为了通过构建一个神经网络模型来获取压缩后的词向量。这里不再详述。
# 3 Word Embedding的应用
现今流行的Word Embedding算法携带了语义信息且维度经过压缩便于运算,因此有了很多用武之地,例如:
- 计算相似度,比如man和woman的相似度比man和apple的相似度高
- 在一组单词中找出与众不同的一个,例如在如下词汇列表中:[dog, cat, chicken, boy],利用词向量可以识别出boy和其他三个词不是一类。
- 直接进行词的运算,例如经典的:woman+king-man =queen
- 由于携带了语义信息,还可以计算一段文字出现的可能性,也就是说,这段文字是否通顺。
本质上来说,经过Word Embedding之后,各个word就组合成了一个相对低维空间上的一组向量,这些向量之间的远近关系则由他们之间的语义关系决定。
4 总结
词的表示一直是NLP很活跃的一个领域,本文主要是提供了一个脉络,简介了一下Word Embedding的原理。感兴趣的读者可以就每种表示方法进行深入了解,基于各自的优缺点在实践中应用。