02-Word Representation

在本章的其余部分中,我们从独热表示开始。此外,我们还详细介绍了分布式词表示模型,包括布朗集群、潜在语义分析、Word2vec和GloVe。然后介绍了两个典型的词表示评价任务。最后,我们讨论了单词表示模型的各种扩展。

2.2 独热编码

本质上,独热表示将每个单词映射到词汇表的索引,这对于存储和计算非常有效。然而,它并不包含丰富的单词的语义和句法信息。因此,一热表示不能捕捉到单词之间的相关性。猫和狗的区别就像猫和床的一个热门词表示的区别一样。此外,一个热门的单词表示将每个单词嵌入到一个|V|维向量中,这只能适用于一个固定的词汇量。因此,在现实世界中处理新词是不灵活的。

2.3 Distributed Word Representation

2.3.1 Brown Cluster

布朗聚类将单词分为几个具有相似语义意义的聚类。其中,Brown聚类从一个大规模的语料库中学习一个二叉树,其中树的叶子表示单词,树的内部节点表示单词的层次聚类。这是一种硬聚类方法,因为每个单词只属于一个组。

用布朗聚类来聚类单词的想法来自于n-gram语言模型。用一个语言模型来评估一个句子出现的概率。例如,句子have a nice day应该比随机的单词序列有更高的概率。使用k-gram语言模型,一个句子的s = {w1,w2,w3,…,wn}的概率可以表示为:

P ( s ) = ∏ i = 1 n P ( w i ∣ w i − k i − 1 ) . P(s)=\prod_{i=1}^nP(w_i|\mathbf{w}_{i-k}^{i-1}). P(s)=i=1nP(wiwiki1).

从一个大的语料库中估计 P ( w i ∣ w i − k i − 1 ) P\left(w_{i}|\mathbf{w}_{i-k}^{i-1}\right) P(wiwiki1)很容易,但是模型具有 ∣ V ∣ k − 1 |V|^k−1 Vk1独立参数,这在20世纪90年代对计算机来说是一个巨大的数字。即使k是2,参数的数量也是相当大的。此外,对罕见的单词的估计是不准确的。为了解决这些问题,[9]提出将单词分组为集群,并训练集群级的n-gram语言模型,而不是单词级的模型。通过为每个单词分配一个簇,这个概率可以被写成

P ( s ) = ∏ i = 1 n P ( c i ∣ c i − k i − 1 ) P ( w i ∣ c i ) , P(s)=\prod_{i=1}^nP(c_i|\mathbf{c}_{i-k}^{i-1})P(w_i|c_i), P(s)=i=1nP(ciciki1)P(wici),

其中ci是wi的对应簇。在集群级语言模型中,只有 ∣ C k ∣ − 1 + ∣ V ∣ − ∣ C ∣ |C^k|−1+|V|−|C| Ck1+VC独立参数,其中C是集群集,通常比词汇表|V|要小得多。

2.3.2 Latent Semantic Analysis(LSA)

潜在语义分析(LSA)是一类基于向量空间模型的策略,它可以更好地捕获单词的语义。LSA旨在通过矩阵分解来探索词和文档的潜在因素,以提高词相似性的估计。参考[14]对单词-文档矩阵应用奇异值分解(SVD),并利用单词和文档的不相关因素。字文档矩阵M的支持向量值得到三个矩阵E、Σ和D

M = E Σ D ⊤ , \mathbf{M}=\mathbf{E}\Sigma\mathbf{D}^\top, M=EΣD,

其中Σ为M奇异值的对角矩阵,矩阵E中的每行向量wi对应word wi,矩阵D中的每行向量di对应文档di。那么,两个单词之间的相似性就可以是

sin ⁡ ( w i , w j ) = M i , ⋮ M j , : ⊤ = w i Σ 2 w j . \sin(w_i,w_j)=\mathbf{M}_{i,\vdots}\mathbf{M}_{j,:}^{\top}=\mathbf{w}_i\Sigma^2\mathbf{w}_j. sin(wi,wj)=Mi,Mj,:=wiΣ2wj.

