Transformer——词向量

词向量

在自然语言处理任务中,模型的输入大多为单个字或者词。但是字词都是自然语言的表述,对于以二进制为处理语言的计算机来说,其并不认识这个字词。所以需要将字词转换为计算机认识的数据

转换的方法有很多,我们接下来将介绍其中最简单的一种:独热编码,这是一种将字词转换为计算机可以识别的数字向量的方式。

注:为什么不可以使用Unicode编码?其不也是唯一的吗?
Unicode编码是表示单个字的编码方式,但是在预模型中,很多词向量表示的是一个词,比如:“我” “有” “一只” “猫”
其中“一只”是一个词,其如果用Unicode编码表示,其长度维度和其他字词不一致。

One-Hot 独热编码

独热编码是一种将离散型(可以划分为n个类别)的数据转化为计算机能够理解的方式,其基本思想是在 n n n维向量空间中,使用 n n n个单位向量,每个单位向量代表一个类别。也就是说,如果我们有 n n n个类别,那么我们就会有一个长度为 n n n的向量,其中有一个元素为1,其余元素为0。这个1的位置就代表了这个类别在向量中的位置。

下面是“我” “有” “一只” “猫”的独热编码表示:

词语一只
1000
0100
一只0010
0001

独热编码虽然可以表示一个字词,但是假如说我的词库非常大。为了让每一个字词都在其中有着唯一的表示,我每个字词的表示就都是 n n n维的,这会带来极大的存储成本。同时,在独热编码中,每个单词都是由一个完全不同的向量表示的。这意味着相似的单词,其向量表示完全不同。这就导致我们在计算独热编码两两的相似度时,得到的欧氏距离都是相同的。

注1:词库:
也称为词汇表或字典,是用于自然语言处理(NLP)的基本工具之一。它是一个包含所有可能单词的集合,每个单词都有一个与之对应的索引。

注2:总结:独热编码在高纬度计算语义信息表示上面有缺陷。

为了解决这个问题,我们需要引入一个新概念:词向量

词向量

词向量是一种用来表示单词的向量,它比独热编码更高级。词向量的长度通常比词库的大小要小得多,例如,我们可以用一个200维的向量来表示所有的单词,而不是使用一个100,000维的向量。此外,词向量可以捕捉到单词之间的语义关系,例如,“猫”和“狗”的词向量可能在向量空间中非常接近。

注:词向量的语义关系捕获
在自然语言处理(NLP)中,常见的词向量训练方法有Word2Vec、GloVe和FastText等。

  • 在Word2Vec算法中,它通过学习预测上下文,使得语义相近的词在向量空间中靠得更近。
  • GloVe算法则是通过利用全局统计信息(即词共现矩阵)来生成词向量。这种方法可以捕获到更丰富的词语共现信息,因此可以更好地表达词与词之间的关系。
  • FastText算法则是通过考虑词的上下文信息以及词内部的字母级信息,从而更好地处理形态丰富的语言,以及处理词典中没有的词。

词向量是独热编码的一种改进和优化,其可以由独热编码 w x w_x wx乘以权重矩阵 Q Q Q得到,公式如下:
w x ∗ Q = c x ( 词向量 ) w_x*Q=c_x(词向量) wxQ=cx(词向量)
上面的例子,可能会得到如下的词向量表示:

词语维度1维度2维度3
0.10.30.2
0.20.40.1
一只0.40.10.3
0.30.20.4

注:权重矩阵Q
权重矩阵Q是通过模型训练过程中的优化算法得到的。 以深度学习模型为例,权重矩阵Q是模型中的参数,通过反向传播和梯度下降等优化算法,不断调整这些权重,使得模型在训练数据上的预测误差最小。

word2vec

Word2Vec是Google于2013年提出的一种用于生成词向量的两层神经网络模型。它的目标是根据给定的语境预测单词或根据单词预测语境。其主要用CBOW(Continuous Bag of Words)Skip-Gram模型来做预测语境。

  • Skip-Gram:输入是一个词,输出是该词周围的一些词。模型的目标是最大化给定单词的情况下,其上下文词出现的概率。适用于处理大型语料库,因为它对罕见词的处理效果比较好。
  • CBOW:和Skip-Gram模型刚好相反,输入是某个词的上下文,输出是这个词。模型的目标是最大化给定上下文的情况下,中心词出现的概率。这种模型训练速度更快,但对罕见词的处理效果不如Skip-Gram。

假设我们有一个句子:“我有一只猫”,我们使用Skip-Gram模型,并设定窗口大小为2,那么对于每个词,我们都会考虑它前后各两个词。
以词"一只"为例,它前面两个词是"我"和"有",后面两个词是"猫"。那么,我们的训练样本就是(“一只”,“我”),(“一只”,“有”),(“一只”,“猫”)。在训练过程中,我们的模型需要学习到这样的信息:当"一只"出现的时候,“我”,"有"和"猫"是可能出现在它周围的词。

from gensim.models import Word2Vec

# 训练文本
sentences = [["我", "有", "一只", "猫"]]

# 训练模型
model = Word2Vec(sentences, min_count=1, window=2)

# 打印"一只"的词向量
print(model.wv["一只"])

注:我们的例子只有一个很短的句子,在实际应用中,Word2Vec通常需要在大量文本数据上进行训练,才能得到有用的词向量。

词向量的局限性

词向量虽然能够捕获词与词间的语义关系,但也存在一些局限性。例如,传统的词向量模型无法处理一词多义的问题,因为它们都是为每个词分配一个固定的向量。然而,最新的预训练模型(如BERT、GPT等)通过引入动态词向量的概念,成功解决了这个问题。在这些模型中,一个词的向量表示会随着其上下文的变化而变化,从而能够捕获到词的多义性。

参考

  1. chat-gpt4
  2. 预训练语言模型的前世今生