【手撕算法】【NLP】【Embedding】word2vec原理,代码实现
文章目录
- 1.前言
- 2.简介
- 3.原理
- 3.1.什么是Word Embedding(词嵌入)?
- 3.2.什么是word2vec?
- 3.3.逐步解释word2vec 之 CBOW 模型
- 3.4.逐步解释word2vec 之 Skip-gram 模型
- 4.代码实现
- 5.总结
- 6.参考资料
1.前言
⭐️ 开箱即食,直接复制,懒人传送门: 代码实现
⭐️ 本文主要从原理、代码实现 理论结合实战两个角度来剖析word2vec算法
⭐️ 理论部分主要是关于 什么是 word2vec,其两种常见的模型,
⭐️ 实战部分主要是通过Gensim库中的word2vec模型,实现文本特征提取
⭐️
2.简介
⭐️ word2vec是监督学习算法,其会通过句子中词的前后顺序构建有标签数据集,通过数据集 训练神经网络模型 得到这一数据集的 词向量 表(可以理解成我们的新华字典)。
⭐️ word2vec是用来进行 对词语进行向量化 的模型,也就是对文本类型的数据进行 特征提取
⭐️ word2vec一般为一个3层(输入层、隐藏层、输出层) 的 全连接神经网络。
⭐️ 重点!!! 我们最终需要的是 词向量表,词向量表为我们输入层和隐藏层 或 隐藏层和输出层之间的权重矩阵。
⭐️
3.原理
3.1.什么是Word Embedding(词嵌入)?
⭐️ 词嵌入是自然语言处理中语言模型与表征技术技术的统称。讲人话就是: 就是把词语(字符串类型)这一文本数据转换成 计算机能认识 的数字表征的数据(一般为浮点型数据)。因为我们的机器学习模型或者深度学习模型,需要的数据都是数字类型的,无法处理文本类型的数据,所以我们需要把单词转换成数字类型。
⭐️ 词嵌入为 文本AI系统的上游任务,只有通过词嵌入模型才能得到文本AI系统才能得到数字类型的输入数据。
⭐️ 现有的词嵌入模型有:word2vec,GloVe,ELMo,BERT等
3.2.什么是word2vec?
⭐️ 为什么需要词向量化技术:
不同于计算机视觉任务,计算机视觉任务的输入是一个数字类型的矩阵,也就是其输入是数字类型的数据。而无论是机器学习模
型,还是深度学习模型,其都是需要根据输入的数据来拟合函数,这就要求我们所需要的数据为数字类型了。对于我们的NLP任务,
其输入是非数字类型的。以文本类型举例,其输入是字符串类型,这个时候我们就需要词向量化技术对这些文本进行向量化编码。换句话说,词向量化是机器学习,或者深度学习模型的上游任务!
⭐️ 什么是word2vec?
word2vec是词向量化技术的一种,通过神经网络来实现。其在表面上看起来是一种无监督学习技术,但本质上仍然是有监督学习。
利用文本的上下文信息构造有监督数据集,通过这一数据集来训练神经网络,最后取得训练好的神经网络两个网络层之间的权重
矩阵作为的词向量表(每个单词对应其中一行数据)。
⭐️ word2vec有哪些模型?
word2vec 有两个模型:Skip-gram模型:其特点为,根据当前单词预测上下文单词。
CBOW模型:全称为 Continuous Bag-of-Word,连续词袋模型,该模型的特点是,输入已知的上下文,输出对当前单词的预测。以下两幅图展现了Skip-gram模型和CBOW模型。
3.3.逐步解释word2vec 之 CBOW 模型
⭐️ 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] |
⭐️ 构建 CBOW 训练数据集
我们语料库仍然为:”I drink coffee everyday“,假设我们的预测窗口大小为 2,通过预料库我们可以构建以下训练集,表2
预测词 | 输入词 |
---|---|
I | [drink, coffee] |
drink | [I, coffee, everyday] |
coffee | [I, drink, everyday] |
everyday | [drink, coffee] |
⭐️ 构建 CBOW 神经网络
从上可知,我们的输入层有4个输入单元,输出层神经元的个数应该跟输入层保持一致,输出层也是4个神经元,加入我们想要每个单词为一个五维的向量表示,那么我们的隐藏层则为五个神经元。由此,我们可以构建一个输入层为4,隐藏层为5,输出层为4的全连接神经网络,如下图所示,训练好的模型的权重矩阵w1和w2可以作为我们的词向量化表。
⭐️ 训练 CBOW 神经网络
这时我们可以根据构建的CBOW数据集对模型进行训练了,假设我们要预测的词是coffee,那么由表2可知,我们输入词为[I, drink, everyday],由表1可知,对其进行one-hot编码后的结果为 [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]], 由于模型只能有四个输入,那么我可以对编码好的结果进行映射操作(取平均,求和等),就可以得到一个 1*4 的输入向量,那么我们可以得到如下训练过程。
⭐️ 权重矩阵的应用
经过训练之后,我们拿 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 模型
⭐️ 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] |
⭐️ 构建 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 |
⭐️ 构建 Skip-gram 神经网络
从上可知,我们的输入层有4个输入单元,输出层神经元的个数应该跟输入层保持一致,输出层也是4个神经元,加入我们想要每个单词为一个五维的向量表示,那么我们的隐藏层则为五个神经元。由此,我们可以构建一个输入层为4,隐藏层为5,输出层为4的全连接神经网络,如下图所示,训练好的模型的权重矩阵w1和w2可以作为我们的词向量化表。
⭐️ 训练 CBOW 神经网络
这时我们可以根据构建的Skip-gram数据集对模型进行训练了,假设我们要预测的词是coffee,那么由表2可知,我们输入词为[I, drink, everyday]中的任何一个,由表2可知,对其进行one-hot编码后的结果为 [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]], 我们选择其中一个就可以得到一个 14 的输入向量,那么我们可以得到如下训练过程。
⭐️ 权重矩阵的应用
经过训练之后,我们拿 **W1( 45 权重矩阵) 作为我们的词向量化表,我们可以得到如下词向量化表,表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.代码实现
⭐️ 导入依赖包和定义语料集
from gensim.models import Word2Vec
import logging # 用来设置日志输出
import jieba # 用来中文分词# 构建语料集
context = ["word2vec是监督学习算法,其会通过句子中词的前后顺序构建有标签数据集,通过数据集 训练神经网络模型 得到这一数据集的 词向量 表(可以理解成我们的新华字典)。","word2vec是用来进行 对词语进行向量化 的模型,也就是对文本类型的数据进行 特征提取","word2vec一般为一个3层(输入层、隐藏层、输出层) 的 全连接神经网络。","本文主要从原理、代码实现 理论结合实战两个角度来剖析word2vec算法","理论部分主要是关于 什么是 word2vec,其两种常见的模型","实战部分主要是通过Gensim库中的word2vec模型,实现文本特征提取"]
⭐️ 对语料集进行中文分词
# 对语料集的每一行进行分词,构造成二维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]
⭐️ 训练模型
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)
⭐️ 查看训练好的模型的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}
"""
⭐️ 查看指定token对应的向量
print(model.wv["word2vec"])
# 输出如下
"""
[ 0.07959913 0.04421799 0.07798034 0.00216899 0.06716361 -0.037463910.01138259 0.06484718 -0.09924352 -0.05084702]"""
5.总结
⭐️ word2vec实际上拿到的是输入层和隐藏层之间的权重矩阵,也就token映射表
⭐️ 在使用word2Vec要注意考虑未登录词的问题
6.参考资料
【手撕算法】【NLP】【Embedding】word2vec原理,代码实现相关推荐
- 【手撕算法】AC显著性检测算法
[手撕算法]AC显著性检测算法 算法原理 论文名称: Salient Region Detection and Segmentation AC算法同样是计算每个像素的显著值,但却不是基于全局对比度,而 ...
- word2vec原理+代码
文章目录 参考 word2vec 简单解释 提速方法 Hierarchical Softmax Negative Sampling word2vec提取关键词 word2vec keras 版代码 网 ...
- python常用代码_Python常用算法学习(3)(原理+代码)——最全总结
1,什么是算法的时间和空间复杂度 算法(Algorithm)是指用来操作数据,解决程序问题的一组方法,对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但是在过程中消耗的资源和时间却会有很大 ...
- 手撕深度学习框架,原理很简单
2020国内深度学习框架领域百花齐放.各大公司也都陆续推出了自己的框架,大大推动了深度学习的发展.深度学习俨然已经渗入到我们生活中的每个角落,给生活带来极大便利. 深度学习能够针对生产生活所面临的复杂 ...
- 【手撕算法】FMM图像修复算法C++实现
FMM算法出自Telea的论文 An Image Inpainting Technique Based on the Fast Marching Method opencv的inpaint函数就是采用 ...
- 【手撕算法】HC显著性检测算法
前言 HC算法出自程明明老师的论文: Global Contrast based Salient Region Detection 这个论文一共提到了两种算法,分别是HC与RC. HC仅仅是考虑了颜色 ...
- 递推算法与递推套路(手撕算法篇)
联系我们:有道技术团队助手:ydtech01 / 邮箱:[ydtech@rd.netease.com] 之前学习基础知识的时候也说了,递推和动态规划有这暧昧不清的关系,可以说,动态规划就是多了一个决策 ...
- LeetCode207: 课程表(字节手撕算法拓扑排序)
文章目录 前言 正文 题干 思路 入度表(广度优先遍历) 展示 后记 前言 (与正文无关,赶时间的跳过呀!!!) 前段时间了解到了这个拓扑排序,我感觉很是陌生.一百度,绝了,数据结构都学习过,想当时数 ...
- 面试集锦-------LRU,LFU手撕算法
LRU(最近最久未使用算法) 思路: 这里用到了两个数据结构,一个是list,另一个是unordeed_map 我们的思路也很简单,在map中以key为键,值得话我们取相对应下list存储key的it ...
最新文章
- 不是微型计算机主板上的部件,微型计算机主板上安装的主要部件
- 关于System.InvalidOperationException异常
- 成功解决xlrd.biffh.XLRDError: Unsupported format, or corrupt file: Expected BOF record; found b‘Debug is
- 更改chrome临时目录(可举一反三)
- ASP.NET 2.0 学习笔记 1: session 与 script 应用
- SAP ABAP Platform 1909最新版的 docker 镜像
- 模式识别与机器学习笔记(一)
- BERT 之后的故事
- lingo程序与c语言的区别,lingo与高级语言连接(以C++)为例
- 批处理顺序执行多条命令
- 本工具仅仅交流之用,把黑群晖洗白用,如果对此感兴趣请支持正版,请勿用于违法,作者不承担法律和相关连带责任,工具内有详细sn算号器,可供使用还有教程
- php mysql关键字查询_使用php mysql进行关键字搜索?
- Stata进行logistic回归绘制列线图并做内部验证
- Pandas数据分析第2部分
- 恶意代码分析实战Lab3-1
- 能不能把ASMR做成一门正经生意?
- centos php安装 pecl,pecl是什么?如何在centos下安装pecl?
- Pytorch框架学习记录10——线性层
- NTFS磁盘读写工具Mounty 1.9 Mac免费版
- 分享 | 基于图像分类网络ResNet50_vd实现桃子分类