【手撕算法】【NLP】【Embedding】word2vec原理,代码实现

1.前言

  1. 开箱即食,直接复制,懒人传送门: 第4章:4.代码实现

  2. 本文主要从原理、代码实现 理论结合实战两个角度来剖析word2vec算法

  3. 理论部分主要是关于 什么是 word2vec,其两种常见的模型

  4. 实战部分主要是通过Gensim库中的word2vec模型,实现文本特征提取


2.简介

  1. word2vec是监督学习算法,其会通过句子中词的前后顺序构建有标签数据集,通过数据集 训练神经网络模型 得到这一数据集的 词向量 表(可以理解成我们的新华字典)。

  2. word2vec是用来进行 对词语进行向量化 的模型,也就是对文本类型的数据进行 特征提取

  3. word2vec一般为一个3层(输入层、隐藏层、输出层)全连接神经网络。

  4. 重点!!! 我们最终需要的是 词向量表,词向量表为我们输入层和隐藏层 或 隐藏层和输出层之间的权重矩阵。


3.原理

3.1.什么是Word Embedding(词嵌入)?

  1. 词嵌入是自然语言处理中语言模型表征技术技术的统称。讲人话就是: 就是把词语(字符串类型)这一文本数据转换成 计算机能认识 的数字表征的数据(一般为浮点型数据)。因为我们的机器学习模型或者深度学习模型,需要的数据都是数字类型的,无法处理文本类型的数据,所以我们需要把单词转换成数字类型。

  2. 词嵌入为 文本AI系统的上游任务,只有通过词嵌入模型才能得到文本AI系统才能得到数字类型的输入数据。

  3. 现有的词嵌入模型有:word2vec,GloVe,ELMo,BERT

3.2.什么是word2vec?

  1. 为什么需要词向量化技术
不同于计算机视觉任务,计算机视觉任务的输入是一个数字类型的矩阵,也就是其输入是数字类型的数据。而无论是机器学习模
型,还是深度学习模型,其都是需要根据输入的数据来拟合函数,这就要求我们所需要的数据为数字类型了。对于我们的NLP任务,
其输入是非数字类型的。以文本类型举例,其输入是字符串类型,这个时候我们就需要词向量化技术对这些文本进行向量化编码。

换句话说,词向量化是机器学习,或者深度学习模型的上游任务!
复制代码
  1. 什么是word2vec?
word2vec是词向量化技术的一种,通过神经网络来实现。其在表面上看起来是一种无监督学习技术,但本质上仍然是有监督学习。
利用文本的上下文信息构造有监督数据集,通过这一数据集来训练神经网络,最后取得训练好的神经网络两个网络层之间的权重
矩阵作为的词向量表(每个单词对应其中一行数据)。
复制代码
  1. word2vec有哪些模型?
word2vec 有两个模型:

Skip-gram模型:其特点为,根据当前单词预测上下文单词。
CBOW模型:全称为 Continuous Bag-of-Word,连续词袋模型,该模型的特点是,输入已知的上下文,输出对当前单词的预测。

以下两幅图展现了Skip-gram模型和CBOW模型。
复制代码

image.png

3.3.逐步解释word2vec 之 CBOW 模型

  1. one-hot编码:

One-hot编码又称一位有效编码,是将文字数字化的过程。假如我们有一个语料库:”I drink coffee everyday“。我们对其以” “(空格)进行分词,则我们会得到4个单词,假设这4个单词是我们所有的单词种类(也就是说,我们的字典中只有这四个单词),这样我们对其进行one-hot编码后可以得到如下编码结果: 表1

单词 One-hot编码
I [1, 0, 0, 0]
drink [0, 1, 0, 0]
coffee [0, 0, 1, 0]
everyday [0, 0, 0, 1]
  1. 构建 CBOW 训练数据集

我们语料库仍然为:”I drink coffee everyday“,假设我们的预测窗口大小为 2,通过预料库我们可以构建以下训练集,表2

预测词 输入词
I [drink, coffee]
drink [I, coffee, everyday]
coffee [I, drink, everyday]
everyday [drink, coffee]
  1. 构建 CBOW 神经网络

