> For the complete documentation index, see [llms.txt](https://baozoulin.gitbook.io/dl-ai-special-notebook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://baozoulin.gitbook.io/dl-ai-special-notebook/course5/di-er-zhou-zi-ran-yu-yan-chu-li-yu-ci-qian-ru-naturallanguageprocessingandwordembeddingscourse5.md).

# 第二周 自然语言处理与词嵌入（Course5/Natural Language Processing and Word Embeddings）

## 2.1 词汇表征（Word Representation）

**one-hot**向量表示：单词Man，Woman，King，Queen，Apple，Orange分别出现在词汇表的第5391，9853，4914，7157，456，6257的位置，则它们分别用$$O\_{5391}$$,$$O\_{9853}$$ 等表示，$$O$$代表**one-hot：**

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/68d7c930146724f39782cb57d33161e9.png)

缺点是把每个词孤立起来，使得算法对相关词的泛化能力不强

因为任何两个one-hot向量的内积都是0，例如king和queen，词性相近，但是单从one-hot编码上来看，内积为零，无法知道二者的相似性

因此用**特征表征（Featurized representation）**&#x7684;方法对每个单词进行编码。也就是使用一个特征向量表征单词，特征向量的每个元素都是对该单词某一特征的量化描述，量化范围可以是\[-1,1]之间，而单词使用这种高维特征表示时，就叫做**词嵌入（word embedding），** 词嵌入可以让算法自动的理解一些类似的词，比如男人对女人，国王对王后：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/ce30c9ae7912bdb3562199bf85eca1cd.png)

> 以上举例的特征实际上并不是手工设计的，而是算法（word embedding）学习而来；而且这些学习的特征，可能并不具有良好的解释性，但无论如何，算法都可以快速找到哪些单词是类似的

特征向量的长度依情况而定，特征元素越多则对单词表征得越全面。这里的特征向量长度设定为300。使用特征表征之后，词汇表中的每个单词都可以使用对应的300 x 1的向量来表示，该向量的每个元素表示该单词对应的某个特征值。每个单词用e+词汇表索引的方式标记，例如$$e\_{5391}$$，$$e\_{9853}$$，$$e\_{4914}$$，$$e\_{7157}$$，$$e\_{456}$$，$$e\_{6257}$$

用这种表示方法来表示**apple**和**orange**这些词，那么**apple**和**orange**的这种表示肯定会非常相似，可能有些特征不太一样，如颜色口味，但总的来说**apple**和**orange**的大部分特征实际上都一样，或者说都有相似的值。这样对于已经知道**orange juice**的算法很大几率上也会明白**apple juice**这个东西，这样对于不同的单词算法会泛化的更好

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/59fb45cfdf7faa53571ec7b921b78358.png)

如果能够学习到一个300维的特征向量，或者说300维的**词嵌入**，把这300维的数据嵌入到一个二维空间里，就可以可视化了。常用的可视化算法是**t-SNE算法**，会发现**man**和**woman**这些词聚集在一块，**king**和**queen**聚集在一块等等

在对这些概念可视化的时候，词嵌入算法对于相近的概念，学到的特征也比较类似，最终把它们映射为相似的特征向量

## 2.2 使用词嵌入（Using Word Embeddings）

之前Named entity识别的例子（即找出语句中的人名），每个单词采用的是one-hot编码。RNN模型能确定**Sally Johnson**是一个人名而不是一个公司名，是因为“orange farmer”是份职业，很明显“Sally Johnson”是一个人名（输出1）

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/b4bf4b0cdcef0c9d021707c47d5aecda.png)

如果用特征化表示方法，即用**词嵌入**作为输入训练好的模型，如果一个新的输入：“**Robert Lin is an apple farmer.**”，因为知道**orange**和**apple**很相近，那么算法很容易就知道**Robert Lin**也是一个人的名字

