引言

虽然本书的读者应当已具备机器学习(machine learning)的基础知识,但仍有必要从定义入手,以确保我们对全书使用的术语有一致的理解。

下面,我复述《百页机器学习书》(The Hundred-Page Machine Learning Book)第 2 章中的部分定义,并给出若干新定义。如果你读过我的第一本书,本章的某些内容听起来可能会很熟悉。

读完本章后,我们将对监督学习(supervised learning)与无监督学习(unsupervised learning)等概念达成一致的理解;我们将统一数据术语,例如直接使用与间接使用的数据、原始数据(raw data)与整洁数据(tidy data)、训练数据与留出数据。

我们将知道何时该用机器学习、何时不该用,以及机器学习的各种形式,如基于模型的学习(model-based learning)与基于实例的学习(instance-based learning)、深度学习(deep learning)与浅层学习(shallow learning)、分类(classification)与回归(regression)等。

最后,我们将界定机器学习工程(Machine Learning Engineering,MLE)的范畴,并介绍机器学习项目生命周期。

1.1 记号与定义

让我们先说明基本的数学记号,并定义本书中会反复使用的术语与概念。

1.1.1 数据结构

标量(scalar)是简单的数值,如 15 或 -3.25。1 取标量值的变量或常量用斜体字母表示,如 \(x\) 或 \(a\)。

向量(vector)是标量值的有序列表,这些标量值称为属性(attribute)。我们用粗体字符表示向量,例如 \(\mathbf{x}\) 或 \(\mathbf{w}\)。向量既可以可视化为指向某些方向的箭头,也可以可视化为多维空间中的点。图 1 给出了三个二维向量 \(\mathbf{a} = [2, 3]\)、\(\mathbf{b} = [-2, 5]\) 和 \(\mathbf{c} = [1, 0]\) 的插图。我们用带索引的斜体值表示向量的属性,如 \(w^{(j)}\) 或 \(x^{(j)}\)。索引 \(j\) 表示向量的特定维度,即属性在列表中的位置。例如,在图 1 中用红色显示的向量 \(\mathbf{a}\) 中,\(a^{(1)} = 2\),\(a^{(2)} = 3\)。

图 1:将三个向量分别可视化为方向与点。

原书插图

记号 \(x^{(j)}\) 不应与幂运算符混淆,例如 \(x^2\)(平方)中的 2 或 \(x^3\)(立方)中的 3。如果我们要对向量的一个带索引属性应用幂运算符(如平方),应写成 \((x^{(j)})^2\) 的形式。

一个变量可以有两个或更多索引,如 \(x_i^{(j)}\) 或 \(x_{i,j}^{(k)}\)。例如,在神经网络中,我们用 \(x_{l,u}^{(j)}\) 表示第 \(l\) 层中单元 \(u\) 的输入特征 \(j\)。

矩阵(matrix)是按行和列排列的矩形数字阵列。下面是一个两行三列的矩阵示例,

\[ A = \begin{bmatrix} 2 & -2 & 1 \\ 3 & 5 & 0 \end{bmatrix} \]

矩阵用粗体大写字母表示,如 \(\mathbf{A}\) 或 \(\mathbf{W}\)。从上面矩阵 \(\mathbf{A}\) 的示例可以看出,矩阵可以看作由向量组成的规则结构。事实上,上面矩阵 \(\mathbf{A}\) 的各列正是图 1 中所示的向量 \(\mathbf{a}\)、\(\mathbf{b}\) 和 \(\mathbf{c}\)。

集合(set)是无序的唯一元素集合。我们用花体大写字母表示集合,例如 \(\mathcal{S}\)。数集可以是有限的(包含固定数量的值),此时用花括号表示,例如 \(\{1, 3, 18, 23, 235\}\) 或 \(\{x_1, x_2, x_3, x_4, \ldots, x_n\}\)。或者,集合也可以是无限的,包含某个区间内的所有值。如果集合包含 \(a\) 和 \(b\) 之间的所有值(包括 \(a\) 和 \(b\)),则用方括号表示为 \([a, b]\)。如果集合不包含 \(a\) 和 \(b\) 这两个值,则用圆括号表示,如 \((a, b)\)。例如,集合 \([0, 1]\) 包含 0、0.0001、0.25、0.784、0.9995 和 1.0 等值。一个特殊的集合记为 \(\mathbb{R}\),包含从负无穷到正无穷的所有数。

当一个元素 \(x\) 属于集合 \(S\) 时,我们写作 \(x \in S\)。我们可以通过两个集合 \(S_1\) 和 \(S_2\) 的交集得到一个新集合 \(S_3\),此时写作 \(S_3 \leftarrow S_1 \cap S_2\)。例如 \(\{1, 3, 5, 8\} \cap \{1, 8, 4\}\) 得到新集合 \(\{1, 8\}\)。

