53 语言模型【动手学深度学习v2】

语言模型
- 语言模型是 NLP 中最经典的模型,假设给定长度为 T 的文本序列 x1,x2, ... ,xT(可能是词序列,也可能是字符序列),xt (1 <= t <= T)可以被认为是文本序列在时间步 t 处的观测或者标签。语言模型的目标是估计序列的联合概率 p(x1,x2, ... xT)
- 序列模型的核心就是整个序列文本所出现的概率
语言模型
- 目前所面对的问题是如何对一个文档,甚至是一个词元序列进行建模
- 为了训练语言模型,需要计算单词的概率以及给定前面几个单词后出现某个单词的条件概率(这些概率本质上就是语言模型的参数)
假设训练数据集是一个大型的文本语料库,训练集中词的概率可以根据给定词的相对词频来计算:一种稍微不太精确的方法是统计单词在数据集中的出现次数,然后将其除以整个语料库中的单词总数
- 由于连续单词对的出现频率出现频率低得多,特别是对于一些不常见的单词组合,要想找到足够的出现次数来获得准确的估计可能都不容易
- 对于三个或者更多的单词组合,情况可能会变得更糟,许多合理的三个单词所组成的单词组合可能是存在的,但是在数据集中可能找不到
- 对于上述情况,如果数据集很小,或者单词非常罕见,那么这类单词出现一次的机会可能都找不到,除非能够提供某种解决方案将这些单词组合指定为非零计数,否则将无法在语言模型中使用它们
- 一种常见的策略是执行某种形式的拉普拉斯平滑(Laplace smoothing),在所有的计数中添加一个小常量。但是这样的模型很容易变得无效,因为需要存储所有的计数,而且完全忽略了单词的意思,最后,长单词序列大部分是没出现过的,因此一个模型如果只是简单地统计先前看到的单词序列频率,那么模型面对这种问题肯定是表现不佳的
语言模型的应用
- 做预训练模型(如 BERT,GPT-3):给定大量的文本做预训练,然后训练模型预测整个文本出现的概率,因此能够得到比较多的训练数据(文本不需要进行标注,因此会比图像便宜,只需要拿出一定量的文本即可)来做比较大的模型
- 生成文本,给定前面几个词,不断使用 xt ~ p( xt | x1,x2, ... x(t-1) ) 来生成后续文本(给定前面几个词,不断地采样下一个词,然后一直预测下去),对模型的要求比较高,否则误差会不断累积
- 判断多个序列中哪个更常见:使用语言模型判断哪一个序列出现的概率更高(在打字的时候,输入法自动补全也是根据语言模型来判断句子出现的概率,还可以针对特定用户打字的习惯来进行个性化定制,根据用户之前的使用习惯来进行补全和纠错)
使用计数来建模
- 语言模型可以使用计数来进行建模
假设序列长度为 2 ,可以预测