**featurized representation**的优点是可以减少训练样本的数目，前提是对海量单词建立特征向量表述。即使训练样本不够多，测试时遇到陌生单词，例如“durian cultivator”，根据之前海量词汇特征向量就判断出“durian”也是一种水果，与“apple”类似，而“cultivator”与“farmer”也很相似。从而得到与“durian cultivator”对应的应该也是一个人名。这种做法将单词用不同的特征来表示，即使是训练样本中没有的单词，也可以根据word embedding的结果得到与其词性相近的单词，从而得到与该单词相近的结果，有效减少了训练样本的数量

词嵌入能够达到这种效果，原因是学习词嵌入的算法会考察非常大的文本集

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/8a1d58b7ade17208053c10728b2bf3b6.png)\
词嵌入做迁移学习的步骤：

1. 先从大量的文本集中学习词嵌入，或者下载网上预训练好的词嵌入模型
2. 用这些词嵌入模型迁移到新的只有少量标注训练集的任务中，比如用300维的词嵌入来表示单词。好处就是可以用更低维度的特征向量代替原来的10000维的**one-hot**向量。尽管**one-hot**向量很快计算，但学到的用于词嵌入的300维的向量会更加紧凑
3. 当在新的任务上训练模型，而在命名实体识别任务上只有少量的标记数据集，可以选择要不要继续微调，用新的数据调整词嵌入。但实际中只有第二步中有很大的数据集才会这样做，如果标记的数据集不是很大，通常不会在微调词嵌入上费力气

当任务的训练集相对较小时，词嵌入的作用最明显，所以它广泛用于**NLP**领域

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/43943c791844cc7f077f6c6f98f1f629.png)

词嵌入和人脸编码有很多相似性，训练了一个**Siamese**网络结构，这个网络会学习不同人脸的一个128维表示，然后通过比较编码结果来判断两个图片是否是同一个人脸，在人脸识别领域用编码指代向量$$f(x^{\left(i \right)})$$，$$f(x^{\left( j\right)})$$，词嵌入的意思和这个差不多

人脸识别领域和词嵌入不同就是：

* 在人脸识别中训练一个网络，任给一个人脸照片，甚至是没有见过的照片，神经网络都会计算出相应的一个编码结果
* 学习词嵌入则是有一个固定的词汇表，比如10000个单词，学习向量$$e\_{1}$$到$$e\_{10000}$$，学习一个固定的编码，即每一个词汇表的单词的固定嵌入
* 人脸识别中的算法未来可能涉及到海量的人脸照片，而自然语言处理有一个固定的词汇表，没有出现过的单词就记为未知单词

## 2.3 词嵌入的特性（Properties of Word Embeddings）

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/12242657bd982acd1d80570cc090b4fe.png)

该例中，假设用的是四维的嵌入向量，假如向量$$e\_{\text{man}}$$和$$e\_{\text{woman}}$$、$$e\_{\text{king}}$$和$$e\_{\text{queen}}$$ 分别进行减法运算，相减结果表明，“Man”与“Woman”的主要区别是性别，“King”与“Queen”也是一样

所以当算法被问及**man**对**woman**相当于**king**对什么时，算法所做的就是计算$$e\_{\text{man}}-e\_{\text{woman}}$$，然后找出一个向量也就是找出一个词，使得：

$$
e\_{\text{man}}-e\_{\text{woman}}\approx e\_{\text{king}} - e\_{?}
$$

即当这个新词是**queen**时，式子的左边会近似地等于右边

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/5a42eea162ddc75a1d37520618b4bcd2.png)]\
在图中，词嵌入向量在一个可能有300维的空间里，箭头代表的是向量在**gender**（**性别**）这一维的差，为了得出类比推理，计算当**man**对于**woman**，**king**对于什么，要做的就是找到单词**w**来使得

$$
e\_{\text{man}}-e\_{\text{woman}}\approx e\_{\text{king}} - e\_{w}
$$