我们可以通过两个集合 \(S_1\) 和 \(S_2\) 的并集得到一个新集合 \(S_3\),此时写作 \(S_3 \leftarrow S_1 \cup S_2\)。例如 \(\{1, 3, 5, 8\} \cup \{1, 8, 4\}\) 得到新集合 \(\{1, 3, 5, 8, 4\}\)。

记号 \(|S|\) 表示集合 \(S\) 的大小,即它所包含的元素个数。

1.1.2 大写 Σ 求和记号

对集合 \(X = \{x_1, x_2, \ldots, x_{n-1}, x_n\}\) 求和,或对向量 \(\mathbf{x} = [x^{(1)}, x^{(2)}, \ldots, x^{(m-1)}, x^{(m)}]\) 的属性求和,记作:

\[ \sum_{i=1}^{n} x_i \quad \text{或} \quad \sum_{j=1}^{m} x^{(j)} \]

记号 \(\overset{\text{def}}{=}\) 表示"定义为”。

向量 \(\mathbf{x}\) 的欧几里得范数(Euclidean norm),记为 \(\|\mathbf{x}\|\),刻画了向量的"大小"或"长度”。其定义为:

\[ \|\mathbf{x}\| = \sqrt{\sum_{j=1}^{D} (x^{(j)})^2} \]

两个向量 \(\mathbf{a}\) 和 \(\mathbf{b}\) 之间的距离由欧几里得距离(Euclidean distance)给出:

\[ \|\mathbf{a} - \mathbf{b}\| = \sqrt{\sum_{j=1}^{D} (a^{(j)} - b^{(j)})^2} \]

1.2 什么是机器学习

机器学习(machine learning)是计算机科学的一个子领域,关注构建这样的算法:它们要发挥作用,就依赖于某一现象的示例集合。这些示例可以来自自然界、由人类手工制作,或由另一个算法生成。

机器学习也可以定义为通过以下方式解决实际问题的过程:

  • 1)收集数据集,以及
  • 2)基于该数据集用算法训练一个统计模型(statistical model)。

假定这个统计模型会被以某种方式用于解决实际问题。为了省些敲键功夫,我交替使用"学习"和"机器学习"这两个词。出于同样的原因,我也常常用"模型"来指代统计模型。

学习可以是监督学习、半监督学习(semi-supervised learning)、无监督学习和强化学习(reinforcement learning)。

1.2.1 监督学习

在监督学习中,数据分析师(data analyst)处理的是带标签示例的集合 \(\{(x_1, y_1), (x_2, y_2), \ldots, (x_N, y_N)\}\)。\(N\) 个元素中的每个元素 \(x_i\) 都称为特征向量(feature vector)。在计算机科学中,向量是一维数组;一维数组又是有序且有索引的值序列。这个值序列的长度 \(D\) 称为向量的维度(dimensionality)。

特征向量是这样一种向量:其中从 1 到 \(D\) 的每个维度 \(j\) 都包含一个描述该示例的值。每个这样的值称为一个特征(feature),记作 \(x^{(j)}\)。例如,如果集合中的每个示例 \(x\) 代表一个人,那么第一个特征 \(x^{(1)}\) 可以包含以厘米为单位的身高,第二个特征 \(x^{(2)}\) 可以包含以千克为单位的体重,\(x^{(3)}\) 可以包含性别,依此类推。对于数据集中的所有示例,特征向量中位置 \(j\) 处的特征总是包含同一种信息。这意味着,如果某个示例 \(x_i\) 中的 \(x_i^{(2)}\) 包含以千克为单位的体重,那么对于从 1 到 \(N\) 的所有 \(k\),每个示例 \(x_k\) 中的 \(x_k^{(2)}\) 也总是包含以千克为单位的体重。标签 \(y_i\) 可以是属于有限类集合 \(\{1, 2, \ldots, C\}\) 的元素,也可以是实数,或者是更复杂的结构,如向量、矩阵、树或图。除非另有说明,本书中 \(y_i\) 要么是有限类集合中的某一类,要么是一个实数。2 你可以把类(class)理解为示例所属的类别。

例如,如果你的示例是电子邮件,而你的问题是垃圾邮件检测,那么你有两个类:垃圾邮件(spam)和非垃圾邮件(not_spam)。在监督学习中,预测类的问题称为分类(classification),而预测实数的问题称为回归(regression)。监督模型必须预测的值称为目标(target)。回归的一个例子是:根据员工的工作经验和知识来预测其薪水。分类的一个例子是:医生将患者的特征输入软件应用,应用返回诊断结果。

分类与回归的区别如图 2 所示。在分类中,学习算法寻找一条将不同类的示例彼此分开的线(或更一般地,一个超曲面)。而在回归中,学习算法寻找一条尽可能贴近训练示例的线或超曲面。

图 2:分类与回归的区别。

原书插图

