第1章 简介篇
1.1机器学习综述
机器学习系统具备如下特点:
>许多机器学习系统所解决的都是无法直接使用固定规则或者流程代码完成的问题,通常这类问题对人类而言却很简单。比如,计算机和手机中的计算器程序就是不属于具备智能的系统,因为里面的计算方法都有很清楚而且固定的规程;但是,如果要求一台机器去辨别一张相片中都有那些人或者物体,这对我们人类来讲非常容易,然而机器却非常难做到。
>所谓具备“学习”能力的程序都是指它能够不断地从经历和数据中吸取经验教训,从而应对未来的预测任务。我们习惯地把这种对未知的预测能力叫做泛化力(Generalization)。
>机器学习系统更加诱人的地方在于,它具备不断改善自身应对具体任务的能力。我们习惯称这种完成任务的能力为性能(Performance)。塞缪尔的西洋棋程序和谷歌的AlphaGo都是典型的借助过去对弈的经验或者棋谱,不断提高自身性能的机器学习系统。
美国卡内基梅隆大学(Garnegie Mellon University)机器学习研究领域的著名教授Tom Mitchell的经典定义:
如果一个程序在使用既有的经验(E)执行某类任务(T)的过程中被认定为是“具备学习能力的”,那么它一定需要展现出:利用现有的经验(E),不断改善其完成既定任务(T)的性能(P)的特性。
三个关键术语:任务(Task)、经验(Experience)、性能(Performance)
1.1.1 任务
机器学习的任务种类有很多,本书侧重于对两类经典的任务进行讲解与实践:监督学习(Supervised Learning)和无监督学习(Unsupervise Learning)。其中,监督学习关注对事物未知表现的预测,一般包括分类问题(Classification)和回归问题(Regression);无监督学习则倾向于对事物本身特性的分析,常用的技术包括数据降维(Dimensionality Reduction)和聚类问题(Clustering)等。
分类问题,顾名思义,便是对其所在的类别进行预测。类别既是离散的,同时也是预先知道数量的。例如,根据一朵鸢尾花的花瓣、花萼的长度等数据,判断其属于哪个鸢尾花亚种;鸢尾花亚种的种类与数量也满足离散和预先知晓这两项条件,因此也是一个分类预测问题。(拓展:这里也同时暴露出一个分类问题的缺陷,就是所有需要预测的类别都是已知的。如果是新物种,我们便无法根据现有经验进行判断。常见的做法是对数据样本的分类表现打分;对于没有满足阈值设定的数据样本,就需要对其做进一步分析,甚至要求人工参与鉴定。)
回归同样是预测问题,只是预测的目标往往是连续变量。比如,根据房屋的面积、地理位置、建筑年代等进行销售价格的预测,销售价格就是一个连续变量。
数据降维是对事物的特性进行压缩和筛选,这项任务相对比较抽象。如果我们没有特定的领域知识,是无法预先确定采样那些数据的;而如今,传感设备的采样成本相对较低,相反,筛选有效信息的成本更高。比如,在识别图像中人脸的任务中,我们可以直接读取到图像的像素信息。若是直接使用这些像素信息,那么数据的维度会非常高,特别是在图像分辨率越来越高的今天。因此,我们通常会利用数据降维的技术对图像进行降维,保留最具有区分度的像素组合。
聚类则是依赖于数据的相似性,把相似的数据样本划分为一个簇。不同于分类问题,我们在大多数情况下不会预先知道簇的数量和每个簇的具体含义。现实生活中,大型电子商务网站经常对用户的信息和购买习惯进行聚类分析,一旦找到数量不菲并且背景相似客户群,便可以针对他们的兴趣投放广告和促销信息。
(威斯康星大学乳腺癌肿瘤数据:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data)
1.1.2 经验
我们习惯性地把数据视作经验;事实上,只有那些对学习任务有用的特定信息才会被列入考虑范围。而我们通常把这些反映数据内在规律的信息叫做特征(Feature)。比如,在前面提到的人脸图像识别任务中,我们很少直接把图像最原始的像素信息作为经验交给学习系统;而是进一步通过降维,甚至一些更为复杂的数据处理方法得到更加有助于人脸识别的轮廓特征。
对于监督学习问题,我们所拥有的经验包括特征和标记/目标(Label/Target)两个部分。我们一帮用一个特征向量(Feature Vector)来描述一个数据样本;标记/目标的表现形式则取决于监督学习的种类。
无监督学习问题自然就没有标记/目标,因此也无法从事预测任务,却更加适合对数据结构的分析。正是这个却别,我们经常可以获得大量的无监督数据;而监督数据的标注因为经常耗费大量的时间、金钱和人力,所以数据量相对较少。
另外,更为重要的是,除了标记/目标的表现形式存在离散、连续变量的区别,从原始数据到特征向量转化的过程中也会遭遇多种数据类型:类别型(Categorical)特征。数值型(Numerical)特征,甚至是缺失的数据(Missing Value)等。实际操作过程中,我们都需要把这些特征转化为具体的数值参与运算,这里暂时不过多交代,实例中遇到时会具体说明。
在“良/恶性乳腺癌肿瘤预测”问题中,我们所使用的经验有两个维度的特征(也许读者会觉得好奇,这里的肿块厚度和细胞尺寸都不像是真正意义的数值,更像是级别的划分。事实上,的确是这。在大多数情况下,我们都无法使用最原始的数据进行机器学习任务;更多的需要我们对数据进行预处理。):肿块厚度(Clump Thickness)和细胞尺寸(Cell Size);除此之外,还有对应肿瘤类型。而且,每一行都是一个独立的样本。我们所要做的便是让我们的学习模型从上述的经验中习得如何判别肿瘤的类型。我们通常把这种既有特征,同事也带有目标/标记的数据集称作训练集(Training Set),用来训练我们的学习系统。
1.1.3 性能
所谓性能,便是评价所完成任务质量的指标。为了评价学习模型完成任务的质量,我们需要具备相同特征的数据,并将模型的预测结果同相对应的正确答案进行比对。我们称这样的数据集为测试集(Testing Set).而且更为重要的是,我们需要保证,出现在测试集中的数据样本一定不能被用于模型训练。简而言之,训练集与测试集之间是彼此互斥的。
对待预测性质的问题,我们经常关注预测的精度。具体来讲:分类问题,我们要根据预测正确类别的百分比来评价其性能,这个指标通常被称作准确性(Accuracy);回归问题则无法使用类似的指标,我们通常会衡量预测值与实际值之间的偏差大小。以“良/恶性乳腺癌肿瘤预测”问题为例,我们使用准确性作为衡量学习模型/系统性能的指标,并且用于测试的乳腺癌肿瘤样本数据有175条。
前面已经提到过,作为一个学习系统,其自身需要通过经验,不断表现出改善性能的能力。
1.2 Python编程库
1.2.2 Python 机器学习的优势
使用Python编程技巧,接触甚至掌握机器学习的经典算法至少有以下4项优势。
>方便调试的解释型语言:Python是一门解释型编程语言,与Java类似,源代码都要通过一个解释器(Interpreter),转换为独特的字节码。这个过程不需要保证全部代码一次性通过编译;相反,Python解释器逐行处理这些代码。因此方便了调试过程,也特别适合于使用不同机器学习模型进行增量是开发。
>跨平台执行作业:上面提到Python的源代码都会先解释成独特的字节码,然后才会被运行。从另一个角度讲,只要一个平台安装有用于运行这些字节码的虚拟机,那么Python便可以执行跨平台作业。这点不同于C++这类编译型语言,但是却和Java虚拟机很相似。由于机器学习任务广泛地执行在多种平台,因此以Python这类解释型语言作为编码媒介也不失为一种好的选择。
>广泛的应用编程接口:除了那些被用于编程人员自行开发所使用的第三方程序库以外,业界许多著名的公司都拥有用于科研和商业的云平台,如亚马逊的AWS(Amazon Web Services)、谷歌的Prediction API等。这些平台同时也面向互联网用户提供机器学习功能的Python应用编程接口(Application Programming Interface)。许多平台的机器学习功能模块不需要用户来编写,只需要用户像搭积木一样,通过Python语言并且遵照API的编写协议与规则,把各个模块串接起来即可。
>丰富完备的开源工具包:软件工程中有一个非常重要的概念,便是代码与程序的重用性。为了构建功能强大的机器学习系统,如果没有特殊的开发需求,通常情况下,我们都不会从零开始编程。比如,学习算法中经常会设计的向量计算;如果Python中没有直接提供用于向量计算的工具,我们还需要自己花费时间编写这样的基础功能吗?答案是否定的。Python自身免费开源的特性使得大量专业,甚至天才型的编程人员,参与到Python第三方开源工具包(程序库)的构建中。更为可喜的是,大多数的工具包(程序库)都允许个人免费使用,乃至商用。这其中就包括本书主要使用的多个用于机器学习的第三方程序库,如便于向量、矩阵和复杂科学计算的NumPy与SciPy;仿MATLAB样式绘图的Matplotlib;包含大量经典机器学习模型的Scikit-learn;对数据进行快捷分析与处理的Pandas;以及集成了上述所有第三方程序库的综合实践平台Anaconda。
1.2.3 Numpy & SciPy
NumPy(http://www.numpy.org/)是全书最为基础的Python编程库。NumPy除了提供一些高级的数学运算机制以外,还具备非常高效的向量和矩阵运算功能。这些功能对于机器学习的计算任务是尤为重要的。因为不论是数据的特征表示也好,还是参数的批量计算也好,都离不开更加方便快捷的矩阵和向量计算。而NumPy更为突出的是它内部独到的设计,使得处理这些矩阵和向量计算比起一般程序员自行编写,甚至是Python自带程序库的运行效率都好高出许多。
SciPy(http://www.scipy.org/)则是在Numpy的基础上构建的更为强大,应用领域也更为广泛的科学计算包。这是出于这个原因,SciPy需要依赖NumPy的支持进行安装和运行。对这两个编程库感兴趣的读者,可以参考下面这个在线教程详细学习它们的方法:https://docs.scipy.org/doc/numpy-dev/user/quickstart.html。
1.2.4 Matplotlib
众所周知,MATLAB作为一款功能强劲,集数据分析和展现于一体的商业软件,受到无数自然科学工作者的青睐。然而在多数情况下,只有高等学校、科研和机构和大型公司才能负担的起其昂贵的正版许可证。就普通个人对数据展现方面的需求而言,我们更加希望有类似MATLAB的绘图功能,但是允许免费使用的Python程序库。Matplotlib(http://matplotlib.org)作为一款Python编程环境下免费使用的绘图工具包,因为其工作方式和绘图命令机会和MATLAB类似,所以立刻便成了本书的首选。欲了解详情的读者可以查阅Matplotlib的在线文档http://matplotlib.org/contents.html。
1.2.5 Scikit-learn
Scikit-learn(http://scikit-learn.org/)是本书所使用的核心程序库,依托于上述几种工具包,封装了大量经典以及最新的机器学习模型。该项目最早由David Cournapeau 在2007年 Google 夏季代码节中提出并启动。后来作为 Matthieu Brucher 博士工作的一部分得以延续和完善。现在已经是相对成熟的机器学习开源项目。近十年来,有超过20位计算机专家参与其代码的更新和维护工作。作为一款用于机器学习和实践的 Python 第三方开源程序库,Scikit-learn 无疑是成功的。无论是其出色的接口设计,还是高效的学习能力,都使它成为本书介绍的核心工具包。另外 Scikit-learn 还提供了详细的英文版使用文档 http://scikit-learn.org/stable/user_guide.html,也是值得参考的辅助学习资料。
1.2.6 Pandas
如果读者有机会采访在一线从事机器学习应用的研发人员,问他们究竟在机器学习的哪个环节最耗费时间,恐怕多数人会很无奈地回答您:“数据预处理。”事实上,多数在业界的研发团队往往不会投入太多精力从事全新机器学习模型的研究;而是针对具体的项目和特定的数据,使用现有的经典模型进行分析。这样一来,时间多数被花费在处理数据,甚至是数据清洗的工作上,特别是在数据还相对原始的条件下。Pandas(http://pandas.pydata.org/)是一款针对于数据处理和分析的 Python 工具包,具体文档见 http://pandas.pydata.org/pandasdocs/stable/ 。其中实现了大量便于数据读写、清洗、填充以及分析的功能。这样就帮助研发人员节省了大量用于数据预处理工作的代码,同时也使得他们有更多的精力专注于具体的机器学习任务。
1.2.7 Anaconda
读到这里,也许会觉得前面介绍的许多工具包相互之间或多或少都存在着一些依赖关系,一时间也很难弄明白;而且实际操作也可能比较复杂。是否有一个集成平台,一旦安装便不需要考虑这些琐碎的事情了呢?答案是:既然有需求,那么一定有!对于想快速上手的初学者而言,笔者推荐使用 Anaconda(https://www.continuum.io/)平台,只要下载并安装对应操作系统以及 Python 解释器版本的程序包,便可以一次性获得 300 多种用于科学和工程计算相关任务的Python编程库的支持;本书所涉及的编程库仅仅是其冰山一角。刚兴趣的读者可以深入阅读其文档:https://www.continuum.io/documentation。