在这里,Σ中包含的奇异值k的数量是一个需要进行调整的超参数。通过使用合理数量的最大奇异值,LSA可以在单词-文档矩阵中捕获许多有用的信息,并提供平滑效果,防止较大的方差。

LSA工作原理
潜语义分析(Latent Semantic Analysis)来源于信息检索(IR)中的一个问题:如何从搜索query中找到相关的文档。有的人说可以用关键词匹配文档,匹配上的就放在搜索结果前面。这明显是有问题滴,一是背景里我们讲过一词多义和同义词问题,二则10亿+的文档采用关键词匹配,实在不现实。

其实呀,在搜索中我们实际想要去比较的不是词,而是隐藏在词之后的意义和概念,用人话说:query搜索的结果文档隐含的概念要和query的概念尽可能的相近。LSA分析试图去解决这个问题,它把词和文档都映射到一个”概念”空间并在这个空间内进行比较(注:也就是一种降维技术)。

当文档的作者写作的时候,对于词语有着非常宽泛的选择。不同的作者对于词语的选择有着不同的偏好,这样会导致概念的混淆。这种对于词语的随机选择在 词-概念 的关系中引入了噪音。LSA滤除了这样的一些噪音,并且还能够从全部的文档中找到最小的概念集合(为什么是最小?)。

为了让这个难题更好解决,LSA引入一些重要的简化:

  • 文档被用BOW( bags of words : 词袋 )表示,因此词在文档中出现的位置并不重要,只有一个词的出现次数。
  • 概念被表示成经常出现在一起的一些词的某种模式。有点想KNN的思想,文档中概念A相关的词出现次数最多,就把这个文档映射到概念A。例如:4k屏幕、8核CPU 、4G RAM ……经常出现在手机广告文档中。
  • 词被认为只有一个意思。但是这可以使得问题变得更加容易。(这个简化会有怎样的缺陷呢?)
2.3.3 word2vec2

谷歌的word2vec2工具包于2013年发布。它可以有效地从一个大型语料库中学习单词向量。该工具包有两种模型,包括连续的单词包(CBOW)和跳过克包。基于一个单词的含义可以从其上下文中学习的假设,CBOW优化了嵌入,以便它们能够预测给定其上下文单词的目标单词。相反,Skip-gram学习了可以预测给定目标单词的上下文单词的嵌入。在本节中,我们将详细介绍这两个模型。

2.3.3.1 Continuous Bag-of-Words

CBOW预测了给定一个上下文窗口的中心词。图2.1显示了一个由5个单词组成的窗口组成的CBOW的概念。在形式上,CBOW根据其上下文预测wi为:

P ( w i ∣ w j ( ∣ j − i ∣ ≤ l , j ≠ i ) ) = Softmax ( M ( ∑ ∣ j − i ∣ ≤ l , j ≠ i w j ) ) , ( 2.15 ) P(w_i|w_{j(|j-i|\leq l,j\neq i)})=\text{Softmax}\left(\text{M}\left(\sum_{|j-i|\leq l,j\neq i}\mathbf{w}_j\right)\right),\quad(2.15) P(wiwj(jil,j=i))=Softmax(M(jil,j=iwj)),(2.15)

其中 P ( w i ∣ w j ( ∣ j − i ∣ ≤ l , j ≠ i ) ) P(w_i|w_{j(|j-i|\leq l,j\neq i)}) P(wiwj(jil,j=i))是给定其上下文的word wi的概率, l l l是训练上下文的大小,M是 R ∣ V ∣ × m R^{|V|×m} RV×m中的权重矩阵,V表示词汇,m是单词向量的维度。