监督学习算法的目标是利用数据集生成一个模型:该模型以特征向量 \(x\) 为输入,输出可用于推断该特征向量标签的信息。例如,用患者数据集创建的模型,可以输入描述患者的特征向量,并输出该患者患癌症的概率。

即使模型通常是一个数学函数,在思考模型如何处理输入时,方便的做法是认为模型会"查看"输入中某些特征的值,并根据与相似示例打交道的经验输出一个值。这个输出值是一个数字或一个类,它与此前见过的、具有相似特征值的示例标签"最相似”。这看起来很简单,但决策树(decision tree)模型和 k 近邻(k-Nearest Neighbors,kNN)算法的工作原理几乎就是这样。

1.2.2 无监督学习

在无监督学习中,数据集是无标签示例的集合 \(\{x_1, x_2, \ldots, x_N\}\)。同样,\(x\) 是特征向量,无监督学习算法的目标是创建一个模型:以特征向量 \(x\) 为输入,将其转换为另一个向量,或转换为可用于解决实际问题的值。例如,在聚类(clustering)中,模型为数据集中的每个特征向量返回簇(cluster)的 ID。聚类对于在大规模对象集合(如图像或文本文档)中寻找相似对象组很有用。例如,利用聚类,分析师可以从大型示例集合中抽样出足够有代表性但又较小的无标签子集用于人工标注:从每个簇中抽取少量示例,而不是直接从大型集合中抽样,以免冒着只抽到彼此非常相似的示例的风险。

在降维(dimensionality reduction)中,模型的输出是比输入维度更少的特征向量。例如,科学家有一个过于复杂而无法可视化的特征向量(超过三维)。降维模型可以将该特征向量转换为仅有二维或三维的新特征向量(在一定程度上保留信息)。这个新特征向量可以绘制在图形上。

在异常检测(outlier detection)中,输出是一个实数,表示输入特征向量与数据集中"典型"示例的差异程度。异常检测可用于解决网络入侵问题(通过检测与"正常"流量中的典型数据包不同的异常网络数据包),或用于检测新颖性(例如与集合中现有文档不同的文档)。

1.2.3 半监督学习

在半监督学习中,数据集同时包含有标签和无标签的示例。通常,无标签示例的数量远高于有标签示例的数量。半监督学习算法的目标与监督学习算法的目标相同。这里的期望是:通过使用大量无标签示例,学习算法可以找到(我们也可以说"产生"或"计算出”)更好的模型。

1.2.4 强化学习

强化学习(reinforcement learning)是机器学习的一个子领域,其中机器(称为智能体(agent))“生活"在环境中,并能够将该环境的状态感知为特征向量。机器可以在非终止状态下执行动作。不同的动作带来不同的奖励,也可能把机器移动到环境的另一个状态。强化学习算法的一个常见目标是学习最优策略(optimal policy)。

最优策略是一个函数(类似于监督学习中的模型):以状态的特征向量为输入,输出在该状态下应执行的最优动作。如果该动作能最大化期望的平均长期奖励,那么它就是最优的。

强化学习解决的是决策是顺序的、目标是长期性的特定问题,如游戏、机器人、资源管理或物流。

在本书中,为简单起见,大部分讲解局限于监督学习。然而,本书介绍的所有内容都适用于其他类型的机器学习。

1.3 数据与机器学习术语

现在我们来介绍常见的数据术语(如直接使用和间接使用的数据、原始数据和整洁数据、训练数据和留出数据)以及与机器学习相关的术语(如基线、超参数、流水线等)。

1.3.1 直接使用与间接使用的数据

在机器学习项目中,你使用的数据可以直接或间接地用于构成示例 \(x\)。

设想我们构建一个命名实体识别(named entity recognition)系统。模型的输入是单词序列,输出是与输入等长的标签3 序列。为了使数据可被机器学习算法读取,我们必须将每个自然语言单词转换为机器可读的属性数组,我们称之为特征向量。4 特征向量中的某些特征可能包含将该特定单词与词典中其他单词区分开来的信息。其他特征可以包含该单词在该特定序列中的附加属性,如其形态(小写、大写、首字母大写等)。也可以是一些二元属性,指示该单词是否是某个人名的第一个词,或某个地名或组织名的最后一个词。为了创建后面这些二元特征,我们可能决定使用一些词典、查找表、地名录(gazetteer)或其他对单词做预测的机器学习模型。

你可能已经注意到,单词序列的集合是直接用于构成训练示例的数据,而词典、查找表和地名录中包含的数据是间接使用的:我们可以用它来为特征向量增加额外特征,但不能用它来创建新的特征向量。

1.3.2 原始数据与整洁数据

正如我们刚才讨论的,直接使用的数据是构成数据集基础的实体集合。该集合中的每个实体都可以转换为一个训练示例。原始数据(raw data)是自然形态的实体集合;它们不一定能直接用于机器学习。例如,Word 文档或 JPEG 文件都是原始数据;机器学习算法不能直接使用它们。5

要能用于机器学习,数据的必要(但不充分)条件是整洁。整洁数据(tidy data)可以看作一张电子表格,其中每一行代表一个示例,每一列代表示例的各种属性,如图 3 所示。有时原始数据本身就可以是整洁的,例如以电子表格形式提供给你的数据。然而在实践中,为了从原始数据获得整洁数据,数据分析师常常诉诸一个称为特征工程(feature engineering)的过程,它应用于直接数据,也可选地应用于间接数据,目标是将每个原始示例转换为特征向量 \(x\)。第 4 章将专门讨论特征工程。

图 3:整洁数据:示例为行,属性为列。

原书插图

原书插图

这里需要指出的是,对于某些任务,学习算法使用的示例可以是向量序列、矩阵或矩阵序列的形式。这类算法的数据整洁性概念的定义类似:你只需把"电子表格中宽度固定的行"替换为"宽度和高度固定的矩阵”,或替换为矩阵向更高维度的推广——称为张量(tensor)。

“整洁数据"一词由 Hadley Wickham 在他同名论文中首创。6

正如我在本小节开头提到的,数据可以是整洁的,但仍然不能被某个特定的机器学习算法使用。事实上,大多数机器学习算法只接受数值特征向量集合形式的训练数据。考虑图 3 所示的数据。属性"Region(地区)“是类别型的,不是数值型的。决策树学习算法可以使用类别型的属性值,但大多数学习算法不能。在第 4 章的 §?? 中,我们将看到如何将类别型属性转换为数值型特征。

请注意,在学术机器学习文献中,“示例"一词通常指整洁数据示例,并可选择性地带有标签。然而,在数据收集和标注阶段(我们将在下一章讨论),示例仍可以是原始形式:图像、文本或电子表格中带类别型属性的行。在本书中,当需要强调区别时,我会说"原始示例(raw example)“来表明一条数据尚未转换为特征向量。否则,就假定示例具有特征向量的形式。

1.3.3 训练集与留出集

在实践中,数据分析师处理三个不同的示例集合:

  • 1)训练集(training set),
  • 2)验证集(validation set),7 以及
  • 3)测试集(test set)。

