word2vec原理也很简单,这里简单介绍下,不细讲。
word2vec有两种训练模式:
1.CBOW(Continuous Bag-of-Words Model)
2.Skip-gram (Continuous Skip-gram Model)
其实它们两都是单个隐藏层的模型,然后最后模型训练好后(也是用反向传播更新模型参数)。输入一个词,得到的隐藏层向量就是词嵌入的结果。
1.CBOW
根据上下文来预测当前词:
模型结构图如下:
输入有多个词,一般处理是求和然后取平均。
2.Skip-gram
根据当前词来预测上下文:
模型结构图如下:
⭐Skip-gram里引入了负采样:
训练一个神经网络意味着要输入训练样本并且不断调整神经元的权重,从而不断提高对目标的准确预测。每当神经网络经过一个训练样本的训练,它的权重就会进行一次调整。
正如我们上面所讨论的,vocabulary的大小决定了我们的Skip-Gram神经网络将会拥有大规模的权重矩阵,所有的这些权重需要通过我们数以亿计的训练样本来进行调整,这是非常消耗计算资源的,并且实际中训练起来会非常慢。
负采样(negative sampling)解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。
关于Skip-gram里的负采样讲解可以看这里(讲的很好懂):
(三)通俗易懂理解——Skip-gram的负采样word2vec具体参考以下:
1.[NLP] 秒懂词向量Word2vec的本质 2.图解Word2vec,读这一篇就够了! 3.Word2Vec解释
import nltk
import numpy as np
raw_corpus = ['I love you man, and you?',
'I want to go home',
'I miss you so much',
'The best way to predict the future is to create it!']
#分词等预处理(这里只用分词举个例子),二维列表的形式!!!
process_corpus = [nltk.word_tokenize(t) for t in raw_corpus]
# 调用word2vec模型
# word2vec模型能够计算词向量,用于提取文本特征
from gensim.models.word2vec import Word2Vec
w2v_model = Word2Vec(sentences=process_corpus, size=300, window=5, min_count=0, sg=1, hs=0, iter=10, workers=10)
print(w2v_model['best'].shape) #(300,)
#print(w2v_model.wv.vocab) 该命令可以查看词表
# 将每句话中的所有词进行词向量的相加
# 得到每个文本的词向量
def total_vector(words):
vec = np.zeros(300).reshape((1, 300))
for word in words:
try:
vec += w2v_model[word].reshape((1, 300))
except KeyError: #可能有些词不在词典里那就跳过
continue
return vec
train_vec = np.concatenate([total_vector(words) for words in process_corpus])
print(train_vec.shape) #(4,300)