大家好,又见面了,我是你们的朋友全栈君。
目录
一、为什么需要Word Embedding
二、Word2vec原理
1、CBOW模型
2、Skip-gram模型
三、行业上已有的预训练词向量
四、用Python训练自己的Word2vec词向量
一、为什么需要Word Embedding
在NLP(自然语言处理)里面,最细粒度的是词语,词语组成句子,句子再组成段落、篇章、文档。所以要处理 NLP 的问题,首先就要拿词语开刀。
举个简单例子,判断一个词语的情感,是积极还是消极。用机器学习的思路,我们有一系列样本(x,y),这里 x 是词语,y 是它们的情感类别,我们要构建 f(x)->y 的映射,但这里的数学模型 f(比如神经网络、SVM)只接受数值型输入,而 NLP 里的词语,是人类的抽象总结,是符号形式的(比如中文、英文、拉丁文等等),所以需要把他们转换成数值形式,或者说——嵌入到一个数学空间里,这种嵌入方式,就叫词嵌入(word embedding),而 Word2vec ,就是词嵌入( word embedding) 的一种。
也就是说,我们要怎么把一堆计算机不认识的词语表示成它认识的,从而继续为我们人类服务,达到人类的目的?这个途径就是词嵌入(word embedding):把人类理解的词语表示成在数学空间里的“词语”,这个数学空间里的“词语”能够帮助计算机去理解我们人类的语义,也就是说,知道哪些词的意思是相近的,等等,这体现在数学空间里的距离和概率等的概念上。
以上我们理解了在NLP领域word embedding的理由和重要性。
二、Word2vec原理
- Wordvec的目标是:将一个词表示成一个向量
- Word2vec中两个重要模型是:CBOW和Skip-gram模型
1、CBOW模型
- 如果是拿一个词语的上下文作为输入,来预测这个词语本身,则是 『CBOW 模型』
注意:在Hidden layer(隐藏层神经元)上没有激活功能,所以有些文章上的图示中没有标示出hidden layer,而是直接就到输出层,或者是将hidden layer称作为投影层,为什么呢,因为这个所谓的隐层的激活函数其实是线性的,所以有的人就不叫它隐藏层了,我后面就称它为投影层吧。后面的输出神经元使用softmax激活函数。
上图中我们可以理解为C个输入单词的维度是V维(可以理解为词库中共有V个词,那么V维onehot向量就可以唯一的表示这个词语),当语料库中的单词数量很多的时候,V值会超级大。
上面我们说到CBOW模型是拿一个词语的上下文作为输入,来预测这个词语本身(中心词周围的多个词来预测这个中心词),那么对应到上图中,输入就是有x1k、xCk、…、xck这些上下文词语共C个,每一个的长度是V,输出就是 y 这个中心词1个,长度也是V。在这个网络中我们的目的不是跟一般的神经网络一样去预测标签,而是想要得到完美的参数:权重,X和这个权重相乘能够唯一的表示这个词语,同时需要提到一点的是,这个词向量的维度(与隐含层节点数一致)一般情况下要远远小于词语总数 V 的大小,所以 Word2vec 本质上是一种降维操作。
Xin Rong 的论文《word2vec Parameter Learning Explained》中对Word2vec的理论完备由浅入深非常好懂,且直击要害,既有 high-level 的 intuition 的解释,也有细节的推导过程。
2、Skip-gram模型
如果是用一个词语作为输入,来预测它周围的上下文,那这个模型叫做『Skip-gram 模型』。分析与上面同理,论文里也有直观的说明。
三、行业上已有的预训练词向量
腾讯AI实验室:该语料库为超过800万个中文单词和短语提供了200维矢量表示,即嵌入,这些单词和短语是在大规模高质量数据上预先训练的。这些向量捕获中文单词和短语的语义含义,可以广泛应用于许多下游中文处理任务(例如,命名实体识别和文本分类)以及进一步的研究中。
四、用Python训练自己的Word2vec词向量
在python的第三方库gensim中有自带的Word2Vec函数来训练自己语料库的词向量,我的语料库数据存在sentence.txt文件中,每行为一句话,是经过分词和去停用词之后的数据,sg=1,是采用skip-gram来训练的意思。
代码语言:javascript复制from gensim.models.word2vec import Word2Vec
# 读取数据,用gensim中的word2vec训练词向量
file = open('sentence.txt')
sss=[]
while True:
ss=file.readline().replace('n','').rstrip()
if ss=='':
break
s1=ss.split(" ")
sss.append(s1)
file.close()
model = Word2Vec(size=200, workers=5,sg=1) # 生成词向量为200维,考虑上下5个单词共10个单词,采用sg=1的方法也就是skip-gram
model.build_vocab(sss)
model.train(sss,total_examples = model.corpus_count,epochs = model.iter)
model.save('./data/gensim_w2v_sg0_model') # 保存模型
new_model = gensim.models.Word2Vec.load('w2v_model') # 调用模型
sim_words = new_model.most_similar(positive=['女人'])
for word,similarity in sim_words:
print(word,similarity) # 输出’女人‘相近的词语和概率
print(model['女孩']) # 输出’女孩‘的词向量
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/145333.html原文链接:https://javaforall.cn