CBOW模型通过最小化负对数概率的和来进行优化: L = − ∑ i log ⁡ P ( w i ∣ w j ( ∣ j − i ∣ ≤ l , j ≠ i ) ) . \mathscr{L}=-\sum_i\log P(w_i|w_{j(|j-i|\leq l,j\neq i)}). L=ilogP(wiwj(jil,j=i)).

image-20230905201938479

CBOW模型包含三层:输入层,投影层,输出层。与NNML相比,去掉了隐藏层。

CBOW是根据上下文预测中心词,有点类似于完形填空。上下文的多少是个超参数,可以自己调整。

在构建数据集时,根据CBOW的特点,一般是将上下文当作输入,中心词当作标签。

下面为示例代码:

import torch
from torch import nn, optim
from torch.autograd import Variable
import torch.nn.functional as F

CONTEXT_SIZE = 2
raw_text = "We are about to study the idea of a computational process. Computational processes are abstract beings that inhabit computers. As they evolve, processes manipulate other abstract things called data. The evolution of a process is directed by a pattern of rules called a program. People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells.".split(' ')

vocab = set(raw_text)
word_to_idx = {word: i for i, word in enumerate(vocab)}

data = []
for i in range(CONTEXT_SIZE, len(raw_text)-CONTEXT_SIZE):
    context = [raw_text[i-2], raw_text[i-1], raw_text[i+1], raw_text[i+2]]
    target = raw_text[i]
    data.append((context, target))

class CBOW(nn.Module):
    def __init__(self, n_word, n_dim, context_size):
        super(CBOW, self).__init__()
        self.embedding = nn.Embedding(n_word, n_dim)
        self.linear1 = nn.Linear(2*context_size*n_dim, 128)
        self.linear2 = nn.Linear(128, n_word)

    def forward(self, x):
        x = self.embedding(x)
        x = x.view(1, -1)
        x = self.linear1(x)
        x = F.relu(x, inplace=True)
        x = self.linear2(x)
        x = F.log_softmax(x)
        return x
        
model = CBOW(len(word_to_idx), 100, CONTEXT_SIZE)
if torch.cuda.is_available():
    model = model.cuda()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=1e-3)

for epoch in range(40):
    print('epoch {}'.format(epoch))
    print('*'*10)
    running_loss = 0
    for word in data:
        context, target = word
        context = Variable(torch.LongTensor([word_to_idx[i] for i in context]))
        target = Variable(torch.LongTensor([word_to_idx[target]]))
        if torch.cuda.is_available():
            context = context.cuda()
            target = target.cuda()

        out = model(context)
        loss = criterion(out, target)
        running_loss += loss.data

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print('loss: {:.6f}'.format(running_loss / len(data)))

2.3.3.2 Skip-Gram

与CBOW相反,Skip-gram预测了给定中心词的上下文。图2.2显示了该模型。形式上,给定一个单词wi,Skip-gram预测其上下文为

P ( w j ∣ w i ) = softmax ⁡ ( M w i ) ( ∣ j − i ∣ ≤ l , j ≠ i ) , P(w_j|w_i)=\operatorname{softmax}(\mathbf{M}\mathbf{w}_i)\big(|j-i|\leq l,j\neq i\big), P(wjwi)=softmax(Mwi)(jil,j=i),

其中 P ( w j ∣ w i ) P(w_j|w_i) P(wjwi)为给定的上下文词wjwi的概率,M为权值矩阵。损失函数的定义类似于CBOW,其定义为

L = − ∑ i ∑ j ( ∣ j − i ∣ ≤ l , j ≠ i ) P ( w j ∣ w i ) . \mathscr{L}=-\sum_{i}\sum_{j(|j-i|\leq l,j\neq i)}P(w_j|w_i). L=ij(jil,j=i)P(wjwi).

image-20230905202228896

#####2.3.3.3 Hierarchical Softmax and Negative Sampling