等式成立，即找到单词**w**来最大化$$e\_{w}$$与$$e\_{\text{king}} - e\_{\text{man}} + e\_{\text{woman}}$$的相似度，即

$$
Find\ word\ w:argmax\ Sim(e\_{w},e\_{\text{king}} - e\_{\text{man}} + e\_{\text{woman}})
$$

即把$$e\_{w}$$全部放到等式的一边，另一边是$$e\_{\text{king}}- e\_{\text{man}} + e\_{\text{woman}}$$。应用相似度函数，通过方程找到一个使得相似度最大的单词，如果结果理想的话会得到单词**queen**

**t-SNE算法**所做的就是把这些300维的数据用一种非线性的方式映射到2维平面上，可以得知**t-SNE**中这种映射很复杂而且很非线性。在大多数情况下，由于**t-SNE**的非线性映射，不能总是期望使等式成立的关系会像左边那样成一个平行四边形

关于相似函数，比较常用的是余弦相似度，假如在向量$$u$$和$$v$$之间定义相似度：

$$
Sim(u,v)=\frac{u^Tv}{||u||\cdot ||v||}
$$

分子是$$u$$和$$v$$的内积。如果$$u$$和$$v$$非常相似，那么它们的内积将会很大，把整个式子叫做余弦相似度，是因为该式是$$u$$和$$v$$的夹角的余弦值

**参考资料：** 给定两个向量$$u$$和$$v$$，余弦相似度定义如下：

$$
{CosineSimilarity(u, v)} = \frac {u . v} {||u||\_2 ||v||\_2} = cos(\theta)
$$

$$u.v$$ 是两个向量的点积（或内积），$$||u||\_2$$是向量$$u$$的范数（或长度）， $$\theta$$ 是向量$$u$$和$$v$$之间的角度。这种相似性取决于角度在向量$$u$$和$$v$$之间。如果向量$$u$$和$$v$$非常相似，它们的余弦相似性将接近1; 如果它们不相似，则余弦相似性将取较小的值

![\](https://github.com/fengdu78/deeplearning\_ai\_books/raw/master/markdown/..\images\cosine\_sim.png "osine\_si")](https://raw.githubusercontent.com/fengdu78/deeplearning_ai_books/master/markdown/..\images\cosine_sim.png)

> 两个向量之间角度的余弦是衡量它们有多相似的指标，角度越小，两个向量越相似

还可以计算Euclidian distance来比较相似性，即$$||u-v||^2$$。距离越大，相似性越小

## 2.4 嵌入矩阵（Embedding Matrix）

当应用算法来学习词嵌入时，实际上是学习一个**嵌入矩阵**

假设某个词汇库包含了10000个单词，每个单词包含的特征维度为300，那么表征所有单词的**embedding matrix**维度为300 x 10000，用$$E$$来表示。某单词$$w$$的one-hot向量表示为$$O\_w$$，维度为10000 x 1

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/ad1c7b1e85d39f56756c28787ccef892.png)

则该单词的嵌入向量(embedding vector)表达式为：

$$
e\_w=E\cdot O\_w
$$

只要知道了embedding matrix$$E$$，就能计算出所有单词的embedding vector $$e\_w$$

不过上述这种矩阵乘积运算$$E\cdot O\_w$$效率并不高，矩阵维度很大，且$$O\_w$$大部分元素为零。通常做法是直接从$$E$$中选取第$$w$$列作为$$e\_w$$

## 2.5 学习词嵌入（Learning Word Embeddings）

embedding matrix $$E$$可以通过构建自然语言模型，运用梯度下降算法得到。若输入样本是：

**I want a glass of orange (juice).**

通过这句话的前6个单词，预测最后的单词“juice”。$$E$$未知待求，每个单词可用embedding vector $$e\_w$$表示。构建的神经网络模型结构如下图所示：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/31347eca490e0ae8541140fb01c04d72.png)