从上可知,我们的输入层有4个输入单元,输出层神经元的个数应该跟输入层保持一致,输出层也是4个神经元,加入我们想要每个单词为一个五维的向量表示,那么我们的隐藏层则为五个神经元由此,我们可以构建一个输入层为4,隐藏层为5,输出层为4的全连接神经网络,如下图所示,训练好的模型的权重矩阵w1和w2可以作为我们的词向量化表

image.png

  1. 训练 CBOW 神经网络

这时我们可以根据构建的CBOW数据集对模型进行训练了,假设我们要预测的词是coffee,那么由表2可知,我们输入词为[I, drink, everyday],由表1可知,对其进行one-hot编码后的结果为 [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]], 由于模型只能有四个输入,那么我可以对编码好的结果进行映射操作(取平均,求和等),就可以得到一个 1*4 的输入向量,那么我们可以得到如下训练过程。

image.png 5. 权重矩阵的应用 经过训练之后,我们拿 W1( 4*5 权重矩阵) 作为我们的词向量化表,我们可以得到如下词向量化表,表3。假如我们要词向量化”I drink coffee“这句话,我们便可以直接查询表3,拿到我们的词向量矩阵,即为[ [0.11, 0.22, 0.23, 0.25, 0.31], [0.32, 0.22, 0.33, 0.11, 0.32], [0.23, 0.03, 0.62, 0.12, 0.17] ]

单词索引 向量
I [0.11, 0.22, 0.23, 0.25, 0.31]
drink [0.32, 0.22, 0.33, 0.11, 0.32]
coffee [0.23, 0.03, 0.62, 0.12, 0.17]
everyday [0.05, 0.25, 0.55, 0.17, 0.47 ]

3.4.逐步解释word2vec 之 Skip-gram 模型

  1. one-hot编码:

One-hot编码又称一位有效编码,是将文字数字化的过程。假如我们有一个语料库:”I drink coffee everyday“。我们对其以” “(空格)进行分词,则我们会得到4个单词,假设这4个单词是我们所有的单词种类(也就是说,我们的字典中只有这四个单词),这样我们对其进行one-hot编码后可以得到如下编码结果: 表4

单词 One-hot编码
I [1, 0, 0, 0]
drink [0, 1, 0, 0]
coffee [0, 0, 1, 0]
everyday [0, 0, 0, 1]
  1. 构建 Skip-gram 训练数据集

我们语料库仍然为:”I drink coffee everyday“,假设我们的预测窗口大小为 2,通过预料库我们可以构建以下训练集,表2

预测词 输入词
I drink
I coffee
drink I
drink coffee
drink everyday
coffee I
coffee drink
coffee everyday
everyday drink
everyday coffee
  1. 构建 Skip-gram 神经网络

从上可知,我们的输入层有4个输入单元,输出层神经元的个数应该跟输入层保持一致,输出层也是4个神经元,加入我们想要每个单词为一个五维的向量表示,那么我们的隐藏层则为五个神经元由此,我们可以构建一个输入层为4,隐藏层为5,输出层为4的全连接神经网络,如下图所示,训练好的模型的权重矩阵w1和w2可以作为我们的词向量化表

image.png

  1. 训练 CBOW 神经网络

这时我们可以根据构建的Skip-gram数据集对模型进行训练了,假设我们要预测的词是coffee,那么由表2可知,我们输入词为[I, drink, everyday]中的任何一个,由表2可知,对其进行one-hot编码后的结果为 [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]], **我们选择其中一个就可以得到一个 1*4 的输入向量,那么我们可以得到如下训练过程。

image.png

  1. 权重矩阵的应用

经过训练之后,我们拿 W1( 4*5 权重矩阵) 作为我们的词向量化表,我们可以得到如下词向量化表,表3。假如我们要词向量化”I drink coffee“这句话,我们便可以直接查询表3,拿到我们的词向量矩阵,即为[ [0.11, 0.22, 0.23, 0.25, 0.31], [0.32, 0.22, 0.33, 0.11, 0.32], [0.23, 0.03, 0.62, 0.12, 0.17] ]

