word2vec词向量通俗化解释:

word2vec(word to vector)是一个将单词转换成向量形式的工具。

作用:

word2vec适合用作序列数据的分类,聚类和相似度计算。有用作app下载推荐系统中的,也有用在推荐系统和广告系统上的,也可以用在机器人对话类别判决系统上。

算法:

首先这是一个逻辑回归(分类)问题,使用最大似然估计。 在已知历史单词,要最大化下一个单词出现的概率,使用softmax函数做分类,则问题的数学描述如下: 

这里计算上下文是时单词是的概率,显然上面的除法和指数计算是比较耗时,那么能否进行简化,答案就是取对数,将目标函数转换如下

word2vec训练中文词向量 word2vec 词向量_word2vec

假设我们的上下文是基于两个单词的,则根据the cat sits on the mat,将得到如下的训练样本:

word2vec训练中文词向量 word2vec 词向量_word2vec训练中文词向量_02

上面只罗列了CBOW下的样本集。神经网络的结构如下:

word2vec训练中文词向量 word2vec 词向量_word2vec_03

输入层:

上述过程可以描述如下: 
1.首先将所有的单词做one-hot映射,这把每一个单词映射到权重矩阵的一行,这每一行对应于该单词的特征向量,

word2vec训练中文词向量 word2vec 词向量_word2vec_04

这里左侧竖条是权重矩阵,对应于上图神经网络的权重 
2.右侧蓝色方框的每一行都是一个单词的特征,把上图hidden layer linear neurons旋转90°就是其表示。 
这里已经说明了如何从单词映射到特征向量。

输出层:

输入层使用softmax逻辑回归进行分类。 
1.输出层输出的值累加和等于1,每一个神经元的值介于0~1 
2.从单词特征向量和输出权重矩阵相乘得到softmax输出,由于输入特征向量是300维的,softmax输出预测的单词数量是和输入一致的,那么可以得出输出权重矩阵将是300*10000维的,这一过程如下: 

word2vec训练中文词向量 word2vec 词向量_权重_05

 

 

实践

  • 1.数据下载

     wiki英文数据下载:https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2

     wiki中文数据下载:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2

  • 2.数据处理

1.抽取文本        wiki数据内容比较复杂,所以在处理之前需要做一些预处理。通过 process_wiki.py 将wiki数据中的每一篇文章转为1行文本。

代码如下:

#--*-- coding:utf-8 --*--
 
from __future__ import print_function
 
import logging
import os.path
import six
import sys
 
from gensim.corpora import WikiCorpus
#import WikiCorpus
 
if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)
 
    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))
 
    # check and process input arguments
    if len(sys.argv) != 3:
        print("Using: python process_wiki.py enwiki.xxx.xml.bz2 wiki.en.text")
        sys.exit(1)
    inp, outp = sys.argv[1:3]
    space = " "
    i = 0
 
    output = open(outp, 'w')
    wiki = WikiCorpus(inp, lemmatize=False, dictionary={})
    for text in wiki.get_texts():
        if six.PY3:
            output.write(bytes(' '.join(text), 'utf-8').decode('utf-8') + '\n')
        #   ###another method###
        #    output.write(
        #            space.join(map(lambda x:x.decode("utf-8"), text)) + '\n')
        else:
            output.write(space.join(text) + "\n")
        i = i + 1
        if (i % 10000 == 0):
            logger.info("Saved " + str(i) + " articles")
 
    output.close()
logger.info("Finished Saved " + str(i) + " articles")

2.训练词向量

    训练word2vec的开源代码非常多,使用的语言种类也很丰富,本实验使用gensim包训练词向量,其特点使用简便,训练速度快。

代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from __future__ import print_function
#导入日志配置
import logging
import os
import sys
import multiprocessing
#引入word2vec
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
 
if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)
 
    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))
 
    # check and process input arguments
    if len(sys.argv) < 4:
        print("Useing: python train_word2vec_model.py input_text "
              "output_gensim_model output_word_vector")
        sys.exit(1)
    inp, outp1, outp2 = sys.argv[1:4]
 
    model = Word2Vec(LineSentence(inp), size=128, window=5, min_count=5,
                     workers=multiprocessing.cpu_count())
 
    model.save(outp1)
    model.wv.save_word2vec_format(outp2, binary=False)

3.测试词向量

代码如下:

import gensim    #导入包
model = gensim.models.KeyedVectors.load_word2vec_format("wiki.en.text.vector", binary=False)
model.most_similar('queen')    #测试相关词
model.similarity("woman", "man")    #测试次间距

Word2Vec 参数:

  • min_count
model = Word2Vec(sentences, min_count=10) # default value is 5

在不同大小的语料集中,我们对于基准词频的需求也是不一样的。譬如在较大的语料集中,我们希望忽略那些只出现过一两次的单词,这里我们就可以通过设置min_count参数进行控制。一般而言,合理的参数值会设置在0~100之间。

  • size

size 是词向量维度

model = Word2Vec(sentences, size=200) # default value is 100
  • workers

workers参数用于设置并发训练时候的线程数,不过仅当Cython安装的情况下才会起作用:

model = Word2Vec(sentences, workers=4) # default = 1 worker = no parallelization