gensim实现word2vec

Myth丶恋晨 2023-05-31 12:09 82阅读 0赞

word2vec模型

假设给定一个长度为T的文本序列,设时间步t的词为w(t)。假设给定中心词的情况下背景词的生成相互独立,当背景窗口大小为m时,跳字模型的似然函数即给定任一中心词生成所有背景词的概率:

∏ t = 1 T ∏ − m ≤ j ≤ m , j ≠ 0 P ( w ( t + j ) ∣ w ( t ) ) ​ \prod_{t=1}^{T} \prod_{-m \leq j \leq m, j \neq 0} P\left(w^{(t+j)} | w^{(t)}\right)​ ∏t=1T​∏−m≤j≤m,j​=0​P(w(t+j)∣w(t))​

设中心词wc在词典中索引为c,背景词wo在词典中索引为o,给定中心词生成背景词的条件概率可以通过对向量内积做softmax运算而得到:

P ( w o ∣ w c ) = exp ⁡ ( u o ⊤ v c ) ∑ i ∈ V exp ⁡ ( u i ⊤ v c ) P\left(w_{o} | w_{c}\right)=\frac{\exp \left(\boldsymbol{u}_{o}^{\top} \boldsymbol{v}_{c}\right)}{\sum_{i \in \mathcal{V}} \exp \left(\boldsymbol{u}_{i}^{\top} \boldsymbol{v}_{c}\right)} P(wo​∣wc​)=∑i∈V​exp(ui⊤​vc​)exp(uo⊤​vc​)​

模型训练

通过最大化似然函数来学习模型参数,即最大似然估计。这等价于最小化以下损失函数:

− ∑ t = 1 T ∑ − m ≤ j ≤ m , j ≠ 0 log ⁡ P ( w ( t + j ) ∣ w ( t ) ) -\sum_{t=1}^{T} \sum_{-m \leq j \leq m, j \neq 0} \log P\left(w^{(t+j)} | w^{(t)}\right) −∑t=1T​∑−m≤j≤m,j​=0​logP(w(t+j)∣w(t))

采用随机梯度下降算法

∂ log ⁡ P ( w o ∣ w c ) ∂ v c = u o − ∑ j ∈ V exp ⁡ ( u j ⊤ v c ) u j ∑ i ∈ V exp ⁡ ( u i ⊤ v c ) = u o − ∑ j ∈ V ( exp ⁡ ( u j ⊤ v c ) ∑ i ∈ V exp ⁡ ( u i ⊤ v c ) ) u j = u o − ∑ j ∈ V P ( w j ∣ w c ) u j \begin{aligned} \frac{\partial \log P\left(w_{o} | w_{c}\right)}{\partial \boldsymbol{v}_{c}} &=\boldsymbol{u}_{o}-\frac{\sum_{j \in \mathcal{V}} \exp \left(\boldsymbol{u}_{j}^{\top} \boldsymbol{v}_{c}\right) \boldsymbol{u}_{j}}{\sum_{i \in \mathcal{V}} \exp \left(\boldsymbol{u}_{i}^{\top} \boldsymbol{v}_{c}\right)} \\ &=\boldsymbol{u}_{o}-\sum_{j \in \mathcal{V}}\left(\frac{\exp \left(\boldsymbol{u}_{j}^{\top} \boldsymbol{v}_{c}\right)}{\sum_{i \in \mathcal{V}} \exp \left(\boldsymbol{u}_{i}^{\top} \boldsymbol{v}_{c}\right)}\right) \boldsymbol{u}_{j} \\ &=\boldsymbol{u}_{o}-\sum_{j \in \mathcal{V}} P\left(w_{j} | w_{c}\right) \boldsymbol{u}_{j} \end{aligned} ∂vc​∂logP(wo​∣wc​)​​=uo​−∑i∈V​exp(ui⊤​vc​)∑j∈V​exp(uj⊤​vc​)uj​​=uo​−j∈V∑​(∑i∈V​exp(ui⊤​vc​)exp(uj⊤​vc​)​)uj​=uo​−j∈V∑​P(wj​∣wc​)uj​​

Gensim词向量训练

Gensim是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。它支持包括TF-IDF,LSA,LDA和word2vec在内的多种主题模型算法,支持流式训练,并提供了诸如相似度计算信息检索等一些常用任务的API接口。