神经网络输入层包含6个embedding vectors，每个embedding vector维度是300，则输入层总共有1800个输入。Softmax层有10000个概率输出，与词汇表包含的单词数目一致。正确的输出label是“juice”。其中$$E,W^{\[1]},b^{\[1]},W^{\[2]},b^{\[2]}$$为待求值。对足够的训练例句样本，运用梯度下降算法，迭代优化，最终求出embedding matrix$$E$$

这种算法的效果还不错，能够保证具有相似属性单词的embedding vector相近

为了让神经网络输入层数目固定，可以选择只取预测单词的前4个单词作为输入，例如该句中只选择“a glass of orange”四个单词作为输入。这里的4是超参数，可调

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/747e619260737ded586ae51b3b4f07d6.png)

把输入叫做**context**，输出叫做**target**。对应到上面这句话里：

* **context: a glass of orange**
* **target: juice**

关于context的选择有多种方法：

* **target前n个单词或后n个单词，n可调**
* **target前1个单词**
* **target附近某1个单词（Skip-Gram）**$$E$$

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/638c103855ffeb25122259dd6b669850.png)

事实证明，不同的context选择方法都能计算出较准确的embedding matrix $$E$$

## 2.6 Word2Vec

选择context和target的方法中，比较流行的是采用**Skip-Gram**模型

Skip-Gram模型的做法是：首先随机选择一个单词作为context，例如“orange”；然后使用一个宽度为5或10（自定义）的滑动窗，在context附近选择一个单词作为target，可以是“juice”、“glass”、“my”等等。最终得到了多个context—target对作为监督式学习样本：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/0800c19895cbf1a360379b5dc5493902.png)

训练的过程是构建自然语言模型，经过softmax单元的输出为：

$$
\hat y=\frac{e^{\theta\_t^T\cdot e\_c}}{\sum\_{j=1}^{10000}e^{\theta\_j^T\cdot e\_c}}
$$

$$\theta\_t$$为target对应的参数，$$e\_c$$为context的embedding vector，且$$e\_c=E\cdot O\_c$$

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/4ebf216a59d46efa2136f72b51fd49bd.png)

相应的loss function为：

$$
L(\hat y,y)=-\sum\_{i=1}^{10000}y\_ilog\ \hat y\_i
$$

> 由于\
> $$y$$\
> 是一个one-hot向量，所以上式实际上10000个项里面只有一项是非0的

然后，运用梯度下降算法，迭代优化，最终得到embedding matrix $$E$$

然而，这种算法计算量大，影响运算速度。主要因为softmax输出单元为10000个，$$\hat y$$计算公式中包含了大量的求和运算

解决的办法之一是使用**hierarchical softmax classifier**，即**树形分类器**：

\[\
![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/89743b5ade106cad1318b8f3f4547a7f.png)]

这种树形分类器是一种二分类。它在每个数节点上对目标单词进行区间判断，最终定位到目标单词。最多需要$$\log\_2 N$$步就能找到目标单词，N为单词总数

实际应用中，对树形分类器做了一些改进。改进后的树形分类器是非对称的，通常选择把比较常用的单词放在树的顶层，而把不常用的单词放在树的底层。这样更能提高搜索速度

关于context的采样：如果使用均匀采样，那么一些常用的介词、冠词，例如the, of, a, and, to等出现的概率更大一些。但是这些单词的embedding vectors通常不是最关心的，更关心的例如orange, apple， juice等这些名词。所以实际应用中一般不选择随机均匀采样的方式来选择context，而是使用其它算法来处理这类问题

## 2.7 负采样（Negative Sampling）

算法要做的是构造一个新的监督学习问题：给定一对单词，比如**orange**和**juice**，去预测这是否是一对上下文词-目标词（**context-target**）

在这个例子中**orange**和**juice**就是个正样本，用1作为标记，**orange**和**king**就是个负样本，标为0。要做的就是采样得到一个上下文词和一个目标词，中间列叫做词（**word**）。然后：

