深度学习之自然语言处理

第一部分:词嵌入/词向量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. 简化目标: 而不是对整个词汇表的所有词都进行概率计算,负采样只对部分样本进行计算。这些样本分为正样本负样本
    • 正样本:真实存在于上下文中的词(目标词)。
    • 负样本:从词汇表中随机抽取的一些词,假设它们不应该在当前上下文中出现。

然后这个时候我们可以按照(假设)抽取负样本,正负样本比例为1:10

计算方式: 使用负采样后,Softmax 计算变得不再必要,通常会使用 Sigmoid 函数来计算正样本和负样本的概率。Sigmoid 函数可以让模型判断某个词是否属于上下文,即输出是一个二分类的概率(0 或 1),从而更适合负采样的结构。

第五部分:霍夫曼树(Word2Vec优化方法)

霍夫曼树(Huffman Tree)是一种基于最优前缀编码的二叉树,广泛用于数据压缩算法中,比如 Huffman 编码。它是将一个字符集中的字符按出现频率的高低进行编码,使得整个编码长度最小,达到高效压缩的目的。

霍夫曼树是一种 二叉树,它通过使用贪心算法来构造。其核心目的是通过为字符集分配不同长度的二进制编码,来最小化整个信息的存储开销。这种编码叫做霍夫曼编码

  • 节点的构造:霍夫曼树是通过将出现频率最低的两个节点合并成一个新的节点,重复此过程直到形成一个根节点,从而得到一棵树。这样可以保证频率越高的字符拥有越短的编码,频率越低的字符编码则越长。
  • 叶节点与路径:霍夫曼树的叶节点代表数据集中出现的字符,路径的长短反映了字符的编码长度。通过这样的结构,字符的编码是前缀编码,即不会有任何字符的编码是另一个字符编码的前缀,确保了解码的唯一性。
如何使用霍夫曼树进行分层 Softmax
  1. 构建霍夫曼树

    • 首先,根据词汇表中各个词出现的频率构建霍夫曼树,词频越高的词离根节点越近,而词频越低的词位于更深的位置。
  2. 路径选择

    • 每个词可以通过霍夫曼树找到其唯一的编码路径,模型通过计算每个节点上的概率来确定路径的方向。
    • 在训练过程中,分层 Softmax 的目标是通过一系列二元分类问题(类似于节点的左/右选择),最终找到目标词的路径,这样可以将 Softmax 的计算复杂度从 O(n) 降低到 O(log n),其中 n 是词汇表的大小。
  3. 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['猫'])  # 输出词向量
#获取词语 "猫" 的词向量并打印。这个词向量是一个高维的浮点数数组,用于表示 "猫" 在训练文本语境中的含义
# 它是训练模型后由神经网络学习到的数值表示,通常用于度量词语之间的相似性、相对位置关系等。

猜你喜欢

转载自blog.csdn.net/weixin_74009895/article/details/143257487