前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第六章(1.2)自然语言处理实战——打造属于自己的中文word2vector工具

第六章(1.2)自然语言处理实战——打造属于自己的中文word2vector工具

作者头像
两只橙
发布2019-02-14 15:53:05
8831
发布2019-02-14 15:53:05
举报
文章被收录于专栏:深度学习深度学习

一、环境

二、实战演练

  • 训练语料source.txt
代码语言:javascript
复制
9月12日随着颁奖典礼的结束,我院获得了商委系统运动会系列活动之一——足球比赛的季军,本次比赛立时十天,十二只球队分成两个小组比赛。我院代表队以小组第二名的成绩出现,在和另一小组第二名石油公司争夺三四名的比赛中,教师们超水平发挥,以五比一的比分大胜对手,获得第三名的优异成绩..
本次比赛由商委主办,我院协办,在我院漂亮的足球场地举行。我院代表队领队孙增春、教练员张鹏,十八名队员都是由学院各部门的老师组成,。并且是在不耽误工作的情况下参加比赛的,商管系的张援越老师已经是年过四十的副教授,在场上依然是生龙活虎,不缺席每一场比赛,为球队的胜利作出了很大的贡献;体育部的梁浩老师, ,这次比赛担任球队的队长,每场比赛都冲锋在前,起到了表率作用;招办的的张国权老师一直是带伤比赛为球队立下战功。体育部的孙增春主任每常比赛亲临现场,给队员打气助威,为队员们增加了信心.
学院领导对比赛非常重视,王院长几次到场为队员们加油助威,许韵苓院助、许艳红主任也给予了大力的支持,一切为了比赛开绿灯,为队员们解决了很多后顾之忧。足球比赛第三名的成绩,使我院在商务系统运动会总成绩的排名又向前提升了一块,同时也充分展示了学院在体育工作方面的优良成绩。
体育教学部
  • 需要运用到的包
代码语言:javascript
复制
#!/bin/bash
# -*-coding=utf-8-*-
import jieba
import re
from gensim.models import word2vec
import multiprocessing
import gensim
  • 使用jieba切词,并过滤文本中的标点符号,生成切词文件
代码语言:javascript
复制
def segment_text(source_corpus, train_corpus, coding, punctuation):
    '''
    切词,去除标点符号
    :param source_corpus: 原始语料
    :param train_corpus: 切词语料
    :param coding: 文件编码
    :param punctuation: 去除的标点符号
    :return:
    '''
    with open(source_corpus, 'r', encoding=coding) as f, open(train_corpus, 'w', encoding=coding) as w:
        for line in f:
            # 去除标点符号
            line = re.sub('[{0}]+'.format(punctuation), '', line.strip())
            # 切词
            words = jieba.cut(line)
            w.write(' '.join(words))
  • 设置需要过滤的标点符号(注意:这里也可以过滤特殊字符)
代码语言:javascript
复制
    # 严格限制标点符号
    strict_punctuation = '。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑·¨….¸;!´?!~—ˉ|‖"〃`@﹫¡¿﹏﹋﹌︴々﹟#﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄¯―﹨ˆ˜﹍﹎+=<­­__-\ˇ~﹉﹊()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】︵︷︿︹︽_﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼'
    # 简单限制标点符号
    simple_punctuation = '’!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
    # 去除标点符号
    punctuation = simple_punctuation + strict_punctuation
  • 设置文件编码,原始语料,切词语料,输出模型文件,模型参数
代码语言:javascript
复制
    # 文件编码
    coding = 'utf-8'
    # 原始语料
    source_corpus_text = 'source.txt'

    # 是每个词的向量维度
    size = 400
    # 是词向量训练时的上下文扫描窗口大小,窗口为5就是考虑前5个词和后5个词
    window = 5
    # 设置最低频率,默认是5,如果一个词语在文档中出现的次数小于5,那么就会丢弃
    min_count = 1
    # 是训练的进程数,默认是当前运行机器的处理器核数。
    workers = multiprocessing.cpu_count()
    # 切词语料
    train_corpus_text = 'words.txt'
    # w2v模型文件
    model_text = 'w2v_size_{0}.model'.format(size)
  • 切词
代码语言:javascript
复制
 # 切词 @TODO 切词后注释
 segment_text(source_corpus_text, train_corpus_text, coding, punctuation)
  • 训练word2vector模型
代码语言:javascript
复制
 # w2v训练模型 @TODO 训练后注释
 sentences = word2vec.Text8Corpus(train_corpus_text)
 model = word2vec.Word2Vec(sentences=sentences, size=size, window=window, min_count=min_count, workers=workers)
 model.save(model_text)
  • 加载训练模型,打印词向量(注意:词需要在文本中出现过)