* 生成一个正样本，先抽取一个context，在一定词距内比如说正负10个词距内选一个target，生成这个表的第一行，即**orange– juice -1**的过程
* 生成一个负样本，用相同的context，再在字典中随机选一个词，如**king、book、the、of**，标记为0。因为如果随机选一个词，它很可能跟**orange**没关联

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/54beb302688f6a298b63178534281575.png)

如果从字典中随机选到的词，正好出现在了词距内，比如说在上下文词**orange**正负10个词之内，也没关系，如**of**被标记为0，即使**of**的确出现在**orange**词的前面

接下来将构造一个监督学习问题，学习算法输入$$x$$，即输入这对词（编号7），要去预测目标的标签（编号8），即预测输出$$y$$

如何选取$$K$$：

* 小数据集的话，$$K$$从5到20，数据集越小$$K$$就越大
* 如果数据集很大，$$K$$就选的小一点。对于更大的数据集$$K$$就从2到5

学习从$$x$$映射到$$y$$的监督学习模型：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/f36df292b7444e9b7379fa7c14626fa2.png)

编号2是新的输入$$x$$，编号3是要预测的值$$y$$。记号$$c$$表示context，记号$$t$$表示可能的target，$$y$$表示0和1，即是否是一对context-target。要做的是定义一个逻辑回归模型，给定输入的$$c$$，$$t$$对的条件下，$$y=1$$的概率，即：

$$
P\left( y = 1 \middle| c,t \right) = \sigma(\theta\_{t}^{T}e\_{c})
$$

如果输入词是**orange**，即词6257，要做的就是输入**one-hot**向量，和$$E$$相乘获得嵌入向量$$e\_{6257}$$，最后得到10,000个可能的逻辑回归分类问题，其中一个（编号4）将会是用来判断目标词是否是**juice**的分类器，其他的词比如下面的某个分类器（编号5）是用来预测**king**是否是目标词

negative sampling中某个固定的正样本对应$$k$$个负样本，即模型总共包含了$$k+1$$个**binary classification**。对比之前10000个输出单元的softmax分类，negative sampling转化为$$k+1$$个二分类问题，每次迭代并不是训练10000个，而仅训练其中$$k+1$$个，计算量要小很多，大大提高了模型运算速度

这种方法就叫做**负采样（Negative Sampling）:** 选择一个正样本，随机采样$$k$$个负样本

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/b05dd0362a19496bb0ad91b8494e374c.png)

选取了context **orange**之后，如何选取负样本：

* 通过单词出现的频率进行采样：导致一些类似a、the、of等词的频率较高
* 均匀随机地抽取负样本：没有很好的代表性

**（推荐）**：

$$
P(w\_{i}) = \frac{f( w\_{i})^{\frac{3}{4}}}{\sum\_{j = 1}^{10,000}{f( w\_{j} )^{\frac{3}{4}}}}
$$

这种方法处于上面两种极端采样方法之间，即不用频率分布，也不用均匀分布，而采用的是对词频的$$\frac{3}{4}$$除以词频$$\frac{3}{4}$$整体的和进行采样的。其中，$$f(w\_j)$$是语料库中观察到的某个词的词频

## 2.8 GloVe 词向量（GloVe Word Vectors）

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/70e282d4d1abb86fd15ff7b175f4e579.png)

**GloVe**代表用词表示的全局变量（**global vectors for word representation**）

假定$$X\_{ij}$$是单词$$i$$在单词$$j$$上下文中出现的次数，$$i$$和$$j$$ 与$$t$$和$$c$$的功能一样，可以认为$$X\_{ij}$$等同于$$X\_{tc}$$。根据context和target的定义，会得出$$X\_{ij}$$等于$$X\_{ji}$$

* 如果将context和target的范围定义为出现于左右各10词以内的话，就有对称关系$$X\_{ij}=X\_{ji}$$
* 如果对context的选择是context总是目target前一个单词，那么$$X\_{ij}\neq X\_{ji}$$

