n元语法(n-gram)
/ EN-gram /
n元语法不过是一个短短的、滑动的窗口,框住连续的 n 个项——通常是 n 个词,有时是 n 个字母。让一个两词宽的窗口在「the cat sat on the mat」上滑过,你就得到一串二元语法(2-gram):「the cat」「cat sat」「sat on」「on the」「the mat」。一个词叫一元语法,两个叫二元,三个叫三元,以此类推。抓取词块而非单个词,妙处在于顺序开始变得重要:「not good」作为一个整体被保留了下来,而单纯的词袋则会把它弄丢。
n元语法支撑着一个关于语言的极简而美妙的想法:你可以靠数「过去通常跟着什么」来猜下一个词。看过海量文本后,程序会注意到「a cup of」后面极常跟「coffee」或「tea」,极少跟「democracy」。数足够多的n元语法,你就有了一个粗糙却真实的语言流动模型——早期的自动补全、拼写纠错和语音识别,正是这么干的。
难处在于一个残酷的取舍。n 越大,捕捉的语境越多,但计数会爆炸:可能的n元语法数量以天文数字增长,而其中绝大多数在你的数据里根本没出现过,于是你永远缺例子(这个问题叫稀疏性)。这道天花板——n元语法顶多只能「看到」往回数的那几个词——恰恰就是神经语言模型被发明出来要打破的,办法是学习平滑的表示,而非脆弱的计数。
从「I really love this」中:一元语法 = I, really, love, this。二元语法 =「I really」「really love」「love this」。一个常见到「really love」的二元模型,能合理地预测下一个会是个褒义词。
滑动一个大小为 n 的窗口,廉价地捕捉了局部词序。
n元语法顶多只能看到几个词的上下文,且随着 n 增大会遭遇严重的数据稀疏。它们是神经网络之前自然语言处理的主力,至今仍是结实的基准——但捕捉不了长距离的语义。