一旦你以示例集合的形式拿到了数据,机器学习项目要做的第一件事就是打乱示例的顺序,并把数据集分成三个不同的集合:训练集、验证集和测试集。训练集通常最大;学习算法用训练集来生成模型。验证集和测试集大小大致相同,比训练集小得多。学习算法不允许使用验证集或测试集中的示例来训练模型。这就是为什么这两个集合也被称为留出集(holdout sets)。

要有三个集合而不是一个,原因很简单:训练模型时,我们不希望模型只擅长预测学习算法已经见过的示例的标签。一个仅仅记住所有训练示例、然后利用记忆"预测"其标签的琐碎算法,在预测训练示例的标签时不会出错。然而,这样的算法在实践中毫无用处。我们真正想要的是一个擅长预测学习算法没见过的示例的模型。换句话说,我们希望在留出集上取得良好表现。8

我们需要两个留出集而不是一个,是因为我们用验证集来:1)选择学习算法,2)为该学习算法寻找最佳的配置值(即所谓的超参数(hyperparameters))。我们用测试集在把模型交付给客户或投入生产之前评估模型。这就是为什么必须确保验证集或测试集的任何信息都不会暴露给学习算法。否则,验证和测试结果很可能过于乐观。这种情况确实可能发生,原因就是数据泄漏(data leakage),这是我们在第 3 章的 §?? 及后续章节中讨论的一个重要现象。

1.3.4 基线

在机器学习中,基线(baseline)是解决某个问题的简单算法,通常基于启发式规则、简单的汇总统计、随机化或非常基础的机器学习算法。例如,如果你的问题是分类,你可以选择一个基线分类器并衡量其性能。这个基线性能将变成你比较任何未来模型(通常是用更复杂的方法构建的)的参照。

1.3.5 机器学习流水线

机器学习流水线(machine learning pipeline)是对数据集从初始状态到模型的一系列操作序列。

流水线可以包括(除其他阶段外):数据划分、缺失数据填补(missing data imputation)、特征提取、数据增强(data augmentation)、类别不平衡消减、降维和模型训练等阶段。

在实践中,当我们把模型部署到生产环境时,通常部署的是整条流水线。此外,调优超参数时通常也是对整个流水线进行优化。

1.3.6 参数与超参数

超参数(hyperparameters)是机器学习算法或流水线的输入,它们影响模型的性能。它们不属于训练数据,也无法从训练数据中学习。例如,决策树学习算法中树的最大深度、支持向量机中的误分类惩罚、k 近邻算法中的 k、降维的目标维度,以及缺失数据填补技术的选择,都是超参数的例子。