单词索引 向量
I [0.11, 0.22, 0.23, 0.25, 0.31]
drink [0.32, 0.22, 0.33, 0.11, 0.32]
coffee [0.23, 0.03, 0.62, 0.12, 0.17]
everyday [0.05, 0.25, 0.55, 0.17, 0.47 ]

4.代码实现

  1. 导入依赖包和定义语料集
from gensim.models import Word2Vec
import logging   # 用来设置日志输出
import jieba     # 用来中文分词

# 构建语料集
context = ["word2vec是监督学习算法,其会通过句子中词的前后顺序构建有标签数据集,通过数据集 训练神经网络模型 得到这一数据集的 词向量 表(可以理解成我们的新华字典)。"
            ,"word2vec是用来进行 对词语进行向量化 的模型,也就是对文本类型的数据进行 特征提取"
            ,"word2vec一般为一个3层(输入层、隐藏层、输出层) 的 全连接神经网络。"
            ,"本文主要从原理、代码实现 理论结合实战两个角度来剖析word2vec算法"
            ,"理论部分主要是关于 什么是 word2vec,其两种常见的模型"
            ,"实战部分主要是通过Gensim库中的word2vec模型,实现文本特征提取"]
复制代码
  1. 对语料集进行中文分词
# 对语料集的每一行进行分词,构造成二维list,形如[["Word2Vec", "监督"],["word2vec", "进行"]]
for i in range(len(context)):
    split_s = context[i]
    context[i] = " ".join(jieba.cut(split_s, HMM=True))
context = [e.split(" ") for e in context]
复制代码
  1. 训练模型
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
model = Word2Vec(sentences = context,workers=8, window=4, vector_size=10, epochs=30, min_count=3)
复制代码
  1. 查看训练好的模型的token字典
print(model.wv.key_to_index)
# 输出如下
"""
{'': 0, '的': 1, 'word2vec': 2, '是': 3, ',': 4, '模型': 5, '层': 6, '数据': 7, '主要': 8,
 '通过': 9, '、': 10, '集': 11, '进行': 12, '特征提取': 13, '文本': 14, '神经网络': 15, 
 '算法': 16, '(':  17, ')': 18, '对': 19, '实现': 20, '理论': 21, '部分': 22, '实战': 23, 
 '。': 24, '理解': 25,  '可以': 26, '表': 27, '向量': 28, '成': 29, '词': 30, '其会': 31, 
 '这一': 32, '得到': 33,  '监督': 34, '学习': 35, '我们': 36, '标签': 37, '有': 38, '构建': 39,
  '顺序': 40, '前后': 41,  '中词': 42, '句子': 43, '训练': 44, '库中': 45, '新华字典': 46, 
  '用来': 47, '常见': 48, '两种': 49,  '其': 50, '什么': 51, '关于': 52, '剖析': 53, '来': 54,
   '角度': 55, '两个': 56, '结合': 57,   '代码': 58, '原理': 59, '从': 60, '本文': 61, 
   '连接': 62, '全': 63, '输出': 64, '隐藏': 65,   '输入': 66, '3': 67, '一个': 68, '为': 69,
    '一般': 70, '类型': 71, '就是': 72, '也': 73,   '量化': 74, '向': 75, 'Gensim': 76, 
    '词语': 77}
"""
复制代码
  1. 查看指定token对应的向量
print(model.wv["word2vec"])
# 输出如下
"""
[ 0.07959913  0.04421799  0.07798034  0.00216899  0.06716361 -0.03746391
  0.01138259  0.06484718 -0.09924352 -0.05084702]
 """
复制代码

5.总结

  1. word2vec实际上拿到的是输入层和隐藏层之间的权重矩阵,也就token映射表
  2. 在使用word2Vec要注意考虑未登录词的问题

6.参考资料

  1. 英文文献:word2vec Parameter Learning Explained
  2. 英文文献:Quick Notes: Useful Terms & Concepts in NLP: BOW, POS, Chunking, Word Embedding

猜你喜欢

转载自juejin.im/post/7082767413682372616