word2vec词向量化算法

word2vec就是一个将词向量化的工具,这里我们使用的是gensim的word2vec。

1、one-hot编码

在介绍Word2vec之前,我们先来看一下one-hot,它是指词向量维度大小为整个词汇表的大小,对于每个具体的词汇表中的词,将对应的位置置为1。例如:“the cat looks so cute”,该文本包含5个单词,词汇表为{'the','cat','looks','so','cute'},用one-hot来向量化例子文本可表示为:[[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]]。

这种词向量化方式虽然非常简单,但是却存在很多问题:

  • 维度过大。如果词典中包含10000个单词,那么每个文本就要用10000维的向量表示,维度太高会影响计算速度;
  • 无法保留词序信息;
  • 存在语义歧义问题。

2、CBOW和Skip-gram

因为word2vec有两种训练方法,CBOW 和 Skip-gram,这里我们分开介绍。

(1)CBOW 模型

word2vec词向量化算法_第1张图片

CBOW模型的训练是输入某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。这是一个简单的神经网络模型,有输入层、隐藏层和输出层,下面详细描述每一层的输入以及操作:

1)输入层的输入为上下文单词的one-hot,假设词典中有V个词,那么单词向量的维度就是V,C是窗口大小,表示当前词的上下文词个数;

2)输入层到隐藏层之间,我们要定义一个权重矩阵W,维度是V*N,N是自己定义的,这里的W需要初始化,之后将输入的每个单词的one-hot向量乘以权重矩阵,再将所得的向量相加求平均作为隐藏层向量(隐藏层向量是当前词的词向量);

3)隐藏层的数据乘以输出权重矩阵W' (初始化),维度是N*V;

4)得到维度为V*1的概率分布;

然后,求使概率分布的最大似然,可用随机梯度下降算法,至此,得到当前词的词向量和最大概率分布。

(2)Skip-gram模型

Skip-gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量,即后验概率。

word2vec词向量化算法_第2张图片

 其训练过程类似CBOW模型。

3、python实战

这里用到的语料是体育新闻语料,先对语料进行分词、去停用词,再调用gensim的word2vec训练模型。

from gensim.models import word2vec
import jieba
import time
import gensim
#读取数据,句子处理为空格连接的词,一个句子即一行,单词需要预先使用空格分隔
def text_deal():
    text=[]
    with open('./data/p1.txt', 'r', encoding='utf-8') as f:
        stop_words=stop_words_deal()
        for line in f.readlines():
            line=line.strip()
            words=jieba.cut(line)
            filter_words=[' '.join(word for word in words if word not in stop_words)]
            print(filter_words)
            text.append(filter_words)
            #text.append(' '.join(word for word in words if word not in stop_words))
    with open('./data/p1_cut.txt','w',encoding='utf-8') as fw:
        for doc in text:
            for word in doc:
                fw.write(str(word))
            fw.write('\n')

def stop_words_deal():
    stop_words=[]
    for line in open('./data/stop_words.txt',encoding='utf-8').readlines():
        stop_words.append(line.strip())
    #print(stop_words)
    return stop_words
#训练模型
def word2vec_model():
    start = time.clock()
    sentence=word2vec.LineSentence('./data/p1_cut.txt')                   #word2vec提供的LineSentence类来读文件
    model = word2vec.Word2Vec(sentence,sg=0,size=100,window=3,min_count=1,workers=4,hs=1)         #sg表示用CBOW模型训练
    end = time.clock()
    model.save('model_news.word2vec')      #保存模型
    time_spend=end-start
    print('训练模型时间花费:',time_spend,'秒')
    #print(model.wv.vocab)
    model=gensim.models.Word2Vec.load('model_news.word2vec')   #加载模型
    print(model.similarity('体育','篮球'))               #利用模型计算词的相似度
    for i in model.most_similar("体育"):
        print(i[0], i[1])

if __name__ =='__main__':
    text_deal()
    word2vec_model()

4、word2vec计算网页相似度

这里我们的操作是基于已经训练好的词向量模型,基本步骤是:

(1)抽取网页新闻中的关键词。这里我们可以用jieba的analyse抽取关键词,例如:

tfidf=analyse.extract_tags
keywords = tfidf(text)

(2)将抽取到的关键词利用训练好的模型向量化。这里我们要注意判断关键词是否在模型词典中,否则会报错;

model.wv.vectors[model.wv.vocab[word].index] 

(3)将得到的各个词向量相加,得到一个词向量总和代表网页新闻的向量化表示,利用总的向量计算相似度,相似度计算可以用余弦距离计算。

 

你可能感兴趣的:(word2vec词向量化算法)