其它章节内容请见机器学习之PyTorch和Scikit-Learn
在作者的心目中,机器学习这一解释推理数据的应用和算法科学,是计算机科学中最令人振奋的领域!我们生活在数据多到泛滥的时代,使用机器学习领域的自学习算法 ,可以将数据转换为知识。借助近些年来开发的众多开源库,我们迎来了进入机器学习领域最好的时代,可以学习利用强大的算法来一窥数据的模式并对未来事件进行预测。
本章中我们将学习机器学习的主要概念及其不同类型。伴随着对相关术语的基础介绍,我们为成功使用机器学习解决实际问题打好基础。
本章中主要讲解如下内容:
- 机器学习的主要概念
- 机器学习的三种类型以及基本术语
- 成功设计机器学习系统的组成部分
- 安装、配置Python进行数据分析和机器学习
构建智能机器将数据转化为知识
现代科技发展至今,有一种资源浩如烟海:大量的结构化和非结构化数据。20世纪下半叶,机器学习演进为人工智能(AI)的子学科,包含自学习算法从数据中提取知识来进行预测。
机器学习没有要求人工分析大量数据提取规则、构建模块,而是提供了众多高效的方法从数据中捕获知识进而提升预测模型的性能并通过数据驱动决策。
机器学习不仅在计算机科学研究中越来越重要,在日常生活中也发挥着越来越重要的作用。因为有了机器学习,我们享受着健壮的垃圾邮件过滤器、便捷的文本和语音识别软件、可行的网页搜索引擎、优秀电影推荐、移动支付、送餐时间预测等等。还有望在不久的将来迎来安全高效的自动驾驶技术。同时在医疗领域也取得了长足的进步,比如研究人员演示了通过深度学习模型可监测出皮肤癌,精度可与人工相媲美(https://www.nature.com/articles/nature21056)。另一项由DeepMind研究人员实现的里程碑是使用深度学习来预测3D蛋白结构,甩出物理方式几条街 (https://deepmind.com/blog/article/alphafold-a-solution-to-a-50-year-old-grand-challenge-in-biology)。精确的蛋白质结构预测在生物制药研究中发挥中举足轻重的作用,在医疗保健领域还有很多其它的机器学习应用。比如,研究人员设计了一套系统提前4天预测新冠病人所需的氧气来辅助医院添置所需的资源 (https://ai.facebook.com/blog/new-ai-research-to-help-predict-covid-19-resource-needs-from-a-series-of-x-rays/)。如今另一个重要的话题是气候变化,它是我们所面临的巨大挑战之一。现在投入了很多资源来开发智能系统 应对这一问题 (https://www.forbes.com/sites/robtoews/2021/06/20/these-are-the-startups-applying-ai-to-tackle-climate-change)。其中一种应对气候变化的方法是新兴的精准农业。研究人员设计了基于计算机视觉的机器学习系统来将肥料的使用和浪费降至最低。
机器学习的三种类型
本节中我们来学习机器学习的三种类型:监督学习、无监督学习和强化学习。我们会学习三种类型的不同点,通过概念示例,我们会进一步了解它们所适用的实际领域:
图1.1: 机器学习的三种类型
通过监督学习预测未来
监督学习的主要目的是通过打好标签的训练数据来对未来进行预测。这里的“监督”是指训练样例(输入数据)中期望的输出信号(标签)是已知的。然后监督学习生成输入数据和标签关联的模型。因此可以把监督学习看成是“标签学习”。
图1.2中总结了典型的监督学习工作流,其中将带标签的训练数据传递给机器学习算法来拟合出预测模型,以便对新的无标签数据进行预测:
图1.2: 监督学习流程
设想下垃圾邮件过滤的场景,我们可以使用监督机器学习算法对一组打过标签的邮件来训练出一个能正确标记出垃圾邮件和正常邮件的模型,进而预测新收到的邮件属于哪一类。带有离散分类标签的监督学习任务,比如我们所举的垃圾邮件过滤的例子,也被称为分类任务。监督学习的另一个分支是回归,其结果信号是一个连续值。
使用分类预测分类标签
分类是监督学习的一个子类,目标是根据过往观察预测出新实例或数据点的分类标签。这些分类标签为离散的无序值,可以理解成数据点的分组成员。前述的垃圾邮件监测就是典型的二元分类任务,机器学习算法学习一组规则来分辨两种可能的分类:垃圾邮件和正常邮件。
图1.3中描述了30个训练样例二元分类任务的概念,15个训练样例标记为A类,另外15个训练样例标记为B类。在这一场景中,数据集是二维的,即每个样例有两个关联值:x1和x2。这时我们可以使用机器学习算法来学习一套规则-使用虚线标记出的决策边界-来分出两类并根据新数据的x1和x2值将其划为其中一类:
图1.3:对新数据集进行分类
但分类标签不一定要是二元的。由监督学习算法预测出的模型可将训练数据集中的任一分类标签分配给未标记的新数据点或实例。
经典的多元分类的例子是手写文字识别。我们可以收集由不同字母组成的多个手写样例训练集。字母((“A,” “B,” “C,”等 )表示需要预测的不同无序分类或类标签。这时用户通过输入设备提供了新的手写文字,预测模型就能预测出正确的字母,达到一定的准确度。但如果数字0到9不在训练集中,机器学习系统就无法识别它们。
预测连续结果的回归
在前面的小节中我们学习了分类任务是对实例分配分类、无序标签。监督学习的第二种类型是对续结果的预测,也称为回归分析。在回归分析中,会给定一些预测(解释)变量和持续响应变量(结果),然后通过这些变量间的关联预测出结果。
在机器学习领域,预测变量通常称为“特征”,响应变量通常称为“目标变量”。在本书中我们会遵照这一惯例。
举个例子,假设想要预测出学生的SAT数学成绩。(SAT常被称为“美国高考”。)如果学生在学习上花费的时间和最终分数之间存在关联,我们就可以将其用作训练数据,训练出一套模型来根据学习的时长预测备考学生未来的成绩。
回归算术平均
“回归”一词来自英国遗传学习Francis Galton于1886年发表的论文《遗传身高的平庸回归》(Regression towards Mediocrity in Hereditary Stature)。Galton发现了人类的身高变化并没有随时间增加的生物现象。
他观察到父母的身高并没有传递给子女,而是子女身高回归到一个平均水平。
图1.4中描述了线性回归的概念。给定特征变量x和目标变量y,我们为数据拟合出了一条最小化距离的直线,常称为(数据点和拟合直线间的)均方距离。
这时我们可以使用通过数据学习的交点和斜线来预测出新数据的目标变量:
图1.4: 线性回归示例
使用强化学习解决交互问题
另一种机器学习是强化学习。强化学习的目标是开发出一套系统(agent)来根据与环境的交互提升提性能。因为当前环境的状态信息通常包含所谓的奖励信号(reward signal),我们可以把强化学习看成是与监督学习相关的领域。但在强化学习中,反馈不再是确定为事实的标签或值 ,而是由奖励函数评价操作有多好的一个度量。通过与环境的交互,agent随后可使用强化学习去学习一系列动作通过探索性试错或刻意规划来最大化奖励。
著名的强化学习的例子是下棋程序。agent根据棋盘(环境)的状态来决定一系列着数,奖励可定义为游戏结束时的赢棋或输棋:
图1.5:强化学习流程
强化学习有很多子类型。但通常的模式是由agent通过一系列与环境的交互学习尝试最大化奖励。每种状态都可以关联为正向或反向奖励,奖励可定义为完成一项整体目标,比如下棋游戏中的赢棋或输棋。例如,下棋时每一着的结果都可看成是环境的不同状态。
为进一步探讨下棋的例子,我们把棋盘上的某一布置看成是导致赢棋可能性所关联的一种状态,比如吃掉对方一颗棋子或将军。在下棋游戏中,奖励(赢棋的正向奖励或输棋的负面奖励)只有游戏结束时才能给出。而且最终的奖励还取决于对手如何下。比如对手可能舍弃了车,最终却记得了比赛。
总之,强化学习关心的是学习选择一系列动作来最大化总奖励,这种奖励可通过立即采取行动或是延迟反馈来赢得。
发现无监督学习的隐藏结构
在监督学习中,我们在训练模型前就知道了正确答案(标签或目标变量),而在强化学习中,我们为agent所招待的具体动作定义了一种奖励的度量。但在无监督学习中,我们处理的是无标签数据或是未知结构的数据。通过无监督学习技术,我们可以在没有结果变量或奖励函数的指引下探索出数据的结构,提取有用信息。
通过聚类找出子分组
聚类是一种解释性数据分类或模式发现技术,可在事前不知道分组成员的情况下将一堆信息组织为有用的分组(聚类)。在分析过程中产生的每个聚类都定义着一组对象,它们有某种相似性却又与其它聚类中的对象存在区别,这也是为什么聚类有时也称作无监督分类。聚类对于信息结构化以及从数据中提取有用信息是一项很好的技术。比如,营销人员可根据客户兴趣发现分组,进而开发出不同的营销策略。
图1.6描绘了聚类如何用于将未打标签数据按特征x1和x2的相似性组织为三种不同的组或聚类(A, B及C,顺序随意):
图1.6: 聚类的原理
通过降维压缩数据
无监督学习的另一个子领域是数据降维(dimensionality reduction)。通常我们所操作的是高维度数据-每次观测都包含大量的度量,这对有限的存储空间和机器学习算法的计算性能都构成了极大挑战。无监督学习的数据降维常用于特征预处理,去除掉数据中的噪声,这些噪声可能会降低某些算法的预测性能。降维将数据压缩为更小维度的子空间,同时又保留其相关信息。
有时,降维还可用于可视化数据,比如,可将高维度的特征投射为一维、二维或三维特征空间,来可视化为2D或3D的散点图或直方图。图1.7展示了使用非线性降维将三维瑞士卷压缩为二维特征子空间:
基本术语和符号简介
前面我们讨论了机器学习的三大分类:监督学习、无监督学习和强化学习,下面来学习本书中会用到一些基本术语。下面的一小节中包含用于表示数据集各方面的常用术语,以及可实现更精准高效沟通的数学符号。
机器学习是一个非常大的领域并且还跨多学科,迟早一定会遇到表示相同概念的不同术语。第二个小节中收集了在机器学习文献中最常用的术语,在阅读机器学习刊物时会当成手册查阅。
本书中使用的符号和约定
图1.8中为鸢尾花数据集的节选,这是机器中学习中的经典案例(详情请见https://archive.ics.uci.edu/ml/datasets/iris)。鸢尾花数据集为包含鸢尾花测量数量的150个数据样本,分类三类(山鸢尾Setosa、变色鸢尾Versicolor和维吉尼亚鸢尾Virginica)。
这里每朵花的样本数据占数据集的一行,单位为厘米的测量数据存放于列中,也被称为数据集的特征:
图1.8: 鸢尾花数据集
为保持记录符号和实现简单高效,我们会使用一些线性代数的基础知识。在接下来的章节中,我们会使用矩阵标记来表示数据。我们会遵循一个常见约定,在特征矩阵X中将每个样本放在单独一行中,而每个特征则放在单独的列中。
鸢尾花数据集由150个样本和4个特征组成,写为150×4的矩阵,正式表示为:
符号约定
本书中除特别说明,大部分时候会使用上标i来表示第i个训练样式,使用下标 j 来来示训练数据集中的第 j 维。
我们会使用小写粗体字母来表示向量 (
例如
而每个特征维度是一个150维的列向量。例如:
类似地,可以将目标变量(此处为类标签)表示为一个150维的列向量:
机器学习术语
机器学习涉及领域广泛并且跨学科,因为它将不同研究领域的科学家汇聚一堂。有时一些术语和概念会被重新发现或重新定义,你可能本来很熟悉的东西使用了另一个名称。为方便起见,下来的列表中,列出了在阅读图书和机器学习文献时常用的术语及近义词:
- 训练样例(Training example):表格中表示数据集的一行,与观测(observation)、记录(record)、实例(instance)或样本(sample )为近义词(在大部分上下文中,样本指的是训练样例的集合)。
- 训练(Training):模型拟合,在参数模型中类似于参数估计( parameter estimation)。
- 特征(Feature),缩写为x:数据表或数据(设计)矩阵中的一列。近义词有预测变量(predictor)、变量(variable)、输入(input)、属性(attribute)或协变量(covariate)。
- 目标(Target),缩写为y:近义词有结果(outcome)、输出(output)、响应变量(response variable)、因变量(dependent variable)、(类)标签( (class) label)、真相(ground truth)。
- 损失函数(Loss function):常用的近义词有代价(cost )函数。有时损失函数也称为误差(error )函数。有某些文献中,“损失”指的是为单个数据点测量的损失 ,代价用于测量对整个数据集计算损失(平均值或汇总)。
构建机器学习系统路线图
在前面的小节,我们讨论了机器学习的基本概念以及其三大类型。本节中,我们会讨论机器学习系统与学习算法的其它重要部分。
图1.9中展示了在预测模型中使用机器学习的典型工作流,这在后面的小节中会分别讨论:
图1.9: 预测模型工作流
预处理-使数据成形
我们先讨论构建机器学习系统的路线图。原数据很少是按照学习模型最优性能的格式。因此数据预处理就成为所有机器学习应用中的重要步骤。
以前面一节中的鸢尾花数据集为例,可以把原数据看成是一组想要提取有用信息的花的图片。有用的特征可能集中在花的颜色或高度、长度和宽度。
很多机器学习算法还要求选择的特征与最优性能处于同一量级,通常的实现方式是将特征转化到 [0, 1] 范围内或是通过零平均值及单位方差所得到的标准正态分布,在后续章节中我们会学到。
某些选中的特征可能高度相关,因此在某种程度上是冗余的。在这种情况下,可使用降维技术把特征压缩为更低维度的子空间。对特征空间降维的优势是所需存储空间更少,并且学习算法运行速度更快。在某些情况下,如果数据集包含大量不相关特殊(或噪声)数据降维还能提升模型的预测性能,换句话说就是在数据集信噪比较低时。
要使机器学习算法不仅对训练数据集性能好而且对新数据也能产生很好的结果,我们需要随机分割数据集为单独的训练和测试数据集。我们使用训练数据集来训练和优化我们的机器学习模型,但保留测试数据集到最后用于评估最终的模型。
训练和选择预测模型
本章稍后我们会学到,为解不同的问题任务开发出了多种机器学习算法。可通过David Wolpert著名的没有免费午餐定理进行总结,我们无法“免费”进行学习(《学习算法间缺少先验差别》,D.H. Wolpert, 1996,《优化没有免费的午餐定理》D.H. Wolpert和W.G. Macready, 1997)。我们可以将这一概念关联到另一个流行的格言:手里拿个锤子,看什么都像钉子 (Abraham Maslow, 1966)。比如,每个分类算法都有内在的偏差(bias),如果不对任务做任何假定就没有哪个分类模型优先级更高。因此在实践中,比较不同的学习算法来训练和选择最佳效果的模型就非常重要了。但在比较不同模型之前,需要决定好测量性能的指标。一个常见的指标是分类准确度,通过正确分类实例的比例来定义。
一个合理的问题是:如果不使用测试数据集来选择模型,又将它保留用做模型评估,那么如何知道哪个模型对最终测试数据集和真实数据的效果更佳呢?要解决其中的问题,可以使用一些统称为“交叉验证”的技术。在交叉验证中,我们将数据集进一步分为训练和验证子集来评估模型的综合性能。
最后,不能奢望软件库所提供的各种学习算法的默认参数对你的具体问题任务就是最优的。因此,在后续章节中我们会经常使用超参数优化技术来辅助我们优化模型性能。
可以把这些超参数看作是数据中未学习到的参数,但可用于提升性能的模型旋钮(knobs)。在后续章节碰到实例案例时读者就清楚了。
评估模型并预测未知数据实例
在选好了拟合训练数据集的模型后,我们可以使用测试数据集来评估其对未知数据的效果,进而评估出所谓的泛化误差(generalization error)。如果对性能满意,可以使用该模型来预测未来的新数据。值得注意的是前面所说的流程中的参数,比如特征缩放和数据降维,只是通过训练数据集获取的,之后会再次应用这些参数来转化测试数据集以及新的数据实例,否则测试数据所测量出的性能可能会过于乐观。
使用Python来进行机器学习
Python是数据科学领域最著名的编程语言之一,借助非常活跃的开发者及开源社区,开发出了大量有用的科学计算和机器学习库。
虽然Python这类解释性语言的性能,在执行计算密集型任务时要逊于其它更底层的编程语言,但开发出了使用底层的Fortran和C所实现的NumPy和SciPy之类的扩展库,可对多维数组执行快速的向量化运算。
对于机器学习编程任务,我们多会使用scikit-learn库,它是当前最流行、易用的开源机器学习库之一。在后续的章节中,在聚焦于机器学习的一个分支深度学习时,我们会使用PyTorch库的最新版本,它通过使用显卡专门用于训练所谓的深度神经网络模型。
安装Python及通过PyPI安装Python包
三大操作系统,Microsoft Windows、macOS和Linux,均可使用Python ,可通过Python官方网站https://www.python.org下载安装包及文档。
本书中的代码示例使用Python 3.9编写和测试,通常建议使用Python 3的最新稳定版本。有些代码同时兼容Python 2.7,但官方对Python 2.7的支持已于2019年终结,大部分开源库都不再支持Python 2.7 (https://python3statement.org),我们强烈建议使用Python 3.9或更新版本。
可以通过在终端(Windows下使用PowerShell )执行如下命令来检测Python版本:
1 |
python --version |
或
1 |
python3 --version |
本书中所使用的其它包可通过pip
安装程序来安装,pip
从Python 3.3开始就集成在于标准库中,无需额外安装。有关pip
的更多信息请参见https://docs.python.org/3/installing/index.html。
在成功安装Python之后,可以在终端中执行pip
来安装其它Python包:
1 |
pip install SomePackage |
已安装的包可通过--upgrade
标记来进行升级:
1 |
pip install SomePackage --upgrade |
使用Anaconda Python发布和包管理器
针对科学计算强烈推荐安装来自Continuum Analytics的开源包管理系统conda。conda免费并且采用了许可式的开源证书。其目标是帮助在各操作系统中安装数据科学、数学和工程的Python以及其版本管理。如果想使用conda,有好几种选择,分别是Anaconda、Miniconda和Miniforge:
- Anaconda中预装了很多科学计算包。可通过https://docs.anaconda.com/anaconda/install/下载安装包,Anaconda的快速开始指南位于https://docs.anaconda.com/anaconda/user-guide/getting-started/。
- Miniconda是Anaconda的简化版(https://docs.conda.io/en/latest/miniconda.html)。和Anaconda基本一致,只是没有预装包,这深受很多人(包括作者在内)的喜爱。
- Miniforge类似于Miniconda,但它是社区维护的,使用了与Miniconda及Anaconda不同的包仓库 (conda-forge)。我们觉得Miniforge是Miniconda的一个很好的替代吕。下载及安装指导位于GitHub仓库https://github.com/conda-forge/miniforge。
在成功通过 Anaconda、Miniconda或Miniforge安装好了conda后,可执行如下命令安装新的Python包:
1 |
conda install SomePackage |
可使用以下命令升级已有的包:
1 |
conda update SomePackage |
官方conda通道中所没有的包可通过社区支持的conda-forge项目(https://conda-forge.org)来获取,通过--channel conda-forge
参数指定即可。例如:
1 |
conda install SomePackage --channel conda-forge |
默认conda通道和conda-forge都没有的包可通过前面讲过的pip
进行安装。比如:
1 |
pip install SomePackage |
科学计算、数据科学和机器学习包
本书的前半部分主要使用NumPy的多维数组来存储和操作数据。有时会用到pandas,这是一个构建于NumPy之上的库,提供了一些更高阶的操作工具可以更方便地处理表格数据。为提升学习体验以及可视化量化数据,这通常有利于进行理解,我们会使用自定义的Matplotlib库。
本书中主要使用到的机器学习库有 scikit-learn (第3到11章)。第12章 使用PyTorch做并行神经网络训练中会介绍用于深度学习的PyTorch库。
在编写本书时主要Python包的版本号参见下方的列表。理想情况下你所安装的包的版本应该要保持一致,这样可保障示例代码能正确运行:
- NumPy 1.21.2
- SciPy 1.7.0
- Scikit-learn 1.0
- Matplotlib 3.4.3
- pandas 1.3.2
在安装好这些包之后,可以通过在Python 中导入这些包并文章其__version__
属性来确认版本,比如:
1 2 3 |
>>> import numpy >>> numpy.__version__ '1.21.2' |
为方便起见,我们在本书的附属代码仓库https://github.com/rasbt/machine-learning-book中添加了一个python-environment-check.py
脚本,可通过执行脚本来确认Python的版本和包的版本。
某些章节会用到其它包,我们会提供相关的安装信息。比如现在大可不必担心PyTorch的安装。第12章中会在需要的时候提供相应的说明。
如果代码与章节中的代码完全一致时仍然出现错误,建议首先检查底层包的版本,再进行调试或联系作者。有时,新版本会引入向后不兼容的修改,可能导致错误。
如果不希望修改主Python安装中包的版本,推荐使用虚拟环境来安装本书中的包。如果使用Python却没有安装conda管理器,可以使用venv
库来新建虚拟环境。例如,可以通过如下两条命令创建及激活虚拟环境:
1 2 |
python3 -m venv /Users/sebastian/Desktop/pyml-book source /Users/sebastian/Desktop/pyml-book/bin/activate |
注意在每次打开新的终端或PowerShell时都需要激活虚拟环境。可在https://docs.python.org/3/library/venv.html中了解到更多有关venv
的信息。
如果使用Anaconda,可以通过如下命令创建和激活虚拟环境:
1 2 |
conda create -n pyml python=3.9 conda activate pyml |
小结
本章中,我们从高层次探讨了机器学习并熟悉了后续章节中会详细学习的全景以及主要概念。我们学习到监督学习由两大子领域组成:分类和回归。通过分类模型可以将对象分成不同类,通过回归分析可预测目标变量的连续结果。无监督学习不仅为发现无标签数据的结构提供了有用的技术,还可用于特征预处理阶段的数据压缩。
我们简单地过了一遍将机器学习应用于问题任务的典型路线图,可作为后续章节中更深入讨论和随手案例的基础。最后我们配置了Python环境并安装和更新了所需要的包,来做好实操机器学习的准备。
本书的后面,随时机器学习本身外,我们还会介绍预处理数据的各种技术,这有助于得到各种机器学习算法的最佳性能。除了在本书中我们会广泛讲解分类算法外,还会探讨回归分析和聚类的各种技术。
前方的旅程可期,会涉及到机器学习广泛领域中的多种强大技术。但我们会一步步地接近机器学习,在本书的各章中层层递进。下一章中我们会开始实现机器学习最早的聚类算法之一,为第3章 使用Scikit-Learn的机器学习分类器之旅的学习打下基础,在第3章中我们会讲解更高级的机器学习算法并使用scikit-learn开源机器学习库。