词向量要点:
一. Efficient Estimation of Word Representations in Vector Space
- vector(”King”) - vector(”Man”) + vector(”Woman”) is close to vec(“Queen”)
- 构建词向量的早期方法有LSA、LDA;
- NNLM计算过于复杂,因为有隐藏层和投影层;因此本文将推出没有隐藏层的模型(可能不像神经网络那么精确,但更高效);RNNLM没有投影层
- CBOW的权重矩阵(输入层和投影层之间)对于每个词是共享的,各个词投影到相同的位置(进行叠加)
- X = vector(”biggest”) - vector(”big”)+ vector(”small”);France is to Paris as Germany is to Berlin
- 可用于machine translation, information retrieval and question answering,sentiment analysis and paraphrase detection 等nlp任务;
- cbow和skipgram分别适用于什么场景?
Skip-gram在semantic方面更好,cbow在syntactic方面更好
二. Distributed Representations of Words and Phrases and their Compositionality
-
提出Noise Contrastive Estimation (NCE)和negative sampling(NEG),比hierarchical softmax(HS)更简单;其中NEG是对NCE的简化,二者最大区别 NCE needs both samples and the numerical probabilities of the noise distribution, while Negative sampling uses only samples.
-
提高向量质量和训练速度;( subsampling of frequent words during training)
-
支持短语表示;(treat the phrases as individual tokens during the training)、vec(“Russia”) + vec(“river”) is close to vec(“Volga River”)、vec(“Germany”) + vec(“capital”) is close to vec(“Berlin”)
-
Skip-gram需要最大化平均似然概率,其中的p(Wt+j|Wt) 需要用(full)softmax计算,但计算量太大,因此采用Hierarchical Softmax(从需要评估W个output nodes到只需要log2W个); binary tree representation、random walk、Huffman tree ;
-
subsampling:频率越高的词被丢弃(不被采样)的概率也越大,因为a、the这些词没有太大信息价值;可以提高训练速度,同时训练出的词向量也更准确;
-
类比推理任务中,NEG比HS准确率更好;甚至比NCE略好;
-
非线性的RNN比线性的Skip-gram在类比推理任务效果更好(当训练集更大);
-
以上这些对CBOW同样适用;因为模型简单,计算高效,适用于更大数据集,因此效果也更好;不同具体问题有不同最优超参数;
词向量有没有现成的、成熟的指标评价质量好坏?
The quality of these representations is measured in a word similarity task
To measure quality of the word vectors, we define a comprehensive test set that contains 5 types of semantic questions, and 9 types of syntactic questions.
(Semantic-Syntactic Word Relationship test set)
三. Distributed Representations of Sentences and Documents
- 目的和重点是训练Paragraph Vector(特征提取器);机器学习需要固定长度的特征向量,和词袋比,具有以下优点:有词序、有词义;
- 文本可以是各种长度,ranging from sentences to document;
- 对于text representations、sentiment analysis task以及text classication task很有用;
- Distributed Memory Model of Paragraph Vectors (PV-DM) 和Distributed Bag of Words version of Paragraph Vector(PV-DBOW),前者与cbow对应、后者与Skip-gram对应;
- PV-DM是根据 paragraph预测next word;paragraph vector和word vectors are averaged or concatenated;通常Using concatenation in PV-DM is often better than sum.
- After being trained, the paragraph vectors can be used as features for the paragraph ;
- 首先训练得到模型的D、W、U、b等参数(已知段落),然后前向计算得到段落特征(未知段落);推断阶段,输入的段落不能有新词,因为W是固定的
- Paragraph Vector同样是从unlabeled data训练得到(与word2vec一样是无监督);
- PV-DM已经很好,但PV-DM和PV-DBOW结合使用更好,通常将两种向量结合作为最终的段落向量
- 使用Stanford Sentiment Treebank Dataset(是情感分析的benchmark,https://nlp.stanford.edu/sentiment/ );使用逻辑回归;
- 使用IMDB dataset训练多个句子(例如段落、文档),也是来自stanford;
- 信息抽取(Information Retrieval),从搜索引擎根据关键字查询得到页面( how a web page matches the query),计算Paragraph Vector的距离(距离越接近的越有可能属于同一个query);
- 重点是2.2节和2.3节
- 和word2vec一样,PV-DM也是在预测下一个词的同时,来训练得到矩阵或向量的,只不过将段落id和段落矩阵‘拉下水’,充当上下文信息(见图2),这样D和W就能同时训练得到
- PV-DBOW不考虑词序,只把段落id和矩阵D作为输入(预测的是small window的词),不涉及词向量矩阵(注意,虽然模型简单了,但不容易理解)
word2vec+RNN只能训练单个句子的情感类别,因为不清楚如何结合多个句子之间的表示;而doc2vec可以为任意长的段落生成向量表示;
如果用IMDB dataset的话,只能用doc2vec了?
doc2vec比word2vec情感分析效果更好!
gensim的doc2vec
doc2vec和word2vec结合使用有2种方式:词向量相加和拼接
###########词向量深入思考与实战################
word2vec的编译、训练与使用
- 下载源码source-archive.zip,解压得到word2vec/trunk目录(源码地址https://code.google.com/archive/p/word2vec/)
- 利用cygwin进入trunk,执行./demo-word.sh(如果wget没安装,可手动下载text8.zip,并将后缀改为gz,将demo-word.sh中wget注释),如有权限问题,执行chmod 777 *
- 编译、训练结束会得到5个exe(分别对应5个c文件),以及vectors.bin(可研究下makefile文件);Vocab size: 71291 Words in train file: 16718843
- 会提示输入单词或句子,得到距离最近的单词(Cosine distance);如输入china得到taiwan等,nba得到basketball等,java得到servlet等;
- 执行./word-analogy vectors.bin进行单词的类比推理,会提示输入3个单词,输入 france paris china,得到一些单词,peking排第一,hangzhou第二,beijing第三。。。
注意:默认使用cbow和NEGATIVE SAMPLING训练
词向量和语言模型的关系:
-
到目前为止我了解到的所有训练方法都是在训练语言模型的同时,顺便得到词向量的(http://licstar.net/archives/328#s24);
《Word2vec使用说明》也是说‘词向量有了,语言模型也有了’;
但Efficient Estimation of Word Representations in Vector Space(论文一)又说NNLM语言模型训练可分两步:首先训练词向量,再N-gram NNLM is trained on top of these distributed representations of words;
所以两种方法都存在!
论文一中又拿cbow、skip-gram和NNLM、RNNLM进行比较(比较训练得到的词向量质量,语义语法性能),是不是说明cbow、skip-gram其实也是语言模型呢(New Log-linear Models)?个人认为最好不要这么理解!它是和NNLM、RNNLM顺便得到的词向量进行比较;
论文一强调该论文目的是以上的第一步,即训练词向量,而不管后面训练NNLM,因此不能认为cbow、skip-gram是语言模型;
-
语言模型其实就是看一句话是不是正常人说出来的。这玩意很有用,比如机器翻译、语音识别得到若干候选之后,可以利用语言模型挑一个尽量靠谱的结果。在 NLP 的其它任务里也都能用到。
注意:
1)NNLM、RNNLM都属于神经网络语言模型,此外还有C&W的SENNA、M&H的HLBL、Huang的语义强化等;
2)统计语言模型除了n-gram,还有上下文无关模型、n-pos模型、基于决策树的语言模型、最大熵模型、自适应语言模型等;
3)seq2seq应该不是语言模型
4)cbow、skip-gram是New Log-linear Models,但不是语言模型!
5)Log-Bilinear模型、层次化Log-Bilinear模型是基于Log-linear一步一步改进的;(按道理应该只需要研究NNLM,但cbow、skip-gram不属于NNLM,反而和那些古老的模型有点关联,所以不得不再去研究历史模型)
C&W的SENNA对应的论文A Unified Architecture for Natural Language Processing: Deep Neural Networks with Multitask Learning、以及Natural Language Processing (Almost) from Scratch
(主要目的不是生成词向量,也不是训练语言模型,而是用词向量完成 NLP 里面的各种任务;训练过程比较特别,不是计算概率,而是对窗口打分)
M&H的HLBL对应的论文Three New Graphical Models for Statistical Language Modelling以及A scalable hierarchical distributed language model
RNNLM对应的论文Recurrent neural network based language model
Huang的语义强化基于C&W改进,对应论文Improving Word Representations via Global Context and Multiple Word Prototypes
对Bengio 03的NNLM理解:
- 模型可看成4层,输入层为词向量的one hot表示,输入层和第一个隐藏层的权重为词向量矩阵,这样就能用BP更新权重的值;
- 如果将模型看成3层,那么词向量就是输入层,但这样理解起来和常规的神经网络有出入,因为输入层通常不能被改变;
- 输出层的softmax表示每个词的概率,即当前面n个词是这些词,紧接着的下个词的概率分布;
- 由于softmax计算开销较高,因此有了层次softmax;
- 每次训练输入n个词的独热向量,并根据输出端下一个词(已确定),来更新权重,最终得到语言模型的各层参数(其中第一层参数就是词向量矩阵);
因此可以说词向量是训练语言模型得到的副产物;训练好模型后,输入一句话的前几个词,就能计算出下一个词(最有可能);
word2vec+rnn和embedding+rnn:前者先训练得到词向量,再用它训练别的;后者同时进行 --------有这种说法?
keras的model.add(Embedding(vocabulary_size, embedding_size, input_length=max_words))就属于后者?
《Word2vec的工作原理及应用探究》
distributed representation 中的 distributed 一词体现了词向量这样一个特点:将词语的不同句法和语义特征分布到它的每一个维度去表示
多义词怎么处理?每个词学习出多个词向量,能更好地处理多义词?------参见Huang的语义强化
语料对词向量的影响比模型的影响要重要得多得多得多(重要的事说三遍)
语料越大越好,但语料的领域更重要。领域选好了,可能只要 1/10 甚至 1/100 的语料,就能达到一个大规模泛领域语料的效果
对CBOW、Skip-gram 的理解:
- Skip-gram 更慢一些,但是对低频词效果更好;对应的 CBOW 则速度更快一些
- 层次softmax对低频词效果更好;对应的 negative sampling 对 高频词效果更好
- 窗口大小:Skip-gram 一般 10 左右,CBOW 一般 5 左右
- 层次softmax和NEG都和词频有关,前者根据词频构造huffman树,后者根据词频决定如何采样,即频率越高的词被采样的概率也越大(除了高频subsampling),见论文二
- 模型输入和NNLM一样,也是onehot,然后查表,只不过论文中没有说明,输出也是onehot,所以有两个词向量矩阵
- 如何把HS、NEG在论文原图中CBOW、Skip-gram 标出???貌似HS可以画,但NEG画不了(word2vec数学原理详解中也没给出);
NEG使用逻辑回归进行分类!和Huffman树相比,只有一个逻辑回归,而后者有很多个!
- W和W’都是词向量,也就是一个词有两个词向量,哪个作为最终的,有两种策略,要么加起来,要么拼接起来,CS224n采用拼接,他们管W中的向量叫input vector,W’中的向量叫output vector;
参见http://www.hankcs.com/nlp/word-vector-representations-word2vec.html
- NEG中对词频特别高的如a、an、the进行了亚采样subsampling,但对其他词仍保持原词频分布进行采样(词频的power次方),即词频高的被采样概率也高,其中t是阈值threshold
总体没有反转,只是没那么陡;NEG就是Categorical Distribution Sampling+subsampling;参考https://en.wikipedia.org/wiki/Categorical_distribution
- word2vec相对传统词袋、tf idf算是多少考虑了词序,但相对以往经典模型(NNLM、LBL、C&W),则不算考虑了词序(因为后一个词和后后一个词没有区分)
- word2vec是逻辑回归,还是神经网络?有些人认为,它没有隐藏层,所以是log 线性模型,而不是神经网络,但根据one hot映射W得到词向量这部分是神经网络,
而且也有bp更新权重的过程;总体仍然是神经网络?
(当然,Huffman binary tree每个非叶子节点是一个二分类的逻辑回归!非叶子节点相当于一个神经元或感知机;叶子节点代表语料库中的一个词语)
- 层次softmax和NEG都是将多分类转化为二分类!(左右子树;正负样本);二分类都有正负例,而神经网络多分类因为类别太多,不能叫正负例;
- word2vec整体上是无监督;局部或细节上是监督的(即多分类的神经网络和softmax,二分类的层次softmax和NEG);其中NEG可看成是自己构造正负样本,而常规的机器学习都是直接下载已标记的,如spam/ham
- 层次softmax和NEG可同时使用?看代码是可以,比如hs=1,negative>0,但效果如何不清楚,word2vec数学原理详解也提到了
- huffman树可以用任意二叉树代替,只不过效率没它高;huffman树的节点编码正好和正负例对应,如编码1对应正例,0对应负例,或相反;
所有叶子节点的概率加起来是1;每个节点的概率等于路径上概率的连乘(每个概率由逻辑回归的sigmoid确定);
- word2vec只需对语料遍历一遍;另外如何实现当语料动态增加时的训练,即增量训练,目前不清楚
看https://www.jianshu.com/p/1cac5777cc41
http://www.hankcs.com/nlp/word2vec.html
http://www.hankcs.com/nlp/word-vector-representations-word2vec.html
http://www.360doc.com/content/17/0814/16/17572791_679142209.shtml
tf的word2vec训练与使用:(官网https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/word2vec/word2vec_basic.py)
- 直接运行python word2vec_basic.py,会从网上下载text8.zip并验证下载,然后解压,并转换成一个word的list(总长度为1700万左右),
制作一个词表,将不常见的词变成一个UNK标识符,词表的大小为5万,批量读取数据给skip-gram模型,默认skip_window=1, num_skips=2,
即从连续的3个词中生成2个样本;建立模型,词嵌入采用128维,会对常见的16个词进行近义词验证(如can、as、first等),使用nce
噪声词数量为64,构建输入层、embedding层(词嵌入矩阵)、nce loss、优化器,训练100001步,每隔2000步计算一次平均loss,每1万步
进行一次近义词验证(对每个常见词,打印最相邻的8个词),最终的词向量存在于final_embeddings,最后可视化,利用sklean的TSNE技术
对词向量进行降维(从128维变为2维,实际使用pca),将500个词的位置坐标保存为tsne.png
- 官网代码和作者给的略有不同,主要是将模型保存为ckpt,以及将词典保存为metadata.tsv
- 和word2vec的原版C代码相比,tf的实现更简单,主要是调用了框架的多个API,而不是都自己实现,比如tf.nn.nce_loss、tf.train.GradientDescentOptimizer、minimize(loss)等
https://github.com/tensorflow/models/blob/master/tutorials/embedding/word2vec.py是更专业、重量级的tf词向量实现
几点区别:
- 不用tf.nn.nce_loss,而用tf.nn.fixed_unigram_candidate_sampler和tf.nn.sigmoid_cross_entropy_with_logits重新定义实现了nce_loss方法
- 模块化、分解为多个函数,更清晰、更详细
- 定义tf.app和main函数,用户可以通过命令指定一些参数,能够进行交互
- 使用word2vec.skipgram_word2vec,首先编译得到word2vec_ops.so(so可看成python调用C++的一种方式)
- 使用_train_thread_body多线程
https://github.com/tensorflow/models/blob/master/tutorials/embedding/README.md如何编译和使用word2vec功能
注:按照说明操作,编译不通过,可能是tf版本问题,应该用tf1.9或1.10?
D:\Anaconda3\lib\site-packages\tensorflow\include/tensorflow/core/lib/random/random_distributions.h:614:27: 错误:‘M_PI’在此作用域中尚未声明
D:\Anaconda3\lib\site-packages\tensorflow\include/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h:53:20: 错误:‘::random’未被声明
https://www.tensorflow.org/extend/adding_an_op#building_the_op_library解析如何自定义op(operation),以及使用、注册和验证
打赏一下作者: