Word2Vec实践
之前了解过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
来源:CSDN
作者:窗边的小七酱
链接:https://blog.csdn.net/weixin_40064136/article/details/104123486