word2vec

参考博客:

1
https://blog.csdn.net/yu5064/article/details/79601683 https://blog.csdn.net/fengdu78/article/details/105321441

 1.什么是word2vec

2013年,Google团队发表了word2vec工具。word2vec工具主要包含两个模型:跳字模型(skip-gram)和连续词袋模型(continuous bag of words,简称CBOW),以及两种高效训练的方法:负采样(negative sampling)和层序softmax(hierarchical softmax)。值得一提的是,word2vec词向量可以较好地表达不同词之间的相似和类比关系。

在自然语言处理中,词语是具有原子性的单位,而词语是符号形式的,如果想对其进行计算,我们就要将他们转换为数值形式,或者说——嵌入到一个数学空间里,这种嵌入方式,就叫词嵌入(word embedding),而 Word2vec,就是词嵌入( word embedding) 的一种.

 2、语言模型 Language Model

统计语言模型给出了这一类问题的一个基本解决框架。对于一段文本序列S=w1,w2,…,wT,它的概率可以表示为:

即将序列的联合概率转化为一系列条件概率的乘积。问题变成了如何去预测这些给定previous words下的条件概率p(wt|w_1,w_2,…,w_{t−1})。常见的统计语言模型有N元文法模型(N-gram Model)

基于马尔科夫假设(Markov Assumption):下一个词的出现仅依赖于它前面的一个或几个词。
假设下一个词的出现依赖它前面的一个词,则有:

假设下一个词的出现依赖它前面的两个词,则有:

那么,我们在面临实际问题时,如何选择依赖词的个数,即n。

更大的n:对下一个词出现的约束信息更多,具有更大的辨别力;

更小的n:在训练语料库中出现的次数更多,具有更可靠的统计信息,具有更高的可靠性。

理论上,n越大越好,经验上,trigram用的最多,尽管如此,原则上,能用bigram解决,绝不使用trigram。

 3、NLP词的表示方法类型

 3.1、词的独热表示one-hot

用词向量来表示词并不是word2vec的首创,在很久之前就出现了。最早的词向量是很冗长的,它使用是词向量维度大小为整个词汇表的大小,对于每个具体的词汇表中的词,将对应的位置置为1。比如我们有5个词组成的词汇表,词"Queen"在词汇表中的序号为2, 那么它的词向量就是(0,1,0,0,0)。同样的道理,词"Woman"是序号3,词向量就是(0,0,1,0,0)。这种词向量的编码方式我们一般叫做one hot representation.

One hot representation用来表示词向量非常简单,但是却有很多问题。
1、任意两个词之间都是孤立的,根本无法表示出在语义层面上词语词之间的相关信息,而这一点是致命的。
2、我们的词汇表一般都非常大,比如达到百万级别,这样每个词都用百万维的向量来表示简直是内存的灾难。能不能把词向量的维度变小呢?

3.2、词的分布式表示 distributed representation

Dristributed representation可以解决One hot representation的问题,它的思路是通过训练,将每个词都映射到一个较短的词向量上来。所有的这些词向量就构成了向量空间,进而可以用普通的统计学的方法来研究词与词之间的关系。这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。
词的分布式表示主要可以分为三类:基于矩阵的分布表示、基于聚类的分布表示和基于神经网络的分布表示

 4.CBOW

CBOW(Continuous Bag-of-Word Model)又称连续词袋模型,是一个三层神经网络。如下图所示,该模型的特点是输入已知上下文,输出对当前单词的预测。
其神经网络示意图如下

网络计算的步骤:

1
输入层:上下文单词的onehot。(假设单词向量空间dim为V,上下文单词个数为C) 所有onehot分别乘以共享的输入权重矩阵W(V*N矩阵,N为自己设定的数,初始化权重矩阵W) 所得的向量 (注意onehot向量乘以矩阵的结果) 相加求平均作为隐层向量, size为 1*N. 乘以输出权重矩阵W’ {N*V} 得到向量 {1*V} 输出经过softmax处理得到V-dim概率分布 {PS: 因为是onehot嘛,其中的每一维斗代表着一个单词},概率最大的index所指示的单词为预测出的中间词(target word) 与true label的onehot做比较,误差越小越好。loss function(一般为交叉熵代价函数)

其学习目标是最大化对数似然函数:

其中,w表示语料库C中任意一个词,即上下文词个数为C
则损失函数为

 5.Skip-gram Model

Skip-gram只是逆转了CBOW的因果关系而已,即已知当前词语,预测上下文。
word2vec在训练过程中的权重矩阵特别大,其还有两种方法优化训练过程。

 6.优化训练方法

 6.1 负采样(negative sampling)

 6.2 层序softmax

目前还不是很能理解这两种办法,等以后再来回顾

 7.实例

