Featured image of post 文本处理与词嵌入

文本处理与词嵌入


🚲 转到 https://nlp.letout.cn 🔔 文本处理与词嵌入 ➡️


本节主要内容为 文本处理 Text Processing词嵌入 Word Embedding。本节和下面两节内容都会使用 IMDb 电影评论的数据,用来搭建机器学习模型分析电影评论。

🌱 IMDb

IMDb 是最有名的电影评论网站,用户可以在 IMDb 上给电影打分,1 分是非常讨厌,10 分是非常喜欢,如果乐意,还可以写一段电影评论。

IMDb

如果不给你看分数,只给你看评论,你大概能猜到用户打的分数,但你的猜测可能不太准确。如果换种方式,让你判断电影评论是 正面 positive 的还是 负面 negative 的,你应该会有很高的准确率。有人从 IMDb 上爬了 5 万条电影评论,这些评论都是很极端的,都是强烈的喜欢,或者强烈反感。这个二分类问题对于人来说很简单,人读一下电影评论就能轻易知道这是正面评价还是负面评价,人应该能有 100% 的准确率,这个数据集被分成两半,2 万 5 千条作为训练数据 Train,另外 2 万 5 千条作为测试数据 Test

你可以在下面的链接中获取到数据集:https://ai.stanford.edu/~amaas/data/sentiment/

🔖 文本处理文本处理

在词嵌入 Word Embedding 和搭建机器学习模型之前,首先要进行文本处理,将文本变成序列 Sequence,文本处理很无聊,但我们应该重视它,文本处理的好坏,会直接影响机器学习模型的准确率。

🚀 Tokenization

文本处理的第一步是 Tokenization,把文本分割成很多 tokens,这里我们把文本分割成很多单词,一个 token 就是一个单词(假如你把文本分割成字符,那么一个 token 就是一个字符),做完 Tokenization,一个很长的字符串就被分割成一个很多单词的列表。

1

Tokenization 看起来很简单,但是讲究很多。比如:

  • 🌰 是否应该把大写变成小写?

通常情况下应该把大写变成小写,大小写单词通常是一个意思;但有时候会混淆单词(Apple -> apple),比如 Apple 是苹果公司,apple 是水果,大小写的 apple 并不是相同的单词。

  • 🌰 去除停用词。stop word

有些应用会去除 stop word,它是 the、a、of 等最高频的单词,这些词几乎出现在所有的句子里,对这个二分类问题几乎是没有帮助。

  • 🌰 拼写纠错。

用户发电影评论的时候,大部分情况下并不会仔细检查,所以写的东西难免会有拼写错误,所以做拼写纠错通常是有用的。

这里只是举了几个例子,实际上做 Tokenization 的时候需要做大量的工作,Tokenization 看似简单,但实际上并不容易。

🧰 Build Dictionary

第二步是建立一个字典。可以先统计词频,去掉一些低频词,让后让每个单词对应一个正整数,比如让 the -> 1; cat -> 2; sat -> 3。有了这个字典,就可以把每个单词对应到一个整数,这样一来,一句话就可以用正整数的列表表示,这个列表被称为序列 Sequences

2

如果有必要的话,还得进一步做 one-hot encoding,把单词表示成 one-hot 向量。

在电影评论的例子里,数据是 5 万条电影评论,每条电影评论可以表示成一个字符串。做完 TokenizationEncoding 后,每条电影评论都会转换成一个 Sequences,也就是一个正整数的列表。

3

电影评论有长有短,有人只能写几个字的评论,有人能洋洋洒洒写几千字,所以得到的这些 Sequences 的长度也各不相同。比如这两条 Sequences 的长度分别是 52 和 90。

4

这就造成了一个问题,训练数据没有对齐,每条 Sequences 都有不同的长度。做机器学习的时候,我们需要把数据存储到矩阵或者张量里,每条序列都得有相同的长度,需要把序列对齐。

5