- n:总词数(或者 token 的个数),也就是采集到的所有样本
- n(x):x 在整个词中出现的个数
- n(x,x'):连续单词对的出现次数
- P(x):统计 x 在数据集中的出现次数,然后将其除以整个语料库中的总词数(这种方法对于频繁出现的单词效果还是不错的)
拓展到序列长度为 3 的情况

N 元语法
- 当序列很长时,因为文本量不够大,很可能 n( x1, ... ,xT) <= 1
- 在序列长度比较长的情况下,可以使用马尔科夫假设
- 对于 N 元语法来说,所要看的子序列的长度是固定的,N 越大,对应的依赖关系越长,精度越高,但是空间复杂度比较大
- 二元语法、三元语法比较常见
如果

成立,则序列上的分布满足一阶马尔科夫性质,且阶数越高,对应的依赖关系就越长
一元语法(unigram)
- 马尔科夫假设中的 τ 为 0 ,也就是说每次计算 xt 的概率时,不用考虑 xt 之前的数据
- 使用一元语法计算 p( x1,x2,x3,x4):可以认为这个序列中每个词是独立的

二元语法(bigram)
- 马尔科夫假设中的 τ 为 1 ,也就是说每次计算 xt 的概率时,只依赖于 x( t-1 ),也就是说每一个词和前面一个词是相关的

三元语法(trigram)
- 马尔科夫假设中的 τ 为 2 ,也就是说每次计算 xt 的概率时,只依赖于 x( t - 1 ) 和 x( t - 2 ),也就是说每一个词和前面两个词是相关的

N 元语法的好处
- 最大的好处是可以处理比较长的序列。如果序列很长的话,很难把它存下来,不可能将序列中任何长度的序列都存下来,这是一个指数级的复杂度
- 所以对于任意长度的序列,N 元语法所扫描的子序列长度是固定的:比如说对于二元语法来说,每次只看长为 2 的子序列,首先将长度为 2 的任何一个词 n(x1,x2)(都来自序列中,假设整个字典中有 1000 个词,则长为 2 的词有 1000*1000=1000,000 种可能性)存下来,然后将每一个词和另外一个词组成的词在文本中出现的概率 n(x1,x2) 全部存起来,再把一个词 n(x1) 出现的概率存起来,最后把 n (也就是1000)存起来
- 查询一个任意长度的序列的时间复杂度为 o(T),T 是序列长度
- N 元语法和 N 是一个指数关系,随着 N 的增大,需要存的东西就会变得很大,所以一元语法使用的不多(一元语法完全忽略掉了时序信息),二元语法、三元语法使用的比较多
- 使用马尔科夫假设的 N 元语法的好处:如果将词存起来,就可以使得计算复杂度变成 o(T)而不是 o(N) ,o(T) 很重要,因为语料库通常会很大,判断一个句子的概率的情况下,每秒钟可能需要做一百万次左右,在语音识别或者是输入法补全的时候需要进行实时的计算,因此计算复杂度非常关键,对于 N 元语法来讲,N 越大,精度越高,但是随着 N 的增大,空间复杂度也会增大,即使是这样,二元语法、三元语法也是非常常见的模型
自然语言统计
停用词(stop words)
- 停用词是指在信息检索中,为节省存储空间和提高搜索效率,在处理自然语言数据(或文本)之前或之后会自动过滤掉某些字或词
读取长序列数据
- 序列数据本质上是连续的,因此当序列变得太长而不能被模型一次性全部处理时,就希望对序列进行拆分以方便模型的读取
总体策略
假设使用神经网络来训练语言模型,模型中的网络一次处理具有预定义长度(例如 n 个时间步)的一个小批量序列
如何随机生成一个小批量数据的特征和标签以供读取?
1、文本序列可以是任意长的,因此任意长的序列可以被划分为具有相同时间步数的子序列
2、训练神经网络时,将这些具有相同步数的小批量子序列输入到模型中
- 假设神经网络一次处理具有 n 个时间步的子序列

- 上图展示了从原始文本序列中获得子序列的所有不同的方式,其中 n 等于 5 ,并且每个时间步的词元对应于一个字符
3、由于可以选择任意偏移量来指示初始位置,因此具有相当大的自由度
- 如果只选择一个偏移量,那么用于训练网络的、所有可能的子序列的覆盖范围将是有限的。因此可以从随机偏移量开始划分序列,来同时获得覆盖性(coverage)和随机性(randomness)
随机采样(random sampling)
- 随机采样中,每个样本都是在原始的长序列上任意捕获的子序列
- 在迭代过程中,来自两个相邻的、随机的、小批量中的子序列不一定在原始序列上相邻
- 语言建模的目标是基于当前所看到的词元预测下一个词元,因此标签是移位了一个词元的原始序列
顺序分区(sequential partitioning)
- 顺序分区:迭代过程中,除了对原始序列可以随机抽样外,还可以保证两个相邻的小批量中的子序列在原始序列上也是相邻的,这种策略在基于小批量的迭代过程中保留了拆分的子序列的顺序
总结
1、语言模型是自然语言处理的关键,语言模型其实就是估计文本序列的联合概率,也是 NLP 领域最常见的应用
2、使用统计方法时通常采用 n元语法,每次看一个长为 n 的子序列来进行计数,对于给定的长序列拆分成很多个连续的长度为 N 的子序列,就能够计算文本序列的联合概率了。n元语法通过截断相关性,为处理长序列提供了一种实用的模型(长序列的问题在于它们很少出现或者从不出现)
3、齐普夫定律(Zipf's law)支配着单词的分布,这个分布不仅适用于一元语法,还适用于其他 n 元语法


- 想要通过计数统计和平滑来建模单词是不可行的,因为这样建模会大大高估尾部单词(即不常用的单词)的频率
4、通过拉普拉斯平滑法可以有效地处理结构丰富而频率不足的低频词词组
5、读取长序列的主要方式是随机采样和顺序分区。在迭代过程中,后者可以保证来自两个相邻的小批量中的子序列在原始序列上也是相邻的
Q&A
- 1、在文本预处理中,所构建的词汇表把文本映射成数字,文本数据量越大,映射的数字也就越大,这些数字还需要做预处理吗?例如归一化处理等。是否对模型有影响?QA P3 - 00:00
- 2、连续单词对是指有固定先后顺序的还是任何顺序都可行呢?QA P3 - 00:41
- 3、n 元语法,n 的增长对空间的增长是指数级的。但如果不存 count 为 0 的词的组合的话,空间复杂度还是 n 吧?也就是把一篇文章从头到尾扫一次就行吧,相当于一个 n 的sliding windowQA P3 - 01:33
- 4、过滤低频次是不是叫长尾效应?QA P3 - 02:54
- 5、中文分词的好坏对结果有影响,ngram 的思维能否用在中文字的维度,而不用分词?QA P3 - 04:06
- 6、o(T),T 指的是什么?QA P3 - 04:43
- 7、请问 n-gram 怎么在广告中当特征?QA P3 - 04:54
- 8、语言 sequence sample ( token 是 word )的时间跨度 T 大概设成多少比较好?如果是中文的话一般又是多少?QA P3 - 07:30
----end----
其他参考
1、《动手学深度学习》,课程安排,https://courses.d2l.ai/zh-v2/assets/pdfs/part-3_2.pdf
2、《动手学深度学习》,https://zh-v2.d2l.ai/chapter_recurrent-neural-networks/language-models-and-dataset.html