代码语言:javascript
复制
 model = gensim.models.Word2Vec.load(model_text)
 print(model['运动会'])
代码语言:javascript
复制
[  5.77729312e-04   6.29229005e-04   3.28074140e-03  -3.12230410e-03
   3.58627993e-03  -1.17090892e-03  -1.19168102e-03   4.79813945e-03
   2.53833435e-03  -4.91693895e-03   4.33469191e-04   4.36443230e-03
   2.68062111e-03  -4.80209151e-03  -1.00263488e-03  -6.90411602e-04
   1.44691532e-03   4.22825292e-03   2.65496224e-03   3.37875634e-03
   9.92664369e-04  -5.25792711e-04   4.22688853e-03   3.42451921e-03
   4.13528131e-03  -9.61833517e-04  -3.25134676e-03  -4.56051296e-03
  -1.79338397e-03  -1.44107558e-03  -5.76348466e-05   3.97552829e-03
   4.96467901e-03   2.99101393e-03   4.31695720e-03   1.33437128e-03
  -2.85419100e-03   4.18939814e-03   3.87660973e-03   3.83673748e-03
   4.17304545e-04  -1.07788993e-03  -1.12797145e-03  -4.58187424e-03
  -3.77954915e-03  -3.86176654e-03   1.82412425e-03   3.85237101e-04
   1.85760713e-04  -2.44700629e-03  -2.03684112e-03   1.23822887e-04
  -4.58160602e-03   3.57383513e-04   2.92601017e-03  -1.15508388e-03
  -2.67226575e-03  -3.23730893e-03   7.30269181e-04   2.51975632e-03
  -7.53291533e-04  -4.10789764e-03   6.79552031e-04  -3.64084938e-03
  -3.41395871e-03   3.35737667e-03  -2.09669583e-03  -2.52196239e-03
   2.53840582e-03   1.40796602e-03   2.21067248e-03   2.54736491e-03
  -4.86714346e-03   3.46355117e-03   3.78919905e-03  -2.19983887e-03
  -1.70295069e-03   3.36180092e-03   2.82198866e-03   9.91262612e-04
   2.30853050e-03  -2.77805189e-03   4.64708824e-03   3.24234832e-03
   2.93854857e-03   8.39327520e-04   1.29010330e-03   2.45986215e-04
  -3.73935048e-03  -3.95879382e-03  -5.32814476e-04  -5.52327721e-04
   8.64025322e-04   8.57468927e-04  -3.78349214e-03  -2.84406659e-03
  -2.61127157e-03   3.54953948e-03   3.86928394e-03   2.82278913e-03]
  • 计算一个词的最近似词(注意:词需要在文本中出现过)
代码语言:javascript
复制
  # 计算一个词的最近似的词,倒序
  similar_words = model.most_similar('球队')
  for word in similar_words:
      print(word[0], word[1])
代码语言:javascript
复制
情况 0.2297670692205429
副教授 0.1899721473455429
梁浩 0.18567171692848206
系列 0.18228858709335327
许韵苓 0.16966953873634338
教练员 0.16140426695346832
和 0.15026438236236572
几次 0.14221936464309692
不 0.13802526891231537
了 0.13522613048553467
  • 计算两词之间的余弦相似度(注意:词需要在文本中出现过)
代码语言:javascript
复制
  sim1 = model.similarity('运动会', '总成绩')
  sim2 = model.similarity('排名', '运动会')
  sim3 = model.similarity('展示', '学院')
  sim4 = model.similarity('学院', '体育')
  print(sim1)
  print(sim2)
  print(sim3)
  print(sim4)
代码语言:javascript
复制
-0.0917341372671
0.0526127512661
0.081955751928
-0.139067511821
0.578819521306
-0.0909827364054
  • 计算两个集合之间的余弦似度(注意:词需要在文本中出现过)
代码语言:javascript
复制
  list1 = ['运动会', '总成绩']
  list2 = ['排名', '运动会']
  list3 = ['学院', '体育']
  list_sim1 = model.n_similarity(list1, list2)
  print(list_sim1)
  list_sim2 = model.n_similarity(list1, list3)
  print(list_sim2)
  • 选出集合中不同类的词语(注意:词需要在文本中出现过)
代码语言:javascript
复制
  list = ['队员', '足球比赛', '小组', '代表队']
  print(model.doesnt_match(list))
  list = ['队员', '足球比赛', '小组', '西瓜']
  print(model.doesnt_match(list))
代码语言:javascript
复制
代表队
小组
  • 运行python word2vector.py