另一方面,参数(parameters)是定义学习算法所训练模型的变量。参数由学习算法根据训练数据直接修改。学习的目标是找到使模型在某种意义下最优的参数值。参数的例子有线性回归方程 \(y = wx + b\) 中的 \(w\) 和 \(b\)。在这个方程中,\(x\) 是模型的输入,\(y\) 是模型的输出(预测值)。

1.3.7 分类与回归

分类(classification)是自动为无标签示例分配标签的问题。垃圾邮件检测就是分类的一个著名例子。

在机器学习中,分类问题由分类学习算法解决:它输入带标签示例的集合,生成一个模型,该模型可以输入无标签示例,要么直接输出标签,要么输出一个分析师可以用来推断标签的数字。这种数字的一个例子是输入数据元素具有特定标签的概率。

在分类问题中,标签是有限类集合中的一个成员。如果类集合的大小为二(“生病”/“健康”、“垃圾邮件”/“非垃圾邮件”),我们称之为二分类(binary classification)(有些资料中也称为二项分类(binomial))。多分类(multiclass classification)(也称为多项分类(multinomial))是包含三个或更多类的分类问题。9

虽然有些学习算法天然支持两个以上的类,但另一些本质上是二分类算法。有一些策略可以把二分类学习算法变成多分类算法。我将在第 6 章的 §?? 中介绍其中之一:一对多(one-versus-rest)。

回归(regression)是根据无标签示例预测实数值量的问题。根据房屋特征(如面积、卧室数量、位置等)估算房价,就是回归的一个著名例子。

回归问题由回归学习算法解决:它输入带标签示例的集合,生成一个模型,该模型可以输入无标签示例并输出一个目标值。

1.3.8 基于模型的学习与基于实例的学习

大多数监督学习算法是基于模型(model-based)的。一个典型的模型是支持向量机(Support Vector Machine,SVM)。基于模型的学习算法使用训练数据创建一个模型,其参数从训练数据中学习。在 SVM 中,两个参数是 \(w\)(一个向量)和 \(b\)(一个实数)。模型训练完成后,可以保存在磁盘上,而训练数据可以丢弃。

基于实例(instance-based)的学习算法把整个数据集当作模型。实践中常用的一种基于实例的算法是 k 近邻(k-Nearest Neighbors,kNN)。在分类中,为了预测输入示例的标签,kNN 算法查看输入示例在特征向量空间中的邻近区域,并输出在这个邻近区域中出现次数最多的标签。

1.3.9 浅层学习与深度学习

浅层学习(shallow learning)算法直接从训练示例的特征中学习模型参数。大多数机器学习算法都是浅层的。众所周知的例外是神经网络学习算法,特别是那些构建输入与输出之间有一层以上隐藏层的神经网络的算法。这样的神经网络称为深度神经网络(deep neural network)。在深度神经网络学习(或简称为深度学习(deep learning))中,与浅层学习相反,大多数模型参数不是直接从训练示例的特征中学习,而是从前一层的输出中学习。

1.3.10 训练与评分

当我们把机器学习算法应用于数据集以获得模型时,我们称之为模型训练(model training),或简称为训练(training)。

当我们把训练好的模型应用于输入示例(有时是示例序列),以获得预测(或一些预测),或以某种方式转换输入时,我们称之为评分(scoring)。

1.4 何时使用机器学习

机器学习是解决实际问题的强大工具。然而,像任何工具一样,它应该在合适的场合使用。试图用机器学习解决所有问题将是一个错误。

在下列情形之一,你应该考虑使用机器学习。

1.4.1 当问题过于复杂、无法用编码解决时

在问题过于复杂或庞大、你无法指望写出所有规则来解决它,而部分解决方案又可行且有价值的情况下,你可以尝试用机器学习来解决问题。

一个例子是垃圾邮件检测:不可能写出实现"有效检测垃圾邮件、同时让真实邮件到达收件箱"这种逻辑的代码。需要考虑的因素太多了。例如,如果你的垃圾邮件过滤器编程为拒绝所有不在你通讯录中的人发来的邮件,你就可能丢失某位在会议上拿到你名片的人发来的邮件。如果你对包含与你工作相关的特定关键词的邮件做例外处理,你可能会漏掉孩子老师发来的邮件,如此等等。

如果你仍然决定直接为这个复杂问题编写解决方案,随着时间推移,你的代码中会出现如此多的条件和例外,以至于维护该代码最终会变得不可行。在这种情况下,在"垃圾邮件”/“非垃圾邮件"示例上训练分类器似乎是合乎逻辑且唯一可行的选择。

