第一部分:词嵌入/词向量Embedding
基本含义:
就是一种将高维的数据表示映射到低维空间的方法。
word embedding就是将语言中的词编码成为一个向量,便于后续的分析和处理
第二部分:独热编码one hot
独热编码是一种对分类数据进行编码的方法
独热编码给每种类别分配了一列,属于该类别的该列为1,其他列为0
缺陷分析:
独热编码属于词袋模型,没有考虑到词的顺序
(比如:“我爱你”和“你爱我”是没有办法区分的)
词间正交,很难表示词的意思
大词表导致矩阵稀疏
第三部分:Word2Vec方法(解决one-hot编码的问题)
它主要是由两个子模型组成:
“连续词袋模型”CBOW(主要是用不同的上下文去预测右侧的这个词)+“跳元模型”Skip-gram(用当前的这个词去预测上下文)
这两种模型,能够学习到一个词,在语法和语义两个维度上的知识
一群老师教一个学生:
一个老师教一群学生:
第四部分:负采样(Word2Vec优化方法)
负采样(Negative Sampling)是一种在自然语言处理任务(例如 Word2Vec 训练)中常用的技巧,用于加速训练并提高计算效率,特别是在处理非常大的数据集时。
背景
在训练类似 Word2Vec 这样的词向量模型时,目标是通过模型来预测一个目标词(Target word)在给定一个上下文词(Context word)的条件下的概率。为了实现这个目标,通常会使用 Softmax 函数来计算目标词的概率。
但是,对于大规模的词汇表(例如数十万或数百万个词汇),使用 Softmax 来计算概率的代价非常高。因为每次更新模型参数时都需要对词汇表中的所有词进行计算,计算成本非常高昂。
负采样 提供了一种高效的替代方法,核心思想是:
- 简化目标: 而不是对整个词汇表的所有词都进行概率计算,负采样只对部分样本进行计算。这些样本分为正样本和负样本:
- 正样本:真实存在于上下文中的词(目标词)。
- 负样本:从词汇表中随机抽取的一些词,假设它们不应该在当前上下文中出现。
然后这个时候我们可以按照(假设)抽取负样本,正负样本比例为1:10
计算方式: 使用负采样后,Softmax 计算变得不再必要,通常会使用 Sigmoid 函数来计算正样本和负样本的概率。Sigmoid 函数可以让模型判断某个词是否属于上下文,即输出是一个二分类的概率(0 或 1),从而更适合负采样的结构。
第五部分:霍夫曼树(Word2Vec优化方法)
霍夫曼树(Huffman Tree)是一种基于最优前缀编码的二叉树,广泛用于数据压缩算法中,比如 Huffman 编码。它是将一个字符集中的字符按出现频率的高低进行编码,使得整个编码长度最小,达到高效压缩的目的。
霍夫曼树是一种 二叉树,它通过使用贪心算法来构造。其核心目的是通过为字符集分配不同长度的二进制编码,来最小化整个信息的存储开销。这种编码叫做霍夫曼编码。
- 节点的构造:霍夫曼树是通过将出现频率最低的两个节点合并成一个新的节点,重复此过程直到形成一个根节点,从而得到一棵树。这样可以保证频率越高的字符拥有越短的编码,频率越低的字符编码则越长。
- 叶节点与路径:霍夫曼树的叶节点代表数据集中出现的字符,路径的长短反映了字符的编码长度。通过这样的结构,字符的编码是前缀编码,即不会有任何字符的编码是另一个字符编码的前缀,确保了解码的唯一性。
如何使用霍夫曼树进行分层 Softmax
-
构建霍夫曼树:
- 首先,根据词汇表中各个词出现的频率构建霍夫曼树,词频越高的词离根节点越近,而词频越低的词位于更深的位置。
-
路径选择:
- 每个词可以通过霍夫曼树找到其唯一的编码路径,模型通过计算每个节点上的概率来确定路径的方向。
- 在训练过程中,分层 Softmax 的目标是通过一系列二元分类问题(类似于节点的左/右选择),最终找到目标词的路径,这样可以将 Softmax 的计算复杂度从 O(n) 降低到 O(log n),其中 n 是词汇表的大小。
-
Sigmoid 函数:
- 在路径的每个节点上,分层 Softmax 使用 Sigmoid 函数来计算是否应该走到左子节点或右子节点。
- 这样,整个预测过程就变成了多次简单的二分类问题,而不需要一次性计算整个词汇表的概率。
总结
- 霍夫曼树是一种用于最优编码的二叉树,其特点是通过频率构造树,使得高频元素离根节点更近,从而实现高效编码。
- 在 分层 Softmax 中,霍夫曼树被用来组织词汇,使得频率高的词路径较短,从而通过路径查找的方式大大减少计算复杂度。
- Sigmoid 函数用于沿着霍夫曼树的节点选择方向,使得最终可以找到目标词的位置。
第六部分:Word2Vec代码实现
①导包
#第一部分:导包
from gensim.models.word2vec import Word2Vec
import gensim.downloader
②直接导入word2vec模型
#第二部分:直接导入word2vec模型
#list(gensim.downloader.info()['models'].keys())
word_vectors = gensim.downloader.load('word2vec-google-news-300')
③训练word2vec模型
#第三部分:训练word2vec模型
sentences = [['猫', '吃', '鱼'], ['狗', '吃', '肉']] # 构造数据集
model = Word2Vec(sentences, min_count=1, sg=1) # 训练模型
#表示使用 Skip-Gram 模型来训练词向量,sg=0 则表示使用 CBOW 模型。
model_path = 'demo.model' # 保存到当前目录下
model.save(model_path) # 保存模型
④加载模型设置词向量并查看效果
#第四部分:加载模型设置词向量
model = Word2Vec.load(model_path) # 加载模型
print(model.wv['猫']) # 输出词向量
#获取词语 "猫" 的词向量并打印。这个词向量是一个高维的浮点数数组,用于表示 "猫" 在训练文本语境中的含义
# 它是训练模型后由神经网络学习到的数值表示,通常用于度量词语之间的相似性、相对位置关系等。
④完整pycharm代码实现(需要vpn,不然这个数据加载不出来)
#第一部分:导包
from gensim.models.word2vec import Word2Vec
import gensim.downloader
#第二部分:直接导入word2vec模型
#list(gensim.downloader.info()['models'].keys())
word_vectors = gensim.downloader.load('word2vec-google-news-300')
#第三部分:训练word2vec模型
sentences = [['猫', '吃', '鱼'], ['狗', '吃', '肉']] # 构造数据集
model = Word2Vec(sentences, min_count=1, sg=1) # 训练模型
#表示使用 Skip-Gram 模型来训练词向量,sg=0 则表示使用 CBOW 模型。
model_path = 'demo.model' # 保存到当前目录下
model.save(model_path) # 保存模型
#第四部分:加载模型设置词向量
model = Word2Vec.load(model_path) # 加载模型
print(model.wv['猫']) # 输出词向量
#获取词语 "猫" 的词向量并打印。这个词向量是一个高维的浮点数数组,用于表示 "猫" 在训练文本语境中的含义
# 它是训练模型后由神经网络学习到的数值表示,通常用于度量词语之间的相似性、相对位置关系等。