层次化的softmax根据单词的频率生成层次化的类,即霍夫曼树。通过近似,它可以更快地计算每个单词的概率,而计算每个单词的概率的复杂性是负抽样更简单。为了计算一个单词的概率, O ( l o g ∣ V ∣ ) O(log |V|) OlogV

负抽样更为直接。为了计算一个单词的概率,O(log |V|)。负抽样根据单词频率直接抽取k个单词作为负样本。然后,它计算k + 1个单词上的softmax来近似目标单词的概率。

2.3.4 GloVe

诸如Skip-gram和CBOW等方法都是基于浅窗口的方法。这些方法扫描了整个语料库的上下文窗口,但没有利用一些全局信息。相反,Word表示的全局向量(GloVe)可以直接捕获语料库统计量。

GloVe的全称叫Global Vectors for Word Representation,它是一个基于全局词频统计(count-based & overall statistics)的词表征(word representation)工具,它可以把一个单词表达成一个由实数组成的向量,这些向量捕捉到了单词之间一些语义特性,比如相似性(similarity)、类比性(analogy)等。我们通过对向量的运算,比如欧几里得距离或者cosine相似度,可以计算出两个单词之间的语义相似性。

GloVe是如何实现的?

GloVe的实现分为以下三步:

  • 根据语料库(corpus)构建一个共现矩阵(Co-ocurrence Matrix)X(什么是共现矩阵?),

    矩阵中的每一个元素 x i j x_{ij} xij代表单词i和上下文单词j在特定大小的上下文窗口(context window)内共同出现的次数。

    一般而言,这个次数的最小单位是1,但是GloVe不这么认为:它根据两个单词在上下文窗口的距离d,提出了一个衰减函数(decreasing weighting):

    d e c a y = 1 / d decay=1/d decay=1/d

    用于计算权重,也就是说距离越远的两个单词所占总计数(total count)的权重越小。

    In all cases we use a decreasing weighting function, so that word pairs that are d words apart contribute 1/d to the total count.

  • 构建词向量(Word Vector)和共现矩阵(Co-ocurrence Matrix)之间的近似关系,论文的作者提出以下的公式可以近似地表达两者之间的关系: w i T w j ~ + b i + b j ~ = log ⁡ ( X i j ) w_i^T\tilde{w_j}+b_i+\tilde{b_j}=\log(X_{ij}) wiTwj~+bi+bj~=log(Xij)

其中, w i T w j ~ w_i^T\tilde{w_j} wiTwj~是我们最终要求解的词向量; b i , b j ~ b_i,\tilde{b_j} bi,bj~分别是两个词向量的bias term。
当然你对这个公式一定有非常多的疑问,比如它到底是怎么来的,为什么要使用这个公式,为什么要构造两个词向量 w i T w j ~ w_i^T\tilde{w_j} wiTwj~文我们会详细介绍。

有了公式1之后我们就可以构造它的loss function了: J = ∑ i , j = 1 V f ( X i j ) ( w i T w ~ j + b i + b ~ j − log ⁡ ( X i j ) ) 2 J=\sum_{i,j=1}^{V}f(X_{ij})(w_i^T\tilde{w}_j+b_i+\tilde{b}_j-\log(X_{ij}))^2 J=i,j=1Vf(Xij)(wiTw~j+bi+b~jlog(Xij))2

这个loss function的基本形式就是最简单的mean square loss,只不过在此基础上加了一个权重函数 f ( X i j ) f(X_{ij}) f(Xij)

,那么这个函数起了什么作用,为什么要添加这个函数呢?我们知道在一个语料库中,肯定存在很多单词他们在一起出现的次数是很多的(frequent co-occurrences),那么我们希望:

  • 1.这些单词的权重要大于那些很少在一起出现的单词(rare co-occurrences),所以这个函数要是非递减函数(non-decreasing);
  • 2.但我们也不希望这个权重过大(overweighted),当到达一定程度之后应该不再增加;
  • 3.如果两个单词没有在一起出现,也就是 X i j X_{ij} Xij=0,那么他们应该不参与到loss function的计算当中去,也就是f(x)要满足f(0)=0