编写代码解决问题的另一个困难在于:人类很难处理基于参数过多输入的预测问题;当这些参数以未知方式相互关联时尤其如此。例如,考虑预测借款人是否会偿还贷款的问题。每个借款人都由数百个数字表示:年龄、薪水、账户余额、过去还款的频率、是否已婚、子女数量、汽车的品牌和年份、抵押贷款余额等等。其中一些数字可能对决策很重要,一些单独来看不那么重要,但与另一些数字组合考虑时会变得更加重要。

编写做出此类决策的代码很困难,因为即便是专家,也不清楚如何以最优方式将描述一个人的所有属性组合成一个预测。

1.4.2 当问题不断变化时

有些问题会随时间不断变化,因此编程代码必须定期更新。这会导致从事该问题的软件工程师感到沮丧、引入错误的可能性增加、“旧"逻辑与"新"逻辑难以结合,以及测试和部署更新解决方案的大量开销。

例如,你可能有一个从一组网页中抓取特定数据元素的任务。假设对于该集合中的每个网页,你编写一组固定形式的数据提取规则:“从 <body> 中选取第三个 <p> 元素,然后从该 <p> 内的第二个 <div> 中提取数据。“如果网站所有者更改了网页设计,你要抓取的数据可能会跑到第二个或第四个 <p> 元素中,从而使你的提取规则失效。如果你抓取的网页集合很大(数千个 URL),每天都会有规则失效;你将陷入无休止地修复这些规则的境地。不用说,很少有软件工程师愿意每天都做这种工作。

1.4.3 当它是感知类问题时

今天,很难想象有人会在不使用机器学习的情况下尝试解决语音、图像和视频识别等感知类问题。以图像为例。它由数百万像素表示。每个像素由三个数字给出:红、绿、蓝通道的强度。过去,工程师试图通过对像素的方形区域应用手工制作的"过滤器"来解决图像识别问题(检测图片中有什么)。如果一个过滤器——例如为"检测"草地而设计的过滤器——在应用到许多像素区域时产生高值,而另一个为检测棕色皮毛而设计的过滤器对许多区域也返回高值,那么我们可以说,这张图片有很大可能表现的是一头牛在田野里(我稍微简化了一点)。

今天,感知类问题都是用机器学习模型(如神经网络)有效解决的。我们将在第 6 章讨论训练神经网络的问题。

1.4.4 当它是尚未被研究透彻的现象时

如果我们需要对某种在科学上尚未被充分研究、但其示例可观察到的现象做出预测,那么机器学习可能是一个合适的选择(在某些情况下,甚至是唯一可用的选择)。例如,机器学习可用于根据患者的基因和感觉数据生成个性化的心理健康药物选择。医生未必能解读此类数据以给出最优建议,而机器可以通过分析数千名患者来发现数据中的模式,预测哪种分子最有可能帮助给定的患者。

可观察但未被研究透彻的现象的另一个例子是复杂计算系统或网络的日志。这些日志由多个独立或相互依赖的进程生成。对人类来说,在没有对每个进程及其相互依赖关系建模的情况下,仅凭日志预测系统的未来状态是很困难的。如果历史日志记录示例的数量足够多(通常如此),机器可以学习隐藏在日志中的模式,并在不了解每个进程的情况下做出预测。

最后,根据人们可观察的行为来预测其行为是困难的。在这个问题中,我们显然无法拥有一个人大脑的模型,但我们很容易获得一个人思想表达的示例(以在线帖子、评论和其他活动的形式)。仅基于这些表达,部署在社交网络中的机器学习模型就可以推荐内容或推荐值得联系的人。

1.4.5 当问题具有简单的目标时

机器学习特别适合解决可以表述为简单目标的问题:例如是/否决策或单个数字。相比之下,你不能用机器学习来构建一个像《马里奥》这样的通用视频游戏,或像 Word 这样的文字处理软件。这是因为需要做出的决策太多:显示什么、在哪里显示、何时显示、对用户输入应做出什么反应、向硬盘写入什么或从硬盘读取什么,等等;获取能说明所有这些(甚至大部分)决策的示例实际上是不可行的。

1.4.6 当它成本效益合算时

机器学习的三大成本来源是:

  • 收集、准备和清洗数据,
  • 训练模型,
  • 构建并运行用于服务和监控模型的基础设施,以及维护它所需的人力资源。

训练模型的成本包括人力,在某些情况下还包括训练深度模型所需的昂贵硬件。模型维护包括持续监控模型以及收集额外数据以保持模型最新。

1.5 何时不应使用机器学习

有大量问题无法用机器学习解决;很难把它们全部刻画出来。这里我们只考虑几点提示。