下面是使用jieba和gensim中的word2vec模块所做的一个实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import jieba.analyse 
import jieba
import os
from gensim.models import word2vec
import logging #添加专有名词,增加分词力度
jieba.suggest_freq('贾宝玉', True)
jieba.suggest_freq('林黛玉', True)
jieba.suggest_freq('薛宝钗', True) j
ieba.suggest_freq('袭人', True)
raw_data_path = 'KG/'
cut_data_path = 'KG/'
def cut_word(file, cut_data_path ): #获取分词
corpus = '' with open(file,'rb')
as f: document = f.read()
document_cut = jieba.cut(document, cut_all=False) #print('/'.join(document_cut))
result = ' '.join(document_cut)
corpus += result # print(result)
with open(cut_data_path + 'corpus.txt', 'w+', encoding='utf-8') as f:
f.write(corpus) # 读取的方式和写入的方式要一致
if __name__ == "__main__":
# cut_word('KG/红楼梦.txt', cut_data_path )
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.Text8Corpus('KG/corpus.txt')
model = word2vec.Word2Vec(sentences, sg=1, vector_size=200, window=5, min_count=5, negative=3, sample=0.001, hs=1, workers=4)
model.save('KG/corpus.model') print(model.wv['贾宝玉']) sim3 =
model.wv.most_similar('贾宝玉', topn=10) print(u'和 贾宝玉 与相关的词有:\n')
for key in sim3:
print(key[0], key[1])

下面是这个程序的输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[ 0.11517011 -0.13025182 -0.0506697   0.11230026  0.07825588  0.06083265  
0.0408464 0.03688164 -0.05094394 0.17846571 0.19295628 -0.29943186
0.0098872 -0.14978722 0.21381369 -0.29901278 0.10257801 0.25977957
-0.1001724 -0.15933797 0.10237969 0.18143703 0.02323888 -0.1736733
0.07725268 0.05197921 0.08818506 0.07531644 -0.20006429 0.00145636
0.23089637 -0.36198795 -0.0430769 -0.13304433 -0.1252904 0.04084631
0.13447632 0.05730589 0.10593662 -0.04668168 0.12648581 0.37434196
-0.07581735 -0.15072787 0.42846853 0.13130079 0.06006766 0.08752171
0.15320961 0.21977353 -0.03631958 0.05457588 0.07916655 0.06465171
0.10700669 0.11692763 -0.09689093 -0.05524246 -0.0868606 0.0268482
-0.15390296 0.08069665 0.01684778 -0.1281145 -0.305897 -0.03418773
-0.00838467 0.08522575 -0.10539597 0.20390259 0.39062884 0.13825959
0.17423898 -0.03503856 0.25166708 0.23292418 0.1459586 0.10998154
-0.05249673 -0.05719278 -0.09460621 -0.36269784 -0.05919957 -0.08704155
-0.02401703 0.03694021 -0.10069004 0.08158587 -0.2939494 0.05513043
-0.02810754 -0.13240668 -0.02678989 -0.00324869 0.03421985 0.21324556
0.0490126 -0.03631027 -0.04038492 -0.01939965 -0.24949607 -0.06678798
-0.12399574 -0.09400048 0.15759763 -0.13440803 -0.07642241 0.0066554
0.14551373 -0.00258602 -0.05648774 0.03031638 0.00097021 0.40590286
-0.01667857 0.02245313 -0.1146565 -0.23001415 -0.19945267 -0.00686539
0.05684485 -0.00525961 -0.01324855 0.17506842 0.08980455 0.12515226
-0.02082999 -0.053046 -0.03555432 0.19290274 -0.07884279 -0.05359721
-0.13929941 0.1570391 0.11968376 0.1315601 0.1282832 0.05463606
-0.27178845 0.30758822 -0.00487008 0.22340722 -0.11702839 0.18459897
-0.08955741 -0.10950074 -0.06030292 0.19976623 -0.2730275 -0.0286714
0.0274738 -0.2032307 -0.17168123 -0.03858007 -0.25066993 0.2920612
0.09440704 -0.09552719 -0.0461195 -0.01838781 0.15252623 -0.01901472
0.00353702 0.11581032 0.17089194 0.0975273 0.25131223 -0.06320237
0.24443214 0.24325773 0.00553935 -0.07861853 0.09858089 0.17023644
-0.05549836 0.12124551 -0.05982196 0.19874723 -0.2739703 0.19873911
-0.20672254 0.13343875 0.24379355 -0.24623941 -0.16303726 -0.1372122
0.01212609 0.19902556 0.05054887 0.02906352 0.310327 0.32060975
-0.17382732 -0.09415792 -0.0584261 -0.0306631 0.03928678 0.09031721
0.012616 0.13385603]
和 贾宝玉 与相关的词有:
甄宝玉 0.7270691394805908
互相 0.7252477407455444
问话 0.6985926628112793
回京 0.698554515838623
传旨 0.6983145475387573
未敢 0.6960150003433228
大臣 0.6944164633750916
审 0.6907076239585876
悲戚 0.6883816123008728
父 0.6867508292198181

和贾宝玉相关最高的是甄宝玉,可以看出在这个参数下word2vec具有一定的参考价值,因为真假宝玉是书中的两条线,相关性高是可以理解的。