满足以上两个条件的函数有很多,作者采用了如下形式的分段函数:

image-20230906102323410

Glove与LSA、word2vec的比较

LSA(Latent Semantic Analysis)是一种比较早的count-based的词向量表征工具,它也是基于co-occurance matrix的,只不过采用了基于奇异值分解(SVD)的矩阵分解技术对大矩阵进行降维,而我们知道SVD的复杂度是很高的,所以它的计算代价比较大。还有一点是它对所有单词的统计权重都是一致的。而这些缺点在GloVe中被一一克服了。而word2vec最大的缺点则是没有充分利用所有的语料,所以GloVe其实是把两者的优点结合了起来。从这篇论文给出的实验结果来看,GloVe的性能是远超LSA和word2vec的,但网上也有人说GloVe和word2vec实际表现其实差不多。

2.4 Contextualized Word Representation(双向lstm)

这里解决的也就是著名的多义问题,比如说bank在不同语境,会有不一样的意义。

为了解决这个问题,[48]提出了ELMo,它使用一个深度的双向LSTM模型来构建单词表示。ELMo可以根据表示每个单词

在使用它的整个上下文中。更具体地说,ELMo没有单词嵌入矩阵的查找表,而是通过将单词及其周围文本输入深度神经网络,将单词转换为低维向量。ELMo利用一个双向语言模型来进行单词表示。具体可见我的博客分析。

2.6 Evaluation

近年来,人们提出了各种将单词嵌入向量空间的方法。因此,评估不同的方法是很有必要的。对单词嵌入有两种一般的评价,包括单词相似性和单词类比。他们的目标都是检查分发这个词是否合理。这两种评价有时会产生不同的结果。例如,CBOW在单词相似度方面表现更好,而Skip-gram在单词类比方面表现优于CBOW。因此,选择哪种方法取决于高级应用程序。特定于任务的单词嵌入方法通常是为特定的高级任务而设计的.

2.6.1 Word Similarity/Relatedness

单词的动态是非常复杂和微妙的。没有一个静态的、有限的关系集可以描述两个词之间的所有相互作用。对于下游任务来说,利用不同类型的单词关系也不是一件小事。一种更实际的方法是给一对单词分配一个分数,以表示它们之间的关联程度。这种测量方法被称为单词的相似度。当谈论这个术语单词的相似性时,确切的含义在不同的情况下可能会有很大的不同。在各种不同的文献中,可以提到几种相似之处。

2.6.2 Word Analogy

s

单词的动态是非常复杂和微妙的。没有一个静态的、有限的关系集可以描述两个词之间的所有相互作用。对于下游任务来说,利用不同类型的单词关系也不是一件小事。一种更实际的方法是给一对单词分配一个分数,以表示它们之间的关联程度。这种测量方法被称为单词的相似度。当谈论这个术语单词的相似性时,确切的含义在不同的情况下可能会有很大的不同。在各种不同的文献中,可以提到几种相似之处。

2.6.2 Word Analogy

除了单词相似性外,单词类比任务也是衡量表征捕获单词语义意义的另一种方法。这个任务给出三个单词w1、w2和w3,然后要求系统预测一个单词w4,使w1和w2之间的关系与w3和w4之间的关系相同。从[43,45]开始,这个任务就被用来利用单词之间的结构关系。在这里,词的关系可以分为语义关系和句法关系两类。这是一种相对新颖的单词表示评估方法,但由于数据集发布,很快成为一个标准的评估度量。与托福同义词测试不同的是,这个数据集中的大多数单词在各种语料库中都很常见,但是第四个单词是从整个词汇表中选择的,而不是四个选项。这个测试倾向于分布式单词表示,因为它强调了单词空间的结构。在[7,56,57,61]中可以找到不同模型之间的比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值