Word2Vec实践

拥有回忆 提交于 2020-01-31 16:29:36


之前了解过Word2Vec的原理,但是没有做过项目实践,这次得到一批专利数据,所以自己上手实践一下。
数据参考:
https://github.com/newzhoujian/LCASPatentClassification

1 gensim word2vec API概述

在gensim中,word2vec 相关的API都在包gensim.models.word2vec中。和算法有关的参数都在类gensim.models.word2vec.Word2Vec中。算法需要注意的参数有:

 1) sentences: 我们要分析的语料,可以是一个列表,或者从文件中遍历读出。后面我们会有从文件读出的例子。
 2) size: 词向量的维度,默认值是100。这个维度的取值一般与我们的语料的大小相关,如果是不大的语料,比如小于100M的文本语料,则使用默认值一般就可以了。如果是超大的语料,建议增大维度。
 3) window:即词向量上下文最大距离,这个参数在我们的算法原理篇中标记为c,window越大,则和某一词较远的词也会产生上下文关系。默认值为5。在实际使用中,可以根据实际的需求来动态调整这个window的大小。如果是小语料则这个值可以设的更小。对于一般的语料这个值推荐在[5,10]之间。
 4) sg: 即我们的word2vec两个模型的选择了。如果是0, 则是CBOW模型,是1则是Skip-Gram模型,默认是0即CBOW模型。
 5) hs: 即我们的word2vec两个解法的选择了,如果是0, 则是Negative Sampling,是1的话并且负采样个数negative大于0, 则是Hierarchical Softmax。默认是0即Negative Sampling。
 6) negative:即使用Negative Sampling时负采样的个数,默认是5。推荐在[3,10]之间。这个参数在我们的算法原理篇中标记为neg。
 7) cbow_mean: 仅用于CBOW在做投影的时候,为0,则算法中的xw为上下文的词向量之和,为1则为上下文的词向量的平均值。在我们的原理篇中,是按照词向量的平均值来描述的。个人比较喜欢用平均值来表示xw,默认值也是1,不推荐修改默认值。
 8) min_count:需要计算词向量的最小词频。这个值可以去掉一些很生僻的低频词,默认是5。如果是小语料,可以调低这个值。
 9) iter: 随机梯度下降法中迭代的最大次数,默认是5。对于大语料,可以增大这个值。
 10) alpha: 在随机梯度下降法中迭代的初始步长。算法原理篇中标记为η,默认是0.025。
 11) min_alpha: 由于算法支持在迭代的过程中逐渐减小步长,min_alpha给出了最小的迭代步长值。随机梯度下降中每轮的迭代步长可以由iter,alpha, min_alpha一起得出。这部分由于不是word2vec算法的核心内容,因此在原理篇我们没有提到。对于大语料,需要对alpha, min_alpha,iter一起调参,来选择合适的三个值。

2 模型训练

  • 注: 刘建平Pinard 博客中说,由于word2vec的算法依赖于上下文,而上下文有可能就是停词。因此对于word2vec,我们可以不用去停词。因此这里没有进行去停用词操作。

1、读取数据

// An highlighted block
# 读取专利数据
import pandas as pd
import pickle
df_files = pd.read_excel('data/data20093/专利数据8000.xlsx', encoding='utf-8')

2、数据预处理

// An highlighted block
sentence  = list(df_files['标题']) + list(df_files['摘要']) + list(df_files['首项权利要求'])
# 对文本进行分词
import jieba
# 对句子进行分词分词
def segment_sen(sen):
    sen_list = []
    try:
        sen_list = jieba.lcut(sen.replace('\n',' '))
    except:
            pass
    return sen_list 
sens_list = [segment_sen(i) for i in sentance]

结果如下图所示:
在这里插入图片描述

3、模型训练

// import modules & set up logging
import logging
import os
from gensim.models import word2vec

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
// 下面参数详见第一部分gensim word2vec API概述
model = word2vec.Word2Vec(sens_list,size = 300, min_count=5,iter=20)
model.save("model/word2vec.model")

得到这三个模型,即为训练好的word2vec
得到这三个模型

4、效果测试

接下来我们来试一下模型训练的效果
在这里插入图片描述
还是有点道理的,不过那个“公厕”是怎么回事???

3 与Fasttext对比

1 Fasttext简介

gensim 中Fasttext 模型架构和Word2Vec的模型架构差几乎一样,只不过在模型词的输入部分使用了词的n-gram的特征。这里需要讲解一下n-gram特征的含义。举个例子,如果原词是一个很长的词:你吃了吗。jieba分词结果为[“你”,“吃了”,“吗”]。
unigram(1-gram)的特征:[“你”,“吃了”,“吗”]
bigram(2-gram) 的特征: [“你吃了”,“吃了吗”]
所以大家发现没,n-gram的意思将词中连续的n个词连起来组成一个单独的词。
如果使用unigram和bigram的特征,词的特征就会变成:[“你”,“吃了”,“吗”,“你吃了”,“吃了吗”]这么一长串。使用n-gram的词向量使得Fast-text模型可以很好的解决未登录词(OOV——out-of-vocabulary)的问题。

2 Fasttext模型训练

fasttext.FastText API一些重要参数:

size: 表示词向量的维度,默认值是100。
window:决定了目标词会与多远距离的上下文产生关系,默认值是5。
sg: 如果是0, 则是CBOW模型,是1则是Skip-Gram模型,默认是0即CBOW模型。

上方参数和word2vec.Word2Vec API的参数一模一样。

word_ngrams :({1,0}, optional) 1表示使用n-gram的信息,0代表不使用n-gram的信息,如果设置为0就等于CBOW或者Skip-gram。

下方是模型训练代码:

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
model1 = fasttext.FastText(sens_list,min_count=1,iter=20)
model1.save("fast_text.model")

3 两者对比

摘自 https://www.jianshu.com/p/ce630c198762
1)语义相似度
cbow的词向量的语义相似度的判断能力要好于fasttext的词向量。

2)未登录词的处理(OOV)
cbow的词向量模型就无法处理这些没有见过的词。
fasttext可以计算未登录词n-gram词(subword)的词向量的平均值,从而得到未登录词的词向量,最终求得和未登录词比较相似的词。

代码和资料参考了
https://www.cnblogs.com/pinard/p/7278324.html
https://www.jianshu.com/p/ce630c198762
向以上创作者表示感谢
在家没有服务器,使用了百度的AI studio进行代码运行,感谢~
https://aistudio.baidu.com

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!