词袋模型与 N-gram
人类第一次把文本变成数字的办法:数词,忽略顺序。简单、出奇地有效,而且是一切后来方法都要去比的基线。
假设你想让计算机分辨垃圾邮件和真邮件。计算机只认数字,邮件是文本。你得有个办法把后者变成前者。最古老的答案,至今仍是强力的基线,简单得让人放下戒心:数词,忽略顺序。
这就是词袋模型(bag-of-words)。听起来糙得不可能有用。它有用。
把词数成向量
拿两篇文档,已经预处理成干净的 token:
- 文档 A:
"the cat sat on the mat" - 文档 B:
"the dog sat on the log"
把两篇里出现过的所有词去重,建成词表:[cat, dog, log, mat, on, sat, the]。然后把每篇文档表示成一个计数向量,词表里每个词占一格:
| cat | dog | log | mat | on | sat | the | |
|---|---|---|---|---|---|---|---|
| 文档 A | 1 | 0 | 0 | 1 | 1 | 1 | 2 |
| 文档 B | 0 | 1 | 1 | 0 | 1 | 1 | 2 |
每篇文档现在都是 7 维空间里的一个点。分类器可以量这些向量之间的距离,共词多的文档会落得近。这就是「袋」:你把所有词扔进一个袋子数了数,顺序整个丢掉了。
丢掉顺序为什么还行得通
"dog bites man" 和 "man bites dog" 得到的词袋向量一模一样,这显然是错的。然而对很多任务来说,这几乎无所谓。
判断一封邮件是不是垃圾邮件,只要 viagra、winner、free 这几个词出现过,就是极强的信号,怎么排列都无所谓。把新闻分成体育和财经,quarterback 和 dividend 两个词自己就能干活。在主题级别的任务上,词的出现与否承载了大部分信号,词序承载的很少。词袋利用的正是这一点。
它失效的地方,正是顺序和结构承载意义的地方:情感(「not good」对「good」)、翻译、问答。这些都得等能读序列的模型,也就是后面循环网络出场的地方。
TF-IDF:不是所有词都一样有用
原始计数有偏。常见词在每篇文档里计数都高,于是它们占据了向量,却什么都没区分出来。TF-IDF 通过按信息量给每个词加权来解决这个问题。
两个因子相乘:
- 词频(TF) —— 这个词在本篇文档里出现了多少次。提得越多,权重越大。
- 逆文档频率(IDF) —— 这个词在所有文档里有多罕见。每篇都有的词(比如
the)权重接近零;只在少数几篇里出现的词,权重很高。
效果是:不需要手工维护停用词表,the 自动被压到接近零,而 photosynthesis 这种有区分度的词被放大。TF-IDF 做了二十年搜索引擎和文本分类器的主力,今天依然是一个真正好用的基线。
N-gram:把一点顺序找回来
词袋丢掉了全部序列信息,这有代价。N-gram 把连续的短词串当成单个单位,买回来一部分。
以 "the cat sat" 为例:
- 一元(n=1):
the、cat、sat - 二元(n=2):
the cat、cat sat - 三元(n=3):
the cat sat
现在 not good 成了一个单独的二元 token,与 good 区分开,你的情感分类器终于能分得清它们。最早的语言模型也是靠 N-gram 驱动的:用前 n−1 个词预测下一个词,全靠计数。
问题是组合爆炸。一万词的词表有一亿种可能的二元组、一万亿种可能的三元组。其中绝大多数从不出现,于是向量变得巨大且几乎全是零。这种**稀疏性(sparsity)**就是 N-gram 撞上的墙:窗口稍微拉长,表示就炸掉,根本没法靠它捕捉长程含义。
这些方法永远做不到的事
词袋和 N-gram 有一个共同的致命局限:每个词都是一个孤立的符号。 在计数向量里,cat 和 kitten 的关系,跟 cat 和 democracy 一样远。模型完全没有「某些词意思相近」的概念。它只认精确匹配。
搜「car」检索不到讲「automobiles」的文档。用「excellent」训练出来的分类器,对「superb」一无所知。每个词都是一个独立维度,和其他任何维度都没有关系。这个具体的缺口,正是 word2vec 被发明出来要补的:给词配上稠密向量,让意思相近的词挨在一起。
要点回顾
- 词袋模型把文档表示成词计数,丢掉顺序。粗糙,但在词的出现就承载信号的课题级任务上很强。
- TF-IDF 用词频乘以稀有度给每个词加权,自动压住常见词、放大有区分度的词。
- N-gram 把词序列当成单位来捕捉短程顺序,但会组合爆炸、变得稀疏。
- 共同的缺陷:每个词都是孤立符号,
cat和kitten被当成完全无关。 - 它们至今仍是有用的基线,任何更花哨的方法如果输给它们,都该回头检查。
下一篇: word2vec —— 给词配上稠密向量,让意思相近的词终于挨在一起。