1.维基百科数据集(大约1.8G)

https://dumps.wikimedia.org/zhwiki/20190701/

在这里插入图片描述

2.将wiki的xml文件处理成正常的txt文件

在这里插入图片描述

代码:

  1. #把基百科的下载xml.bz2文件转化成text文件 (process.py)
  2. import logging
  3. import os.path
  4. import sys
  5. from gensim.corpora import WikiCorpus
  6. if __name__ == '__main__':
  7. program = os.path.basename(sys.argv[0])
  8. logger = logging.getLogger(program)
  9. logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
  10. logging.root.setLevel(level=logging.INFO)
  11. logger.info("running %s" % ' '.join(sys.argv))
  12. # check and process input arguments
  13. if len(sys.argv) < 3:
  14. print(globals()['__doc__'] % locals())
  15. sys.exit(1)
  16. inp, outp = sys.argv[1:3]
  17. space =' '
  18. i = 0
  19. output = open(outp, 'w',encoding='utf-8')
  20. wiki = WikiCorpus(inp, lemmatize=False, dictionary={ })
  21. for text in wiki.get_texts():
  22. s = space.join(text)
  23. s = s.encode('utf-8').decode('utf8') + "\n"
  24. output.write(s)
  25. i = i + 1
  26. if (i % 10000 == 0):
  27. logger.info("Saved " + str(i) + " articles")
  28. output.close()
  29. logger.info("Finished Saved " + str(i) + " articles")

运行:

在这里插入图片描述

3.使用opencc将繁体txt转换为简体txt

在这里插入图片描述

将前面生成的wiki.zh.text拖动至opencc-1.0.1-win64文件夹中,cmd在当前文件夹中输入如下:

  1. opencc -i wiki.zh.text -o wiki.zh.jian.text -c t2s.json

4.jieba分词

在这里插入图片描述

代码:

  1. #jieba分词(jieba_cut.py)
  2. import jieba
  3. import jieba.analyse
  4. import jieba.posseg as pseg
  5. import codecs, sys
  6. def cut_words(sentence):
  7. #print sentence
  8. return " ".join(jieba.cut(sentence)).encode('utf-8')
  9. f = codecs.open('wiki.zh.jian.text', 'r', encoding="utf8")
  10. target = codecs.open("zh.jian.wiki.seg.txt", 'w', encoding="utf8")
  11. print('open files')
  12. line_num = 1
  13. line = f.readline()
  14. while line:
  15. print('---- processing ', line_num, ' article----------------')
  16. line_seg = " ".join(jieba.cut(line))
  17. target.writelines(line_seg)
  18. line_num = line_num + 1
  19. line = f.readline()
  20. f.close()
  21. target.close()
  22. exit()

5.词向量训练

  1. from __future__ import print_function
  2. import logging
  3. import os
  4. import sys
  5. import multiprocessing
  6. from gensim.models import Word2Vec
  7. from gensim.models.word2vec import LineSentence
  8. if __name__ == '__main__':
  9. program = os.path.basename(sys.argv[0])
  10. logger = logging.getLogger(program)
  11. logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
  12. logging.root.setLevel(level=logging.INFO)
  13. logger.info("running %s" % ' '.join(sys.argv))
  14. # check and process input arguments
  15. if len(sys.argv) < 4:
  16. print("Useing: python train_word2vec_model.py input_text "
  17. "output_gensim_model output_word_vector")
  18. sys.exit(1)
  19. inp, outp1, outp2 = sys.argv[1:4]
  20. model = Word2Vec(LineSentence(inp), size=200, window=5, min_count=5,
  21. workers=multiprocessing.cpu_count())
  22. model.save(outp1)
  23. model.wv.save_word2vec_format(outp2, binary=False)

训练过程大致为25分钟
在这里插入图片描述

训练后得到的词向量
在这里插入图片描述

6.测试模型

查找相似词

  1. from gensim.models import Word2Vec
  2. en_wiki_word2vec_model=Word2Vec.load('wiki.zh.model')
  3. testwords=['孩子','苹果','篮球','学习','动物']
  4. for i in range (5):
  5. res = en_wiki_word2vec_model.wv.most_similar(testwords[i])
  6. print (testwords[i])
  7. print (res)

结果:
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,82人围观)

还没有评论,来说两句吧...

相关阅读