word2vec是目前比较通用的训练词向量的工具,使用Gensim模块,可以使词向量的训练变的简单,但是调用gensim.models的word2vec模块使用skip-gram或CBOW完成词向量训练之后,如何获取词向量中的词汇表以及对应的词向量矩阵呢。本文以一个小例子进行演示。

1. 导入相关包

主要用到了jieba和gensim包,可以使用命令行pip3 install gensim或下载gensim包的方式,具体不述。

  1. import jieba
  2. from gensim.models import Word2Vec

1. 加载语料并清洗

为了方便演示,本文直接定义了一个语料,并使用jieba进行分词操作。

  1. # 停用词
  2. stopword_list = []
  3. with open('./stopwords.txt', 'r+', encoding='utf8') as f:
  4. for word in f.readlines():
  5. if len(word)>0 and word != '\n\t':
  6. stopword_list.append(word)
  7. # 语料
  8. content = [
  9. "长江是中国第一大河,干流全长6397公里(以沱沱河为源),一般称6300公里。流域总面积一百八十余万平方公里,年平均入海水量约九千六百余亿立方米。以干流长度和入海水量论,长江均居世界第三位。",
  10. "黄河,中国古代也称河,发源于中华人民共和国青海省巴颜喀拉山脉,流经青海、四川、甘肃、宁夏、内蒙古、陕西、山西、河南、山东9个省区,最后于山东省东营垦利县注入渤海。干流河道全长5464千米,仅次于长江,为中国第二长河。黄河还是世界第五长河。",
  11. "黄河,是中华民族的母亲河。作为中华文明的发祥地,维系炎黄子孙的血脉.是中华民族民族精神与民族情感的象征。",
  12. "黄河被称为中华文明的母亲河。公元前2000多年华夏族在黄河领域的中原地区形成、繁衍。",
  13. "在兰州的“黄河第一桥”内蒙古托克托县河口镇以上的黄河河段为黄河上游。",
  14. "黄河上游根据河道特性的不同,又可分为河源段、峡谷段和冲积平原三部分。 ",
  15. "黄河,是中华民族的母亲河。"
  16. ]
  17. # 分词
  18. seg = [jieba.lcut(text) for text in content]
  19. # 清洗
  20. content_clean = []
  21. for t in seg:
  22. text_clean = []
  23. for i in t:
  24. if len(i)>1 and i != '\t\n':
  25. if not i.isdigit():
  26. if i.strip() not in stopword_list:
  27. text_clean.append(i.strip())
  28. content_clean.append(text_clean)

最后的content_clean为一个list,具体为:
批注 2020-05-13 155509.png

3. 使用gensim训练词向量

  1. ## 用gensim训练词向量模型
  2. model = Word2Vec(content_clean, sg=1, size=100, window=5, min_count=2, negative=1,
  3. sample=0.001, workers=4)
  4. '''
  5. sg=1 是 skip-gram 算法,对低频词敏感;默认 sg=0 为 CBOW 算法。
  6. size 是输出词向量的维数,值太小会导致词映射因为冲突而影响结果,值太大则会耗内存并使算法计算变慢,一般值取为100到200之间。
  7. window 是句子中当前词与目标词之间的最大距离,3表示在目标词前看3-b 个词,后面看 b 个词(b 在0-3之间随机)。
  8. min_count 是对词进行过滤,频率小于 min-count 的单词则会被忽视,默认值为5。
  9. negative 和 sample 可根据训练结果进行微调,sample 表示更高频率的词被随机下采样到所设置的阈值,默认值为 1e-3。
  10. hs=1 表示层级 softmax 将会被使用,默认 hs=0 且 negative 不为0,则负采样将会被选择使用。
  11. '''
  12. # 训练后的模型model可以保存,备用
  13. model.save('./word2vec') #保存
  14. model = Word2Vec.load('word2vec') #加载model

代码中model是一个训练好的词向量模型,里面包含许多内容,可以获取词汇表和对应的词向量。

  1. ## 获取词汇
  2. words = model.wv.index2word
  3. print(words) # 长度18
  4. # ['黄河', '长江', '中国', '干流', '中华民族', '母亲河', '第一', '全长',
  5. # '公里', '入海', '水量', '世界', '内蒙古', '河道', '长河', '中华文明', '民族', '上游']
  6. ## 获取对应词向量
  7. vectors = model.wv.vectors
  8. print(vectors) # 18*100 100为设置的size,即词向量维度
  9. #[[ 1.2898202e-03 -3.4580764e-03 3.4779524e-03 ... -3.6768757e-03
  10. # 2.6582647e-03 -3.7408734e-03]
  11. # [ 2.9404070e-03 3.9611240e-03 -2.1796243e-03 ... 2.3843886e-03
  12. # -4.3357350e-03 -3.3540600e-03]
  13. # [ 4.9255025e-03 1.4151304e-03 -8.7503344e-04 ... 4.2551141e-03
  14. # -2.9053804e-03 3.6766860e-03]
  15. # ...
  16. # [ 1.9452259e-03 4.8658932e-03 -2.3852135e-03 ... -2.7566685e-03
  17. # 4.9943980e-03 -3.9313175e-03]
  18. # [ 5.2972522e-04 4.8273476e-03 -3.0694890e-03 ... 4.2261067e-03
  19. # 9.7657423e-05 4.4411011e-03]
  20. # [-2.2659900e-03 1.5058877e-03 -4.7887382e-03 ... 2.4552434e-03
  21. # 4.4189487e-04 5.9008709e-04]]
  22. ## 根据指定词获取该词的向量
  23. vec = model.wv['长江']
  24. print(vec)
  25. #[ 2.9404070e-03 3.9611240e-03 -2.1796243e-03 3.5846021e-03
  26. # -8.5443829e-04 -1.5641276e-03 -1.6966875e-03 -4.6902820e-03
  27. # -4.3645203e-03 -1.8363699e-03 -3.9727231e-03 4.7817207e-03
  28. # -1.3380363e-03 -2.6813489e-03 4.1867769e-03 3.4822649e-03
  29. # -3.9391480e-03 -2.3266519e-03 1.4906399e-03 -7.4510416e-04
  30. # ...
  31. ## 判断词之间的相似度
  32. print(model.similarity('黄河','黄河')) #1.0
  33. print(model.similarity('黄河','长江')) #-0.08
  34. print(model.similarity('黄河','中国')) #0.14
  35. ## 预测与'黄河'和'母亲河'最相似,而与长江不接近的词
  36. print(model.most_similar(positive=['黄河','母亲河'], negative=['长江']))
  37. #[('长河', 0.10036612302064896), ('世界', 0.065335713326931),
  38. # ('民族', 0.05369586870074272), ('中华民族', 0.03456304967403412),
  39. # ('入海', 0.00084715336561203), ('公里', -0.007249757647514343),
  40. # ('第一', -0.0175853930413723), ('内蒙古', -0.0281079038977623),
  41. # ('干流', -0.02939787693321705), ('上游', -0.029546111822128296)]
  42. #__main__:1: DeprecationWarning: Call to deprecated `most_similar`
  43. #(Method will be removed in 4.0.0, use self.wv.most_similar() instead).