对于**GloVe**算法，可以定义context和target为任意两个位置相近的单词，假设是左右各10词的距离，那么$$X\_{ij}$$就是一个能够获取单词$$i$$和单词$$j$$彼此接近的频率计数器

**GloVe**模型做的就是进行优化，将差距进行最小化处理：

$$
\text{mini}\text{mize}\sum\_{i = 1}^{10,000}{\sum\_{j = 1}^{10,000}}{f\left( X\_{ij}
\right)\left( \theta\_{i}^{T}e\_{j} + b\_{i} + b\_{j}^{'} - \log X\_{ij} \right)^{2}}
$$

$$\theta{i}^{T}e{j}$$即$$\theta\_{t}^{T}e\_{c}$$。对于$$\theta\_{t}^{T}e\_{c}$$，这两个单词同时出现的频率是多少受$$X\_{ij}$$影响，若两个词的embedding vector越相近，同时出现的次数越多，则对应的loss越小

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/f6fc2cec52f4ecb15567511aae822914.png)

当$$X\_{ij}=0$$时，权重因子$$f(X\_{ij})=0$$。这种做法直接忽略了无任何相关性的context和target，只考虑$$X\_{ij}>0$$的情况

出现频率较大的单词相应的权重因子$$f(X\_{ij})$$较大，出现频率较小的单词相应的权重因子$$f(X\_{ij})$$较小一些

因为$$\theta$$和$$e$$是完全对称的，所以$$\theta\_{i}$$和$$e\_{j}$$是对称的。因此训练算法的方法是一致地初始化$$\theta$$和$$e$$，然后使用梯度下降来最小化输出，当每个词都处理完之后取平均值：

$$
e\_{w}^{(final)}= \frac{e\_{w} +\theta\_{w}}{2}
$$

**GloVe**算法不能保证嵌入向量的独立组成部分：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/ec4b604d619dd617f14c2a34945c075d.png)

通过上面的很多算法得到的词嵌入向量，无法保证词嵌入向量的每个独立分量是能够理解的。但能够确定是每个分量和所想的一些特征是有关联的，可能是一些我们能够理解的特征的组合而构成的一个组合分量

使用上面的GloVe模型，从线性代数的角度解释如下：

$$
\Theta\_{i}^{T}e\_{j} = \Theta\_{i}^{T}A^{T}A^{-T}e\_{j}=(A\Theta\_{i})^{T}(A^{-T}e\_{j})
$$

加入的$$A$$项，可能构成任意的分量组合

## 2.9 情感分类（Sentiment Classification）

情感分类任务就是看一段文本，然后分辨这个人是否喜欢他们在讨论的这个东西，最大的挑战就是可能标记的训练集没有那么多，但是有了词嵌入，即使只有中等大小标记的训练集，也能构建一个不错的情感分类器

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/bf6f5879d33ae4ef09b32f77df84948e.png)

> 输入$$x$$是一段文本，输出$$y$$是要预测的相应情感。比如一个餐馆评价的星级

情感分类一个最大的挑战就是可能标记的训练集没有那么多。对于情感分类任务来说，训练集大小从10,000到100,000个单词都很常见，甚至有时会小于10,000个单词，采用了词嵌入能够带来更好的效果，尤其是只有很小的训练集

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/ea844a0290e66d1c76a31e34b632dc0c.png)

给定四个词（"**dessert is excellent**"），通常用10,000个词的词汇表，找到相应的**one-hot**向量，再乘以嵌入矩阵$$E$$，$$E$$可以从一个很大的文本集里学习到，比如它可以从一亿个词或者一百亿个词里学习嵌入，然后用来提取单词**the**的嵌入向量$$e\_{8928}$$，对**dessert**、**is**、**excellent**做同样的步骤

然后取这些向量（编号2），如300维度的向量，通过平均值计算单元（编号3），求和并平均，再送进**softmax**分类器，然后输出$$\hat y$$。这个**softmax**能够输出5个可能结果的概率值，从一星到五星