在以下情况下,你可能不应该使用机器学习:

  • 系统的每个动作或其做出的每个决策都必须可解释,
  • 系统出错代价太高,
  • 系统行为与其在过去类似情境中的行为相比的任何变化都必须可解释,
  • 你想尽快进入市场,
  • 你可以用传统软件开发以更低的成本解决该问题,
  • 获取正确的数据太难或不可能,
  • 一个简单的启发式方法就能表现得相当好,
  • 你构建的系统未来不需要频繁改进,
  • 现象有太多可能的结果,而你无法获得足够多的示例来代表它们(如视频游戏或文字处理软件),
  • 你可以通过为任何输入提供预期输出来手动填写一份详尽的查找表(也就是说,可能的输入值数量不是太大,或者获取输出的速度很快、成本很低)。

1.6 什么是机器学习工程

机器学习工程(Machine Learning Engineering,MLE)是运用机器学习和传统软件工程的科学原理、工具和技术来设计和构建复杂计算系统。MLE 涵盖从数据收集、模型训练,到使模型可供产品或客户使用等所有阶段。

通常,数据分析师10 关注的是理解业务问题、构建模型来解决它,以及在受限的开发环境中评估模型。而机器学习工程师关注的是从各种系统和位置获取数据并对其进行预处理、编程实现特征、训练一个有效的模型——该模型要在生产环境中运行、与其他生产流程良好共存、稳定、可维护,并且便于不同类型、不同用例的用户访问。

换言之,MLE 包括任何让机器学习算法得以作为有效生产系统一部分来实施的活动。

在实践中,机器学习工程师可能从事这样的活动:把数据分析师的代码从相当慢的 R 和 Python11 重写为更高效的 Java 或 C++,扩展这些代码并使其更健壮,把代码打包成易于部署的带版本号的包,优化机器学习算法以确保它生成的模型与组织的生产环境兼容并能正确运行。

在许多组织中,数据分析师会执行一些 MLE 任务,如数据收集、转换和特征工程。另一方面,机器学习工程师也常常执行一些数据分析任务,包括学习算法选择、超参数调优和模型评估。

从事机器学习项目不同于从事典型的软件工程项目。与行为通常是确定性的传统软件不同,机器学习应用包含的模型其行为可能随时间自然退化,或者可能开始表现异常。模型的这种异常行为可能由多种原因造成,包括输入数据的根本性变化,或更新后的特征提取器现在返回不同分布的值或不同类型的值。人们常说机器学习系统"无声地失败”。机器学习工程师必须能够预防此类失败,或者在无法完全预防时,知道在失败发生时如何检测和处理它们。

1.7 机器学习项目生命周期

机器学习项目始于理解业务目标。通常,业务分析师(business analyst)与客户12 和数据分析师合作,把业务问题转化为工程项目。工程项目可以包含机器学习部分,也可以不包含。在本书中,我们当然只考虑包含机器学习内容的工程项目。

一旦工程项目被定义,机器学习工程的范畴就从这里开始。在更广泛的工程项目范围内,机器学习首先必须有一个明确界定的目标(goal)。机器学习的目标是对以下内容的说明:统计模型接收什么输入、生成什么输出,以及模型行为可接受(或不可接受)的标准。

机器学习的目标不一定与业务目标相同。业务目标是组织想要实现的东西。例如,Google 在 Gmail 上的业务目标可以是让 Gmail 成为世界上使用最多的电子邮件服务。Google 可能会创建多个机器学习工程项目来实现这一业务目标。其中某个机器学习项目的目标可以是:以超过 90% 的准确率区分主邮箱(Primary)邮件和推广(Promotions)邮件。

图 4:机器学习项目生命周期。

原书插图

总的来说,机器学习项目生命周期如图 4 所示,包含以下阶段:1)目标定义,2)数据收集与准备,3)特征工程,4)模型训练,5)模型评估,6)模型部署,7)模型服务(model serving),8)模型监控,9)模型维护。

在图 4 中,机器学习工程的范畴(以及本书的范畴)以蓝色区域为界。实线箭头显示项目阶段的典型流程。虚线箭头表示在某些阶段,可以决定回到流程中,要么收集更多数据,要么收集不同的数据,并修改特征(停用其中一些特征并工程化新特征)。

上面提到的每个阶段都将在本书的一章中讨论。但首先,让我们讨论如何对机器学习项目进行优先级排序、定义项目目标以及组建机器学习团队。下一章将专门讨论这三个问题。

1.8 小结

基于模型的学习算法输入一组训练示例并输出一个模型。基于实例的学习算法将整个训练数据集用作模型。训练数据会暴露给机器学习算法,而留出数据不会。

监督学习算法构建的模型接收特征向量并输出关于该特征向量的预测。无监督学习算法构建的模型接收特征向量作为输入并将其转换为有用的东西。

分类是根据输入示例预测有限类集合中某一类的问题。回归则是预测数值型目标的问题。

数据可以直接使用,也可以间接使用。直接使用的数据是形成示例数据集的基础。间接使用的数据用于丰富这些示例。

