Loading...

目录


1. word2vec

1.1 主要步骤

Word2Vec算法的具体思路请见这里

    1. 随起:从随机的词向量开始
    1. 遍历:遍历整个语料库的每个单词
    1. 预测:尝试是使用词向量预测周围的词
    1. 学习:更新向量,以便他们可以更好地预测周围的实际单词

1.2 计算过程

根据中心词和外围词,作dot,然后softmax:

其实,我们想要的就像上述模型一样,模型在每个位置做出相同的预测,它可以对上下文中出现的所有单词(经常)给出合理的高概率估计,这个模型就是“词袋”模型

  • 每行代表一个单词的词向量,点乘后得到的分数通过softmax映射为概率分布,并且我们得到的概率分布是对于该中心词而言的上下文中单词的概率分布,该分布于上下文所在的具体位置无关,所以在每个位置的预测都是一样的
  • 我们希望模型对上下文中(相当频繁)出现的所有单词给出一个合理的高概率估计
  • the, and, that, of 这样的停用词,是每个单词点乘后得到的较大概率的单词,去掉这一部分可以使词向量效果更好

1.3 最大化目标函数

word2vec通过将相似的单词放在邻近的空间来最大化目标函数:

1.4 优化:梯度下降

公式:

    1. 批量梯度下降: $\theta_{\text{new}} = \theta_{\text{old}} - \alpha \nabla J(\theta)$
    1. 随机梯度下降: $\theta_{\text{new}_j} = \theta_{\text{old}_j} - \alpha \frac{\partial}{\partial \theta_{\text{old}_j}} J(\theta)$
1
2
3
while True:
theta_grad = evaluate_gradient(J, corpus, theta)
theta = theta - alpha * theta_grad


注意

    1. 因为上述$J(\theta)$是语料库(一个语料库非常大有足足几十亿)中所有窗口的函数,所以更新一次需要很长时间.
    1. 改进方法:使用随机梯度下降法,在单个样本内更新参数,然后遍历所有样本
    1. 改进方法*:但基于单个样本更新会表现为参数震荡很厉害,收敛过程并不平稳,所以很多时候我们会改为使用mini-batch gradient descent
1
2
3
4
while True:
window = sample_window(corpus)
theta_grad = evaluate_gradient(J, window, theta)
theta = theta - alpha * theta_grad


新的问题:稀疏,每次梯度更新的时候需要计算全部词向量的累加,也就是计算下面的分母,词典很大的时候会导致计算很难

方法:只更新实际出现的词向量

    1. 稀疏矩阵来仅更新完整嵌入矩阵U和V的某些行,例如,我们可以只存储和更新当前mini-batch中出现的那些词向量对应的行。例如,如果一个mini-batch包含句子”我去上班”和”你在家吗”,其中只包含6个词:”我”、”去”、 “上班”、”你”、”在”、”家”和”吗”
    1. 保留词向量的哈希表,只更新特定的列

1.5 Word2vec算法族:两个向量、两种模型、两种算法

model:Continuous Bag-of-Words(CBOW)和 Skip-Gram
algorithm:Negative Sampling 和 Hierarchical Softmax


2. 共现矩阵

在自然语言处理里另外一个构建词向量的思路是借助于共现矩阵(我们设其为 X ),我们有两种方式,可以基于窗口(window) 或者 全文档(full document) 统计

窗口 Window :类似于 word2vec,在每个单词周围使用窗口来捕获一些句法和语义信息
文档 Word-document :共现矩阵的基本假设是在同一篇文章中出现的单词更有可能相互关联。若单词 wi 出现在文档 dj中,则共现矩阵元素 Xij加 1。

2.1 共现向量

一个共现向量是共现矩阵的一行,代表一个词向量。直接基于共现矩阵构建词向量,会有一些明显的问题

缺点:

  1. 使用共现次数衡量单词的相似性,向量随着词汇量的增加而增加
  2. 非常高的维度:需要大量存储
  3. 稀疏

解决方法:降维

2.2 奇异值分解SVD

定义:矩阵X可以分解为下面是哪个矩阵的乘积

    1. $U$ 是一个 $m \times m$ 的酉矩阵,也就是说,它是方阵,其列向量是标准正交的,即满足 $U^U = I_m$,其中 $U^$ 是 $U$ 的共轭转置, $I_m$ 是 $m$ 阶单位矩阵。
    1. $V^T$ 是一个 $n \times n$ 的酉矩阵的转置,其中 $V$ 是酉矩阵,其行向量是标准正交的,即满足 $VV^* = I_n$。
    1. $\Sigma$ 是一个 $m \times n$ 的对角矩阵,对角线上的元素是奇异值,并且这些奇异值是非负的并以降序排列。非对角线上的元素都是0。


例如,假设有一个矩阵 $X$ 的维度是 $m = 1,000,000$ 和 $n = 500,000$,即矩阵 $X$ 有 $1,000,000 \times 500,000 = 500$ 亿个元素。如果这些元素以5号字体打印出来,它们所占的空间将相当于两个杭州西湖那么大。奇异值分解(SVD)就是将这样一个庞大的矩阵 $X$ 分解成三个较小矩阵相乘的过程:一个 $1,000,000 \times 100$ 的矩阵 $U$,一个 $100 \times 100$ 的矩阵 $\Sigma$,以及一个 $100 \times 500,000$ 的矩阵 $V^T$。这三个矩阵的元素总和是 $1.5$ 亿,大约是原始元素总数的 $\frac{1}{3000}$,即 “弱水三千,只取一瓢饮”,这样的降维效果非常显著,它相应地将存储量和计算量都降低了三个数量级以上。

2.3 求X矩阵的小技巧

原始计数上运行SVD效果不佳,缩放单元格的计数会有很大的帮助
例如,the,he,has出现太频繁,导致句法的影响太大,下面是一些解决方法:

    1. 记录频率
    1. min(X,t),限制高频词的出现
    1. 忽略虚词
    1. 使用log进行缩放


倾斜的窗口:多对较近的单词进行计数(即根据与中心词的距离对权重进行衰减),例如与中心词相邻时记 1 次共现,与中心词相距 5 个单词时记 0.5 次共现;

使用 Pearson 系数代替计数,然后将负值设置为 0


有趣的现象:

    1. 句法模型中,词向量是团快组件
    1. 语义模式中,词向量基本是线性组件


SVD缺陷

    1. 在大的数据集上训练是很困难,计算复杂度高;
    1. 若想将新的词汇或文章融合进去,就必须重新进行 SVD,计算代价高


参考链接