首先我们要先从机器怎么了解人类的语言说起,对人来说一个单词就是一个单词,但是对计算机来说却不是这样,因为机器是只能理解0和1指令的,那么计算机是如何处理单词或者文本的呢?最简单最直观的做法就是把单词(word)按照某种规则表达成一个向量(vector),y这就是Word Representation。
one-hot encoding表达向量?
比如:假设我们有这样的两个文本:
D1: I like green
D2: I like red
那么针对这两个文本所组成的语料库而言,我们会得到如下所示的字典:[green, I, like, red],那么单词”I”的one-hot encoding就是[0100],单词”like”则是[0010]。
我们训练的语料库通常来说是很庞大的,利用one-hot encoding 来表达单词,可能造成的问题就是维度灾难,这里我们引入另外一个表达单词的方法或者说概念Word Embedding
什么是Word Embedding?
要理解这个概念,先理解什么是Emdedding? 通俗的翻译可以认为是单词嵌入,就是把X所属空间的单词映射为到Y空间的多维向量,那么该多维向量相当于嵌入到Y所属空间中,就是给one-hot encoding降低维度。避免维度灾难。
几种ccz的方式
目前主要分为两类:
- Frequency based Embedding
- Prediction based Embedding
Frequency based Embedding就是基于词频统计的映射方式,主要有以下三种:
- Count Vector
这种就是最简单,最基本的词频统计算法:比如我们有N个文本(document),我们统计出所有文本中不同单词的数量,结果组成一个矩阵。那么每一列就是一个向量,表示这个单词在不同的文档中出现的次数 - TF-IDF Vector
TF-IDF方法基于前者的算法进行了一些改进,TF-IDF把词袋表达的向量转换到另一个向量空间,这个向量空间中,词频是根据语料中每个词的相对稀有程度(relative rarity)进行加权处理的。
from gensim import models
tfidf = models.TfidfModel(bow_corpus)
string = "system minors"
string_bow = dictionary.doc2bow(string.lower().split())
string_tfidf = tfidf[string_bow]
print(string_bow)
print(string_tfidf)
# 输出
[(5, 1), (11, 1)]
[(5, 0.5898341626740045), (11, 0.8075244024440723)]
TF-IDF返回了一组元组。元组中第一个元素表示id,第二个表示tf-idf权重。注意到,“system”在原语料中出现4次,“minors”出现2次,所以第一个权重比第二个小。
- Co-Occurrence Vector
比如我们有如下的语料库:
He is not lazy. He is intelligent. He is smart.
我们假设Context Window(上下文单词数)=2,那么我们就可以得到如下的co-occurrence matrix:
Word2vec
上面介绍完,我们进入文章的重点word2vec, 基于神经网络的预测模型-word2vec。它是只有一个隐含层的神经网络,且激活函数(active function)是线性的,最后一层output采用softmax来计算概率。它包含两种模型:
- COBW(Continuous Bag of words)根据上下文来预测一个单词
- Skip-gram 根据一个单词来预测上下文
在介绍这两种模型之前,我先po一个我在知乎看到的一个关于word2vec生成的向量word Embedding向量在哪里
大致流程是首先有了文本语料库,你需要对语料库进行预处理,这个处理流程与你的语料库种类以及个人目的有关,比如,如果是英文语料库你可能需要大小写转换检查拼写错误等操作,得到你想要的processed corpus之后,将他们的one-hot向量作为word2vec的输入,通过word2vec训练低维词向量(word embedding)。
目前有两种训练模型(CBOW和Skip-gram),两种加速算法(Negative Sample与Hierarchical Softmax)
word2vec如何由corpus的one-hot向量变成低维词向量(word embedding)
下面将描述word2vec如何将corpus的one-hot向量(模型的输入)转换成低维词向量(模型的中间产物,更具体来说是输入权重矩阵)
- 输入层:上下文单词的onehot. {假设单词向量空间dim为V,上下文单词个数为C}
- 所有onehot分别乘以共享的输入权重矩阵W. {V*N矩阵,N为自己设定的数,初始化权重矩阵W}
- 所得的向量 {因为是onehot所以为向量} 相加求平均作为隐层向量, size为1*N.
- 乘以输出权重矩阵W’ {N*V}
- 得到向量 {1*V} 激活函数处理得到V-dim概率分布 ,概率最大的index所指示的单词为预测出的中间词(target word)
- 与true label的onehot做比较,误差越小越好
所以,需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W’。训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量(word embedding),这个矩阵(所有单词的word embedding)也叫做look up table(其实聪明的你已经看出来了,其实这个look up table就是矩阵W自身),也就是说,任何一个单词的onehot乘以这个矩阵都将得到自己的词向量。有了look up table就可以免去训练过程直接查表得到单词的词向量了。
作者:crystalajj
链接:https://www.zhihu.com/question/44832436/answer/266068967
理解COBW
图解Word2vec:
https://jalammar.github.io/illustrated-word2vec/
Word2vec初探:
http://www.fanyeong.com/2017/10/10/word2vec/
知乎:word2vec是如何得到词向量的?
https://www.zhihu.com/question/44832436
gensim - Word2vec embeddings
https://radimrehurek.com/gensim/models/word2vec.html
An Intuitive Understanding of Word Embeddings: From Count Vectors to Word2Vec
https://www.analyticsvidhya.com/blog/2017/06/word-embeddings-count-word2veec/