第二部分 · 学习给文本分类

怎样把文本变成模型能用的数据?

从带答案的例子出发,把文字整理成数字特征,再交给模型学习分类。

模型怎样从例子中学习 Lec 3 · Sep 1 · Lec 4 · Sep 3 回顾

假设我们想让模型判断一条评论是好评还是差评。做法是先给它看一些已经标好答案的评论,让它预测,再根据预测的错误调整模型。这就是监督学习(supervised learning)。从逻辑回归到神经语言模型,本课程中的学习过程都可以拆成下面五个部分:

I · 数据
带有答案的例子
共有 \(N\) 对样本 \((x^{(i)}, y^{(i)})\),\(i \in \{1 \ldots N\}\)。输入用向量 \([x_1, \ldots, x_d]\) 表示,也可以使用词向量。
II · 模型
根据输入作出预测
模型计算 \(p(y \mid x)\),也就是给定输入后,某个答案出现的概率。逻辑回归和朴素贝叶斯都是例子。
III · 损失
衡量预测有多差
损失函数给预测打分,错误越严重,惩罚通常越大。例如交叉熵损失 \(L_{CE}\)。
IV · 优化
调整模型,让错误变少
随机梯度下降等算法会修改模型参数,使损失降低。
V · 推断
把学到的模型用于新数据
训练结束后,对测试样本作出预测,再评估结果。

前四部分共同构成训练过程。本页先讲如何准备数据,后面依次介绍模型与损失、如何更新模型,以及如何避免模型只记住训练样本。

文本分类要解决什么问题 Lec 3 · Sep 1

分类就是从预先规定的类别中,为一个输入选出答案。例如,判断邮件是不是垃圾邮件、识别文章的主题或语言、判断评论的情感,都属于文本分类。分类也广泛用于语言之外的预测任务。

  • 输入:一篇文档 \(x\),用一组数值特征表示;同时规定可选的类别集合 \(C = \{c_1, c_2, \ldots, c_J\}\)。
  • 输出:一个预测类别,记作 \(\hat y \in C\)。字母上方的帽子表示这是预测值。
  • 二分类:答案只有两种。训练样本是 \((x^{(i)}, y^{(i)})\),标签 \(y^{(i)} \in \{0, 1\}\)。遇到新输入 \(x_{\text{test}}\) 时,模型给出 \(\hat y_{\text{test}} \in \{0,1\}\)。
  • 多分类:答案超过两种。例如可以用 \(y \in \{0,1,2,3,4\}\) 编码一到五星这五种评分。

为什么先学逻辑回归

逻辑回归(logistic regression)的计算过程比较容易看清,而且其中许多思路会一直用到后面的神经网络中。

  • 它是自然科学和社会科学中常用的数据分析工具。
  • 它适合作为基准模型:先看看一个简单分类器能做到什么程度,再与复杂模型比较。
  • 它可以看成一个单层神经网络,因此也是理解后续模型的起点。
  • 它直接学习给定输入后各标签的概率 \(p(y\mid x)\),属于判别式分类器(discriminative classifier);它并不试图解释输入本身是怎样生成的。
  • 课件还提到朴素贝叶斯(Naïve Bayes)、k 近邻、决策树和支持向量机(SVM)等分类方法。

对于一个样本,输入特征记作 \(x = [x_1, \ldots, x_n]\),每个特征对应一个权重,合起来是 \(w = [w_1, \ldots, w_n]\)。模型利用这些权重作出分类判断,参数有时也统一记作 \(\theta\)。模型形式确定后,需要学习的参数集合也就固定了,因此它属于参数模型(parametric model)。

特征描述文本,权重决定它有多重要 Lec 3 · Sep 1 · Lec 4 · Sep 3 回顾

特征(feature)是从输入中能够测量的属性,例如评论里是否出现某个词。对应的权重(weight)则决定,这个线索会在多大程度上推动模型判断为正面评论。课件给出了下面的例子:

特征权重
\(x_i\):评论中包含 awesome(很棒)+10
\(x_j\):评论中包含 abysmal(糟透了)−10
\(x_k\):评论中包含 mediocre(平庸)−2
\(x_l\):评论中包含 restaurant(餐厅)≈ 0

在这个例子里,“awesome”提供很强的正面线索,“abysmal”提供很强的负面线索,“mediocre”的负面作用较弱,而“restaurant”几乎不影响情感判断。特征可以由人来设计,这称为特征工程(feature engineering);也可以像现代模型那样,让模型自动学习有用的特征。

先把原始文本准备好 Lec 3 · Sep 1

提取特征之前,我们要决定怎样清理文本、怎样把它分成可处理的单元。今天这些选择仍然重要,也能帮助我们理解大语言模型自动完成了哪些步骤。

  • 把文本切成单元。分词(tokenization)负责确定模型处理的基本单元。例如把标点分开,就会将“Happy New Year!”变成“Happy New Year !”。此外,还可以根据任务需要清理多余空格、外部网址或无用的非字母字符;这些是可选的清洗操作,并不是分词必须做的事。
  • 按需要统一词形。例如把“won't”展开成“will not”,把“New York”转成小写的“new york”。词干提取通过去掉部分词形来归并词,例如“tokenization”→“token”;词形还原则尝试恢复词典中的标准形式。
  • 大多数操作都有现成工具,例如 Porter 词干提取器。

把文本变成一组数 Lec 3 · Sep 1

先选定词表

词表决定我们要记录哪些词,也规定每个词在向量中对应哪个位置。

  • 建立一个包含任务所需词语的词典。对于非常常见、又没有提供多少有效信息的停用词(stop words),可以考虑删除;一个词是否有用,要由具体任务决定。
  • 给每个词分配一个编号,例如 are → 2。
  • 事先决定怎样处理词表以外的词:可以丢弃,也可以归入一个“未知词”位置。测试时遇到新词,就会面临与 n-gram 语言模型中 <UNK> 相同的问题。

再决定每个数代表什么

  • 词袋表示记录每个词出现的次数,下面会具体说明。
  • TF-IDF,即词频与逆文档频率的乘积,会调整词的计数,降低那些在许多文档中都常见的词的权重。
  • 词向量(word embeddings)是通过学习得到的稠密向量,课程后面会介绍 word2vec、GloVe 等方法。

词袋:数一数每个词出现了几次 Lec 3 · Sep 1 · Lec 4 · Sep 3 回顾

根据应用选择 \(k\) 个词,组成词表。词袋(bag of words,BoW)为每个词留一个位置,得到整数向量 \(x = [x_1, \ldots, x_k]\),其中 \(x_i \in \{0, 1, 2, \ldots\}\)。如果 \(x_i = j\),就表示第 \(i\) 个词在文档中出现了 \(j\) 次。

把一条衬衫评论写成向量

按这个顺序选定词表:[good, bad, nice, ugly, love, hate, complements, coarse, itchy]。

“I love this shirt because it is nice and warm. The fabric is also nice and the color complements my skin tone.”

其中“nice”出现两次,“love”和“complements”各出现一次,词表中的其他词没有出现。因此,\(x = [0, 0, 2, 0, 1, 0, 1, 0, 0]\)。

为什么使用它它遗漏了什么
构建简单,在不少场景中能取得还不错的效果。计数保留不了词序和局部语境,也不会记录“new”与“york”或“book”之间的搭配关系。多数位置为零,所以向量很稀疏;常见词还可能占据计数的主体。这些局限促使我们使用 TF-IDF,并在合适的任务中删除停用词。

这个思路也能用于图像。视觉词袋(bag of visual words)先把图像中的局部小片段归成离散类型,再用各类片段出现的次数表示整张图像。

这一页要记住什么
  • 学习每个模型时,都可以依次问:它用什么数据,怎样预测,怎样衡量错误,怎样调整参数,以及怎样用于新输入?
  • 文本分类把文档特征变成类别判断。逻辑回归是一个容易理解、也适合用来比较效果的起点。
  • 先准备文本、选定词表,再构建数值表示。词袋保留了词的次数,但没有保留词序。