在NLP(自然语言处理)领域,文本表示是第一步,也是很重要的一步,通俗来说就是把人类的语言符号转化为机器能够进行计算的数字,因为普通的文本语言机器是看不懂的,必须通过转化来表征对应文本。早期是基于规则的方法进行转化,而现代的方法是基于统计机器学习的方法。
数据决定了机器学习的上限,而算法只是尽可能逼近这个上限,在本文中数据指的就是文本表示,所以,弄懂文本表示的发展历程,对于NLP学习者来说是必不可少的。接下来开始我们的发展历程。文本表示分为离散表示和分布式表示:
(1)根本原因是计算机不方便直接对文本字符串进行处理,因此需要进行数值化或者向量化。
(2)便于机器学习。不仅传统的机器学习算法需要这个过程,深度学习也需要这个过程。
(3)良好的文本表示形式可以极大的提升算法效果。
One-hot简称独热向量编码,也是特征工程中最常用的方法。其步骤如下:
1.构造文本分词后的字典,每个分词是一个比特值,比特值为0或者1。
2.每个分词的文本表示为该分词的比特位为1,其余位为0的矩阵表示。
例如:
John likes to watch movies. Mary likes too
John also likes to watch football games.
以上两句可以构造一个词典,
{“John”: 1, “likes”: 2, “to”: 3, “watch”: 4, “movies”: 5, “also”: 6, “football”: 7, “games”: 8, “Mary”: 9, “too”: 10}
每个词典索引对应着比特位。那么利用One-hot表示为:
John: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
likes: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
to: [0, , 0, 1, 0, 0, 0, 0, 0, 0] …等等,以此类推。
One-hot表示缺点:
随着语料库的增加,数据特征的维度会越来越大,产生一个维度膨胀 稀疏矩阵。
这种表示方法的分词顺序和在句子中的顺序是无关的,不能保留词与词之间的关系信息。
词袋模型(Bag-of-words model),像是句子或是文件这样的文字可以用一个袋子装着这些词的方式表现,这种表现方式不考虑文法以及词的顺序。
文档的向量表示可以直接将各词的词向量表示加和。
例如:
John likes to watch movies. Mary likes too
John also likes to watch football games.
以上两句可以构造一个词典,
{“John”: 1, “likes”: 2, “to”: 3, “watch”: 4, “movies”: 5, “also”: 6, “football”: 7, “games”: 8, “Mary”: 9, “too”: 10}
那么第一句的向量表示为:[1,2,1,1,1,0,0,0,1,1],其中的2表示likes在该句中出现了2次,依次类推。
词袋模型缺点:
词向量化后,词与词之间是有大小关系的,不一定词出现的越多,权重越大。
词与词之间是没有顺序关系的。
TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。
TF意思是词频(Term Frequency),IDF意思是逆文本频率指数(Inverse Document Frequency)。
字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。一个词语在一篇文章中出现次数越多, 同时在所有文档中出现次数越少, 越能够代表该文章。
现在假设我们要统计一篇文档中的前10个关键词,应该怎么下手?首先想到的是统计一下文档中每个词出现的频率(TF),词频越高,这个词就越重要。但是统计完你可能会发现你得到的关键词基本都是“的”、“是”、“为”这样没有实际意义的词(停用词),这个问题怎么解决呢?你可能会想到为每个词都加一个权重,像这种”停用词“就加一个很小的权重(甚至是置为0),这个权重就是IDF。下面再来看看公式:
TF应该很容易理解就是计算词频,IDF衡量词的常见程度。为了计算IDF我们需要事先准备一个语料库用来模拟语言的使用环境,如果一个词越是常见,那么式子中分母就越大,逆文档频率就越小越接近于0。这里的分母+1是为了避免分母为0的情况出现。TF-IDF的计算公式如下:
根据公式很容易看出,TF-IDF的值与该词在文章中出现的频率成正比,与该词在整个语料库中出现的频率成反比,因此可以很好的实现提取文章中关键词的目的。
TF–IDF 优缺点分析
优点:简单快速,结果比较符合实际
缺点:单纯考虑词频,忽略了词与词的位置信息以及词与词之间的相互关系。
n-gram模型为了保持词的顺序,做了一个滑窗的操作,这里的N表示的就是滑窗的大小,例如2-gram模型,也就是把2个词当做一组来处理,然后向后移动一个词的长度,再次组成另一组词,把这些生成一个字典,按照词袋模型的方式进行编码得到结果。该模型考虑了词的顺序。
例如:
John likes to watch movies. Mary likes too
John also likes to watch football games.
以上两句可以构造一个词典,
{"John likes”: 1, "likes to”: 2, "to watch”: 3, "watch movies”: 4, "Mary likes”: 5, "likes too”: 6, "John also”: 7, "also likes”: 8, “watch football”: 9, “football games”: 10}
那么第一句的向量表示为:[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],其中第一个1表示John likes在该句中出现了1次,依次类推。
**缺点:**随着n的大小增加,词表会成指数型膨胀,会越来越大。
为了提高模型的精度,又发明出了分布式的表示文本信息的方法,这种方法是基于人的语言表达,认为一个词是由这个词的周边词汇一起来构成精确的语义信息。就好比,物以类聚人以群分,如果你想了解一个人,可以通过他周围的人进行了解,因为周围人都有一些共同点才能聚集起来。
共现矩阵顾名思义就是共同出现的意思,词文档的共现矩阵主要用于发现主题(topic),用于主题模型,如LSA。
局域窗中的word-word共现矩阵可以挖掘语法和语义信息
例如:
有以上三句话,设置滑窗为2,可以得到一个词典:
{“I like”,“like deep”,“deep learning”,“like NLP”,“I enjoy”,“enjoy flying”,“I like”}。
我们可以得到一个共现矩阵(对称矩阵):
中间的每个格子表示的是行和列组成的词组在词典中共同出现的次数,也就体现了共现的特性。
共现矩阵存在的问题:
NNLM (Neural Network Language model),神经网络语言模型是03年提出来的,通过训练得到中间产物–词向量矩阵,这就是我们要得到的文本表示向量矩阵。
NNLM说的是定义一个前向窗口大小,其实和上面提到的窗口是一个意思。把这个窗口中最后一个词当做y,把之前的词当做输入x,通俗来说就是预测这个窗口中最后一个词出现概率的模型。
以下是NNLM的网络结构图:
input层是一个前向词的输入,是经过one-hot编码的词向量表示形式,具有V*1的矩阵
C矩阵是投影矩阵,也就是稠密词向量表示,在神经网络中是w参数矩阵,该矩阵的大小为D*V,正好与input层进行全连接(相乘)得到D*1的矩阵,采用线性映射将one-hot表 示投影到稠密D维表示。
output层(softmax)自然是前向窗中需要预测的词。
通过BP+SGD得到最优的C投影矩阵,这就是NNLM的中间产物,也是我们所求的文本表示矩阵,通过NNLM将稀疏矩阵投影到稠密向量矩阵中。
谷歌2013年提出的Word2Vec是目前最常用的词嵌入模型之一。Word2Vec实际 是一种浅层的神经网络模型,它有两种网络结构,**分别是CBOW(Continues Bag of Words)连续词袋和Skip-gram。**Word2Vec和上面的NNLM很类似,但比NNLM简单。
CBOW
CBOW获得中间词两边的的上下文,然后用周围的词去预测中间的词,把中间词当做y,把窗口中的其它词当做x输入,x输入是经过one-hot编码过的,然后通过一个隐层进行求和操作,最后通过激活函数softmax,可以计算出每个单词的生成概率,接下来的任务就是训练神经网络的权重,使得语料库中所有单词的整体生成概率最大化,而求得的权重矩阵就是文本表示词向量的结果。
Skip–gram:
Skip-gram是通过当前词来预测窗口中上下文词出现的概率模型,把当前词当做x,把窗口中其它词当做y,依然是通过一个隐层接一个Softmax激活函数来预测其它词的概率。如下图所示:
优化方法:
层次Softmax:至此还没有结束,因为如果单单只是接一个softmax激活函数,计算量还是很大的,有多少词就会有多少维的权重矩阵,所以这里就提出层次Softmax(Hierarchical Softmax),使用Huffman Tree来编码输出层的词典,相当于平铺到各个叶子节点上,瞬间把维度降低到了树的深度,可以看如下图所示。这课Tree把出现频率高的词放到靠近根节点的叶子节点处,每一次只要做二分类计算,计算路径上所有非叶子节点词向量的贡献即可。
负例采样(Negative Sampling):这种优化方式做的事情是,在正确单词以外的负样本中进行采样,最终目的是为了减少负样本的数量,达到减少计算量效果。将词典中的每一个词对应一条线段,所有词组成了[0,1]间的剖分,如下图所示,然后每次随机生成一个[1, M-1]间的整数,看落在哪个词对应的剖分上就选择哪个词,最后会得到一个负样本集合。
Word2Vec存在的问题