本文介绍常见的文本表示模型,One-hot、词袋模型(BOW)、TF-IDF、N-Gram和Word2Vechtml
1、离散表示
一、One-hot编码
one-hot编码是经常使用的方法,咱们能够用one-hot编码的方式将句子向量化,大体步骤为:git
- 用构造文本分词后的字典
- 对词语进行One-hot编码
John likes to watch movies. Mary likes toogithub
John also likes to watch football games.网络
上面的两句话分词后能够构造一个字典,字典内容以下,字典的键是词语,值是ID分布式
{"John": 1, "likes": 2, "to": 3, "watch": 4, "movies": 5, "also": 6, "football": 7, "games": 8, "Mary": 9, "too": 10}
咱们能够根据ID值对每一个词语进行向量化,用0和1表明这个词是否出现函数
# John [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] # too [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
one-hot 词向量构造起来简单,但一般不是一个好的选择,它有明显的缺点:优化
- 维数太高。咱们这里只有短短的2句话,每一个词语已是一个10维的向量了,随着语料的增长,维数会愈来愈大,致使维数灾难
- 矩阵稀疏。利用One-hot编码的另外一个问题就是矩阵稀疏,从上面也能够看到,每个词向量只有1维是有数值的,其余维上的数值都为0
- 不能保留语义。用这种方式获得的结果不能保留词语在句子中的位置信息, “我爱你” 和 “你爱我” 的向量化结果并无什么不一样。
二、词袋(BOW)模型
词袋模型(Bag-of-words model,BOW),BOW模型假定对于一个文档,忽略它的单词顺序和语法、句法等要素,将其仅仅看做是若干个词汇的集合,文档中每一个单词的出现都是独立的,不依赖于其它单词是否出现。ui
John likes to watch movies. Mary likes too编码
John also likes to watch football games.spa
使用以前一样的例子,跟前面同样,将上面的两句话中看做一个文档集,列出文档中出现的全部单词(忽略大小写与标点符号),构造一个字典
{"John": 1, "likes": 2, "to": 3, "watch": 4, "movies": 5, "also": 6, "football": 7, "games": 8, "Mary": 9, "too": 10}
再用再将句子向量化,维数和字典大小一致,第 $i$ 维上的 数值 表明 ID 为 $i$ 的词语在这个句子里出现的频次
# 第一个文本 [1, 2, 1, 1, 1, 0, 0, 0, 1, 1] # 第二个文本 [1, 1, 1, 1, 0, 1, 1, 1, 0, 0]
以第一个文本的向量化结果 [1, 2, 1, 1, 1, 0, 0, 0, 1, 1] 为例,2在第二维上,ID为2的词语是likes,在第一个文本中出现了2次,因此第二维上的数值是2
这种方式不像one-hot编码那样致使维数很是大,但也有本身的缺点
- 不能保留语义:不能保留词语在句子中的位置信息,“你爱我” 和 “我爱你” 在这种方式下的向量化结果依然没有区别。“我喜欢北京” 和 “我不喜欢北京” 这两个文本语义相反,利用这个模型获得的结果却能认为它们是类似的文本。
- 维数高和稀疏性:当语料增长时,那么维数也会不可避免的增大,一个文本里不出现的词语就会增多,致使矩阵稀疏
三、TF-IDF
TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的经常使用加权技术。TF意思是词频(Term Frequency),IDF意思是逆文本频率指数(Inverse Document Frequency)。
字词的重要性随着它在文件中出现的次数成正比增长,但同时会随着它在语料库中出现的频率成反比降低。一个词语在一篇文章中出现次数越多, 同时在全部文档中出现次数越少, 越可以表明该文章。
TF-IDF公式以下:
$TF(t,d)$表示 词语t 在 文档d 中出现的频率,$IDF(t)$是逆文本频率指数,它能够衡量 单词t 用于区分这篇文档和其余文档的重要性。IDF的公式以下,分母加1是为了不分母为0
好比在10篇文档中,1篇是猴子的,9篇是关于人的,关于人的文章中不出现 “尾巴” 这个词语,10篇文章中都出现 “嘴巴” 这个词语,那么 “尾巴” 这个词在这些文章中就颇有区分度。从公式的角度也很容易看出。以10为底数的话,$IDF(尾巴)$ = 0.70, $IDF(嘴巴)$ = -0.04,说明 “尾巴” 重要性更高点,它有区分性。
前面说的缺点依然存在,它依然不能保留词语在句子中的位置关系。
四、N-Gram
N-Gram语言模型的思想就是,给定一串字母,下一个最大可能出现的词语是什么?好比 “今天你”,后面跟 “吃饭” 可能性大,但跟着 “后天” 的可能性就很小。
N=1时称为unigram,N=2称为bigram,N=3称为trigram,假设下一个词的出现依赖它前面的一个词,即 bigram,假设下一个词的出现依赖它前面的两个词,即 trigram,以此类推。
如下面的文本为例
你帮我
我帮你
它的bigram依次为:
你,你帮,帮,帮我,我
我,我帮,帮,帮你,你
一样地,咱们能够构造一个字典
{"你": 1, "你帮"; 2, "帮": 3,"帮我": 4, "我": 5, "我帮": 6, "帮你": 7}
向量化结果能够表示为
# 第一个文本 [1, 1, 1, 1, 1, 0, 0] # 第二个文本 [1, 0, 1, 0, 1, 1, 1]
N-Gram基于一个假设:第n个词出现与前n-1个词相关,而与其余任何词不相关(这也是隐马尔可夫当中的假设)。整个句子出现的几率就等于各个词出现的几率乘积,公式以下:
上面的表达式并很差计算,引入马尔科夫假设,那么能够将式子写成
马尔可夫链(Markov chain)为状态空间中通过从一个状态到另外一个状态的转换的随机过程。该过程要求具有“无记忆”的性质:下一状态的几率分布只能由当前状态决定,而与以前的状态无关
特别地,对unigram,有
对bigram,有
对trigram,有
N-Gram考虑了词的顺序,信息量更充分。
但缺点是随着N的增大,词表迅速膨胀,数据出现大量稀疏的问题。
五、总结
因为存在如下的问题,对于通常的NLP问题,是可使用离散表示文本信息来解决问题的,但对于要求精度较高的场景就不适合了。
- 没法衡量词向量之间的关系。
- 词表的维度随着语料库的增加而膨胀。
- n-gram词序列随语料库增加呈指数型膨胀,更加快。
- 离散数据来表示文本会带来数据稀疏问题,致使丢失了信息,与咱们生活中理解的信息是不同的。
2、分布式表示
科学家们为了提升模型的精度,又发明出了分布式的表示文本信息的方法。
用一个词附近的其它词来表示该词,这是现代统计天然语言处理中最有创见的想法之一。当初科学家发明这种方法是基于人的语言表达,认为一个词是由这个词的周边词汇一块儿来构成精确的语义信息。就比如,物以类聚人以群分,若是你想了解一我的,能够经过他周围的人进行了解,由于周围人都有一些共同点才能汇集起来。
一、共现矩阵
共现矩阵顾名思义就是共同出现的意思,词文档的共现矩阵主要用于发现主题(topic),用于主题模型,如LSA。
局域窗中的word-word共现矩阵能够挖掘语法和语义信息,例如:
I like deep learning.
I like NLP.
I enjoy flying.
有以上三句话,设置滑窗(对称窗口)为2,能够获得一个词典:{"I like","like deep","deep learning","like NLP","I enjoy","enjoy flying","I like"}。
咱们能够获得一个共现矩阵(对称矩阵):
中间的每一个格子表示的是行和列组成的词组在词典中共同出现的次数,也就体现了共现的特性。好比例如:“I like”出如今第1,2句话中,一共出现2次,因此=2。 对称的窗口指的是,“like I”也是2次
存在的问题:
- 向量维数随着词典大小线性增加。
- 存储整个词典的空间消耗很是大。
- 一些模型如文本分类模型会面临稀疏性问题。
- 模型会欠稳定,每新增一份语料进来,稳定性就会变化。
二、Word2Vec
谷歌2013年提出的Word2Vec是目前最经常使用的词嵌入模型之一。Word2Vec实际 是一种浅层的神经网络模型,它有两种网络结构,分别是CBOW(Continues Bag of Words)连续词袋和Skip-gram。
2.一、CBOW
CBOW是一个三层神经网络,特色是输入已知上下文,输出对当前单词的预测。 CBOW经过中间词来预测窗口中上下文词出现的几率模型,把中间词当作y,把窗口中的其它词当作x输入,x输入是通过one-hot编码过的,而后经过一个隐层进行求和操做,最后经过激活函数softmax,能够计算出每一个单词的生成几率,接下来的任务就是训练神经网络的权重,使得语料库中全部单词的总体生成几率最大化,而求得的权重矩阵就是文本表示词向量的结果。。
举一个例子,咱们有如下文本
I drink coffee everyday
假设咱们输入为 I, drink, everyday,那么咱们训练的神经网络要使 coffee 的输出几率最大。首先,咱们将原来的文本的单词用One-hot编码表示,以下图所示
初始化输入权重矩阵 $W$ 和输出权重矩阵 $W^{'}$,利用这个权重矩阵W和One-hot编码完的向量相乘,能够获得惟一的向量 $V$,至关于根据One-hot编码中1的位置取出W中的对应的列,除非两列彻底相同,不然获得的向量不会是同样的。
咱们这里有3个输入值,将3个输入值与 $W$ 相乘获得的向量相加作平均,获得隐藏层向量
隐藏层向量再乘以输出权重矩阵 $W^{'}$ ,获得一个输出向量
对输出向量作softmax,获得输出几率
2.二、Skip-Gram
Skip-Gram与CBOW相反,即已知某个词语,预测周围的词语。经过当前词来预测窗口中上下文词出现的几率模型,把当前词当作 $x$,把窗口中其它词当作 $y$,依然是经过一个隐层接一个Softmax激活函数来预测其它词的几率。
如下图举例,咱们选定句子“The quick brown fox jumps over lazy dog”,设定咱们的窗口大小为2(window_size=2),也就是说咱们将输入词先后各两个词和输入词进行组合做为训练样本。下图中,蓝色表明input word,方框内表明位于窗口内的单词。
以第一条为例,The为输入词,可是The开头,前面没有词跟它组合,因此只能和后面两个单词分别组合。
当quick输入时,它前面只有1个单词,因此一共只有3个组合。
从brown开始,前面才会有2个及以上的单词,因此从这里开始有4个组合。
咱们的模型将会从每对单词出现的次数中习得统计结果。例如,咱们的神经网络可能会获得更多相似(“可乐“,”百事“)这样的训练样本对,而对于(”可乐“,”酱油“)这样的组合却看到的不多。所以,当咱们的模型完成训练后,给定一个单词”可乐“做为输入,输出的结果中”百事““要比”酱油“的几率高。
2.三、加速优化方法
有Hierarchical Softmax(层次Softmax)和Negative Sample(负采样)两个加速方法,参考如下连接
- Hierarchical Softmax:http://www.javashuo.com/article/p-enrvxzho-ec.html,https://cloud.tencent.com/developer/article/1387413
- Negative Sample:http://www.javashuo.com/article/p-pnxwarnk-ek.html
参考资料:
https://github.com/mantchs/machine_learning_model/tree/master/Word2Vec
https://www.jianshu.com/p/f8300129b568
https://blog.csdn.net/weixin_43112462/article/details/88669902
https://blog.csdn.net/lxg0807/article/details/78615917
https://www.cnblogs.com/bep-feijin/p/9430164.html
https://blog.csdn.net/yu5064/article/details/79601683
https://www.jianshu.com/p/471d9bfbd72f