用于机器学习的数据必须是整洁的。整洁的数据集可以看作一张电子表格,其中每一行是一个示例,每一列是示例的某个属性。除了整洁之外,大多数机器学习算法还要求数值型数据而非类别型数据。特征工程是将数据转换为机器学习算法可用形式的过程。

基线对于确保模型比简单启发式方法表现更好至关重要。

在实践中,机器学习以流水线的形式实现,流水线包含一系列串联的数据转换阶段:从数据划分、缺失数据填补,到类别不平衡和降维处理,再到模型训练。通常会对整条流水线的超参数进行优化;整条流水线可以被部署并用于预测。

模型的参数由学习算法根据训练数据优化。超参数的值无法由学习算法学习,需要利用验证数据集来调优。测试集仅用于评估模型性能,并向客户或产品负责人汇报。

浅层学习算法训练的模型直接从输入特征做出预测。深度学习算法训练的是分层模型,其中每一层以紧邻前一层的输出为输入来生成输出。

当问题过于复杂、无法用编码解决时,当问题不断变化时,当它是感知类问题时,当它是尚未被研究透彻的现象时,当问题具有简单的目标时,以及当它成本效益合算时,你应该考虑使用机器学习来解决业务问题。

在很多情况下可能不应使用机器学习:需要可解释性时、错误不可容忍时、传统软件工程是更便宜的选择时、所有输入和输出都可以枚举并存入数据库时,以及数据难以获取或成本过高时。

机器学习工程(MLE)是运用机器学习和传统软件工程的科学原理、工具和技术来设计和构建复杂计算系统。MLE 涵盖从数据收集、模型训练,到使模型可供产品或消费者使用等所有阶段。

机器学习项目生命周期包括以下阶段:1)目标定义,2)数据收集与准备,3)特征工程,4)模型训练,5)模型评估,6)模型部署,7)模型服务,8)模型监控,9)模型维护。

每个阶段都将在本书的一章中讨论。


《机器学习工程》(Machine Learning Engineering)

Andriy Burkov(安德烈·布尔科夫)

“理论上,理论与实践没有区别;但在实践中,有区别。"——本杰明·布鲁斯特(Benjamin Brewster)

“完美的项目计划是可能的,只要你先把所有未知项列成一份清单。"——比尔·兰利(Bill Langley)

“融资时它是 AI,招聘时它是 ML,实现时它是线性回归,调试时它是 printf()。"——巴伦·施瓦茨(Baron Schwartz)

本书按"先读后买”(read first, buy later)的原则发行。


  1. 如果某个术语以粗体显示,表示该术语可以在书末的索引中找到。 ↩︎

  2. 实数是可以在一条直线上表示距离的量。例如:0、-256.34、1000、1000.2。 ↩︎

  3. 标签可以是例如集合 {‘Location’, ‘Organization’, ‘Person’, ‘Other’} 中的值。 ↩︎

  4. 术语"属性(attribute)“和"特征(feature)“经常互换使用。在本书中,我用"属性"来描述示例的特定性质,而"特征"指机器学习算法使用的特征向量 \(x\) 中位置 \(j\) 处的值 \(x^{(j)}\)。 ↩︎

  5. 术语"非结构化数据(unstructured data)“常用来指代包含类型未正式定义信息的数据元素。非结构化数据的例子有照片、图像、视频、短信、社交媒体帖子、PDF、文本文档和电子邮件。术语"半结构化数据(semi-structured data)“指其结构有助于推导其中编码的某些信息类型的数据元素。半结构化数据的例子包括日志文件、逗号和制表符分隔的文本文件,以及 JSON 和 XML 格式的文档。 ↩︎

  6. Wickham, Hadley. “Tidy data.” Journal of Statistical Software 59.10 (2014): 1-23. ↩︎

  7. 在某些文献中,验证集也被称为"开发集(development set)"。有时,当带标签的示例稀缺时,分析师可以决定不使用验证集,正如我们在第 5 章交叉验证(cross-validation)一节中看到的。 ↩︎

  8. 准确地说,我们希望模型在我们数据所属的统计分布的大多数随机样本上表现良好。我们假设,如果模型在一个从我们数据的未知分布中随机抽取的留出集上表现出良好的性能,那么我们的模型在其他数据随机样本上也很可能表现良好。 ↩︎

  9. 不过,每个示例仍然只有一个标签。 ↩︎

  10. 大约从 2013 年起,“数据科学家(data scientist)“成为一个流行的职位头衔。不幸的是,公司和专家对这个词的定义没有达成一致。因此,我使用"数据分析师"一词,指能够对已准备好进行分析的数据应用数值或统计分析的人。 ↩︎

  11. Python 中的许多科学模块确实是用快速的 C/C++ 实现的;然而,数据分析师自己写的 Python 代码仍然可能很慢。 ↩︎

  12. 如果机器学习项目支撑的是组织开发并销售的产品,那么业务分析师将与产品负责人(product owner)合作。 ↩︎