word2vec-词向量embeding实现

 一 word2vec现有三种模型框架:
eg求大家 喜欢 吃 (苹果)的概率
(1)计算后验概率:
p(大家)表示“大家”这个词在语料库里面出现的概率;
p(喜欢|大家)表示“喜欢”这个词出现在“大家”后面的概率;
p(吃|大家,喜欢)表示“吃”这个词出现在“大家喜欢”后面的概率;
p(苹果|大家,喜欢,吃)表示“苹果”这个词出现在“大家喜欢吃”后面的概率。
(2)所以,最终P(大家,喜欢,吃,苹果)为:
P(大家,喜欢,吃,苹果)=p(大家)p(喜欢|大家)p(吃|大家,喜欢)p(苹果|大家,喜欢,吃)
 
2 CBOW(bag of word)词袋:1one_hot编码(统计每个词频率,编号大频序号小),2向量化(维度M),3预测求和softmax,目标函数是预测结果和真实结果的交叉熵。
网络结构图如下所示:
 
3 Skip—Gram模型:根据单词计算上下文的概率(逆向思维)
CBOW和Skip—Gram模型都是考虑到语境上下文的。
 
 
二 word2vec的实现trick
作者的还用到了一些其他的trick,比如每个句子都做采样,根据词频随机删掉一些单词,上下文窗口的大小是随机的。
 距离:1欧式距离 2余弦距离 (numpy快速实现)
 
三 编程code
 
1)paddle网络搭建如下:
 
import math
import paddle.v2 as paddle
 
embsize = 32 # 词向量维度
hiddensize = 256 # 隐层维度
N = 5 # 训练5-Gram
 
def wordemb(inlayer):
    wordemb = paddle.layer.table_projection(
        input=inlayer,
        size=embsize,
        param_attr=paddle.attr.Param(
            name="_proj",
            initial_std=0.001,
            learning_rate=1,
            l2_rate=0,
            sparse_update=True))
    return wordemb
 
paddle.init(use_gpu=False, trainer_count=3) # 初始化PaddlePaddle
word_dict = paddle.dataset.imikolov.build_dict()
dict_size = len(word_dict)
 
# 每个输入层都接受整形数据,这些数据的范围是[0, dict_size)
firstword = paddle.layer.data(
    name="firstw", type=paddle.data_type.integer_value(dict_size))
secondword = paddle.layer.data(
    name="secondw", type=paddle.data_type.integer_value(dict_size))
thirdword = paddle.layer.data(
    name="thirdw", type=paddle.data_type.integer_value(dict_size))
fourthword = paddle.layer.data(
    name="fourthw", type=paddle.data_type.integer_value(dict_size))
nextword = paddle.layer.data(
    name="fifthw", type=paddle.data_type.integer_value(dict_size))
 
Efirst = wordemb(firstword)
Esecond = wordemb(secondword)
Ethird = wordemb(thirdword)
Efourth = wordemb(fourthword)
 
contextemb = paddle.layer.concat(input=[Efirst, Esecond, Ethird, Efourth])
 
hidden1 = paddle.layer.fc(input=contextemb,
                          size=hiddensize,
                          act=paddle.activation.Sigmoid(),
                          layer_attr=paddle.attr.Extra(drop_rate=0.5),
                          bias_attr=paddle.attr.Param(learning_rate=2),
                          param_attr=paddle.attr.Param(
                                initial_std=1. / math.sqrt(embsize * 8),
                                learning_rate=1))
 
predictword = paddle.layer.fc(input=hidden1,
                              size=dict_size,
                              bias_attr=paddle.attr.Param(learning_rate=2),
                              act=paddle.activation.Softmax())
 
cost = paddle.layer.classification_cost(input=predictword, label=nextword)
 
parameters = paddle.parameters.create(cost)
adagrad = paddle.optimizer.AdaGrad(
    learning_rate=3e-3,
    regularization=paddle.optimizer.L2Regularization(8e-4))
trainer = paddle.trainer.SGD(cost, parameters, adagrad)
 
import gzip
 
def event_handler(event):
    if isinstance(event, paddle.event.EndIteration):
        if event.batch_id % 100 == 0:
            print "Pass %d, Batch %d, Cost %f, %s" % (
                event.pass_id, event.batch_id, event.cost, event.metrics)
 
    if isinstance(event, paddle.event.EndPass):
        result = trainer.test(
                    paddle.batch(
                        paddle.dataset.imikolov.test(word_dict, N), 32))
        print "Pass %d, Testing metrics %s" % (event.pass_id, result.metrics)
        with gzip.open("model_%d.tar.gz"%event.pass_id, 'w') as f:
            parameters.to_tar(f)
 
trainer.train(
    paddle.batch(paddle.dataset.imikolov.train(word_dict, N), 32),
    num_passes=100,
    event_handler=event_handler)
训练过程截图:
 
2)对词编码成向量后对应用如下
输出apple的单词编码:
embeddings = parameters.get("_proj").reshape(len(word_dict), embsize)
print embeddings[word_dict['apple’]]
 

 

 

运行结果:
计算两个词的相似度:
from scipy import spatial
emb_1 = embeddings[word_dict['world']]
emb_2 = embeddings[word_dict['would']]
print spatial.distance.cosine(emb_1, emb_2)
 
运行结果:
0.99375076448
 
 
升级篇:一种是Hierarchical Softmax,另一种是Negative Sampling  http://www.cnblogs.com/Determined22/p/5807362.html
posted @ 2017-07-26 17:15  rongyux  阅读(3842)  评论(0编辑  收藏  举报