解决方案是这样的:我们可以固定长度为 $w$。假如一个序列长度太长,超过了 $w$ 个词,就砍掉前面的词,只保留最后面 $w$个词(当然保留最前面 $w$ 个词也同样可以);假如一个序列太短,不到 $w$ 个词,那么就做 zero padding 用 0 来补齐,把长度增加到 $w$。

6

这样一来,所有序列的长度都是 $w$,可以存储到一个矩阵里。

🍀️ 词嵌入

文本处理已经完成了,现在每个词都用一个正整数来表示,下一步是 Word Embedding,把每个词都表示为一个一维向量。

现在每个单词都用一个数字来表示,该怎么把这些 Categorical 特征表示为数值向量呢?

显然可以做 one-hot encoding,用一个 one-hot 向量来表示一个单词。 比如 good: index = 2,于是使用标准正交积 $e_2$ 来表示,它的第二个元素是 1,其余元素都是 0,$e_2=[0, 1, 0, 0, …, 0]$

假如 vocabulary = v,也就是说字典里一共有 $v$ 个单词,那么就需要维度 dimension = vone-hot 向量,要是字典里有 1 万个单词,那么这些 one-hot 向量都是 1 万维的,这样的向量维度是在太高了。下一节介绍 RNN 的时候你会看到,RNN 的参数数量正比于输入向量的维度,我们肯定不想让输入的向量是 1 万维的,否则一层 RNN 将会有好几十万个参数。所以我们要做 Word Embedding,把这些高维 one-hot 向量映射到低维向量。

具体做法是吧 one-hot 向量 $e_i$ 乘到参数矩阵 $P^T$ 上,矩阵 $P^T$ 的大小是 $d*v$。其中 $d$ 是词向量的维度,由用户自己决定;$v$ 是 vocabulary,表示字典里单词的数量。

7

矩阵的乘法的结果记做向量 $x_i$,$x_i$ 就是一个词向量,维度是 $d*1$,如果 one-hot 向量 $e$ 的第三个元素是 1,那么 $x_i$ 就是 $P^T$ 矩阵的第三列,可以看出,$P^T$ 矩阵每一列都是一个词向量。

同理,下面这个参数矩阵 $P$ 的每一行都是一个词向量。这个矩阵的行数是 $v$,也就是 vocabulary;每一行对应一个单词,矩阵的列数是 $d$,$d$ 是用户决定的,$d$ 的大小会影响机器学习模型的表现,应该用 交叉验证 Cross Validation 用来选择一个比较好的 $d$。

字典里的第一个词的是 movie,那么第一行就是 movie 的词向量;字典里的第二个词是 good,那么第二行就是 good 的词向量。

8

我们的任务是判断电影评论是正面的还是负面的,这个参数矩阵是从训练数据中学习出来的,所以这些词向量都带有感情色彩,假如这些词向量都是二维的,我们就可以在平面坐标系中标出这些词向量。

9

fantastic; good; fun 这些词向量都带有正面情感,所以这三个词的词向量学出来都比较接近;同理,poor; boring; mediocre 这些词带有负面情感,所以学出来的词同样也应该比较接近,但是这些词的词向量应该远离正面色彩的词向量。像 movie; is 这样的中性词,没有感情色彩,它们应该在中间。

🎐 总结

最后总结一下这一章的内容。

这一节上半部分,说明了文本处理是什么样的。给我们一条电影评论,首先做 Tokenization,把电影评论分割成很多单词,然后把很多单词编码成数字,这样一整条电影评论就可以很多正整数来表示,我们把这个正整数序列叫做 Sequences,就是神经网络中 Embedding 层的输入。由于电影评论的长短不一,得到的 Sequence 的长短也不一样,没办法存储在一个矩阵里,解决方案是 Alignment 对齐。假设最大长度为 20,如果长度大于20,就只保留最后 20 个单词;如果长度不到 20,就用 0 补齐,把长度增加到 20。这样一来,每个 Sequences 长度都相同。