三 、实战代码

  • word2vector.py
代码语言:javascript
复制
#!/bin/bash
# -*-coding=utf-8-*-
import jieba
import re
from gensim.models import word2vec
import multiprocessing
import gensim


def segment_text(source_corpus, train_corpus, coding, punctuation):
    '''
    切词,去除标点符号
    :param source_corpus: 原始语料
    :param train_corpus: 切词语料
    :param coding: 文件编码
    :param punctuation: 去除的标点符号
    :return:
    '''
    with open(source_corpus, 'r', encoding=coding) as f, open(train_corpus, 'w', encoding=coding) as w:
        for line in f:
            # 去除标点符号
            line = re.sub('[{0}]+'.format(punctuation), '', line.strip())
            # 切词
            words = jieba.cut(line)
            w.write(' '.join(words))


if __name__ == '__main__':
    # 严格限制标点符号
    strict_punctuation = '。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑·¨….¸;!´?!~—ˉ|‖"〃`@﹫¡¿﹏﹋﹌︴々﹟#﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄¯―﹨ˆ˜﹍﹎+=<­­__-\ˇ~﹉﹊()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】︵︷︿︹︽_﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼'
    # 简单限制标点符号
    simple_punctuation = '’!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
    # 去除标点符号
    punctuation = simple_punctuation + strict_punctuation

    # 文件编码
    coding = 'utf-8'
    # 原始语料
    source_corpus_text = 'source.txt'

    # 是每个词的向量维度
    size = 400
    # 是词向量训练时的上下文扫描窗口大小,窗口为5就是考虑前5个词和后5个词
    window = 5
    # 设置最低频率,默认是5,如果一个词语在文档中出现的次数小于5,那么就会丢弃
    min_count = 1
    # 是训练的进程数,默认是当前运行机器的处理器核数。
    workers = multiprocessing.cpu_count()
    # 切词语料
    train_corpus_text = 'words.txt'
    # w2v模型文件
    model_text = 'w2v_size_{0}.model'.format(size)

    # 切词 @TODO 切词后注释
    # segment_text(source_corpus_text, train_corpus_text, coding, punctuation)

    # w2v训练模型 @TODO 训练后注释
    sentences = word2vec.Text8Corpus(train_corpus_text)
    model = word2vec.Word2Vec(sentences=sentences, size=size, window=window, min_count=min_count, workers=workers)
    model.save(model_text)

    # 加载模型
    model = gensim.models.Word2Vec.load(model_text)
    # print(model['运动会'])

    # 计算一个词的最近似的词,倒序
    # similar_words = model.most_similar('球队')
    # for word in similar_words:
    #     print(word[0], word[1])

    # 计算两词之间的余弦相似度
    # sim1 = model.similarity('运动会', '总成绩')
    # sim2 = model.similarity('排名', '运动会')
    # sim3 = model.similarity('展示', '学院')
    # sim4 = model.similarity('学院', '体育')
    # print(sim1)
    # print(sim2)
    # print(sim3)
    # print(sim4)

    # 计算两个集合之间的余弦似度
    list1 = ['运动会', '总成绩']
    list2 = ['排名', '运动会']
    list3 = ['学院', '体育']
    list_sim1 = model.n_similarity(list1, list2)
    print(list_sim1)
    list_sim2 = model.n_similarity(list1, list3)
    print(list_sim2)

    # 选出集合中不同类的词语
    list = ['队员', '足球比赛', '小组', '代表队']
    print(model.doesnt_match(list))
    list = ['队员', '足球比赛', '小组', '西瓜']
    print(model.doesnt_match(list))

四、注意

  • 若词未在文本中出现,会报错
代码语言:javascript
复制
Traceback (most recent call last):
  File "E:/项目/test/word2vec.py", line 64, in <module>
    print(model['一周'])
  File "D:\software\work\Anaconda3\lib\site-packages\gensim\models\word2vec.py", line 1281, in __getitem__
    return self.wv.__getitem__(words)
  File "D:\software\work\Anaconda3\lib\site-packages\gensim\models\keyedvectors.py", line 589, in __getitem__
    return self.word_vec(words)
  File "D:\software\work\Anaconda3\lib\site-packages\gensim\models\keyedvectors.py", line 288, in word_vec
    raise KeyError("word '%s' not in vocabulary" % word)
KeyError: "word '一周' not in vocabulary"
  • 若词出现在文本中,但加载使用模型时仍然报错,可能是训练模型的参数min_count设置过大
代码语言:javascript
复制
  # 设置最低频率,默认是5,如果一个词语在文档中出现的次数小于5,那么就会丢弃
  min_count = 1
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.01.13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档