这个算法适用于任何长短的评论，因为即使评论是100个词长，也可以对这一百个词的特征向量求和取平均，得到一个300维的特征向量，然后送进**softmax**分类器

但问题是没考虑词序，如负面的评价，"**Completely lacking in good taste, good service, and good ambiance.**"，**good**这个词出现了很多次，但算法忽略词序，仅仅把所有单词的词嵌入加起来或者平均下来，最后的特征向量会有很多**good**的表示，分类器很可能认为这是一个好的评论，尽管事实上这是一个差评，只有一星的评价

为了解决这一问题，情感分类的另一种模型是RNN：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/de4b6513a8d1866bccf1fac3c0d0d6d2.png)

首先取这条评论，"**Completely lacking in good taste, good service, and good ambiance.**"，找出每一个**one-hot**向量，乘以词嵌入矩阵$$E$$，得到词嵌入表达$$e$$，然后把它们送进**RNN**

**RNN**的工作就是在最后一步（编号1）计算一个特征表示，用来预测$$\hat y$$。这样的算法考虑词的顺序效果更好，能意识到"**things are lacking in good taste**"是个负面的评价，“**not good**”也是一个负面的评价。而不像原来的算法一样，只是把所有的加在一起得到一个大的向量，根本意识不到“**not good**”和 “**good**”不是一个意思，"**lacking in good taste**"也是如此，等等

如果训练一个这样的算法，最后会得到一个很合适的情感分类的算法。由于词嵌入是在一个更大的数据集里训练的，这样会更好的泛化一些没有见过的新的单词。比如"**Completely absent of good taste, good service, and good ambiance.**"，即使**absent**这个词不在标记的训练集里

如果是在一亿或者一百亿单词集里训练词嵌入，它仍然可以正确判断，并且泛化的很好，甚至这些词是在训练集中用于训练词嵌入，但不在专门做情感分类问题标记的训练集

## 2.10 词嵌入除偏（Debiasing Word Embeddings）

根据训练模型所使用的文本，词嵌入能够反映出性别、种族、年龄、性取向等其他方面的偏见：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/25430afa93f24dc6caa6f85503bbad27.png)

假设已经完成一个词嵌入的学习，各个词的位置如图：

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/cf60f429ef532a2b3bbad3db98b054c5.png)

首先做的事就是辨别出想要减少或想要消除的特定偏见的趋势

怎样辨别出偏见相似的趋势：

一、对于性别歧视，对所有性别对立的单词求差值，再平均：

$$
bias\ direction=\frac1N ((e\_{he}-e\_{she})+(e\_{male}-e\_{female})+\cdots)
$$

二、中和步骤，对于定义不确切的词可以将其处理一下，避免偏见。像**doctor**和**babysitter**使之在性别方面中立。将它们在这个轴（编号1）上进行处理，减少或是消除他们的性别歧视趋势的成分，即减少在水平方向上的距离（编号2方框内所示的投影）

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/4102795b004ff090ed83dc654f585852.png)

三、均衡步，**babysitter**和**grandmother**之间的距离或者说是相似度实际上是小于**babysitter**和**grandfather**之间的（编号1），因此这可能会加重不良状态，或者非预期的偏见，也就是说**grandmothers**相比于**grandfathers**最终更有可能输出**babysitting**。所以在最后的均衡步中，想要确保的是像**grandmother**和**grandfather**这样的词都能够有一致的相似度，或者说是相等的距离，做法是将**grandmother**和**grandfather**移至与中间轴线等距的一对点上（编号2），现在性别歧视的影响也就是这两个词与**babysitter**的距离就完全相同了（编号3）

![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/9b27d865dff73a2f10abbdc1c7fc966b.png)

最后，掌握哪些单词需要中立化非常重要。一般来说，大部分英文单词，例如职业、身份等都需要中立化，消除embedding vector中性别这一维度的影响
