MATLAB机器学习

978-7-115-53203-9
作者: [意]朱塞佩·恰布罗(Giuseppe Ciaburro)
译者: 张雅仁李洋
编辑: 吴晋瑜

图书目录:

详情

MATLAB为机器学习领域提供了必要的工具。用户可以借助MATLAB环境提供的强大交互式图形界面,非常轻松地解决机器学习问题。 本书在介绍每个主题前,会简要概述其理论基础,然后辅以实际案例进行阐释。通过阅读本书,读者能够应用机器学习方法,并能充分利用MATLAB的功能解决实际问题。 《MATLAB机器学习》前3章主要介绍MATLAB机器学习的基础知识、使用MATLAB导入数据和组织数据的方法以及从数据到知识发掘的方法,中间3章主要介绍回归分析、分类分析以及无监督学习,最后3章介绍人工神经网络、降维变换的方法以及机器学习实战的相关知识。 本书可供数据分析员、数据科学家以及任何希望学习机器学习算法以及构建数据处理、预测应用的读者阅读。

图书摘要

版权信息

书名:MATLAB机器学习

ISBN:978-7-115-53203-9

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    [意]朱塞佩·恰布罗(Giuseppe Ciaburro)

译     张雅仁  李 洋

审   校 李 畅

责任编辑 吴晋瑜

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


版权声明 Copyright ©Packt Publishing 2017.First published in the English language under the title MATLAB for Machine Learning (9781788398435). All rights reserved.

本书由英国Packt Publishing公司授权人民邮电出版社有限公司出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。

版权所有,侵权必究。


MATLAB为机器学习领域提供了必要的工具。用户可以借助MATLAB环境提供的强大交互式图形界面,非常轻松地解决机器学习问题。

本书在介绍每个主题前,会简要概述其理论基础,然后辅以实际案例进行阐释。通过阅读本书,读者能够应用机器学习方法,并能充分利用MATLAB的功能解决实际问题。

本书前3章主要介绍MATLAB机器学习的基础知识、使用MATLAB导入数据和组织数据的方法以及从数据到知识发掘的方法,中间3章主要介绍回归分析、分类分析以及无监督学习,最后3章介绍人工神经网络、降维变换的方法以及机器学习实战的相关知识。

本书可供数据分析员、数据科学家以及任何希望学习机器学习算法以及构建数据处理、预测应用的读者阅读。


朱塞佩·恰布罗(Giuseppe Ciaburro),获有意大利那不勒斯腓特烈二世大学(Università degli Studi di Napoli Federico Ⅱ)的化学工程硕士学位和那不勒斯第二大学(Seconda Università degli Studi di Napoli)的声学和噪声控制硕士学位。他目前在意大利坎帕尼亚的一所大学(Università degli Studi della Campania“Luigi Vanvitelli”)的建成环境控制实验室工作。

他在燃烧领域以及声学和噪声控制领域方面有15年以上的编程工作经验。他使用的核心编程语言是Python和R,并且在使用MATLAB上也有丰富的经验。Giuseppe虽为声学和噪声控制领域的专家,但他在专业计算机课程的教学以及在线课程方面也有丰富的经验。他出版过专著,也在科学期刊、主题会议上发表过文章。近期他的研究方向是将机器学习应用到声学和噪声控制理论中。


安基特·迪克西特(Ankit Dixit)是来自印度孟买的数据科学家和计算机视觉工程师。他拥有生物医学工程技术专业的学士学位和计算机视觉专业的硕士学位,在计算机视觉和机器学习领域有超过6年的工作经验。他一直在使用各类软硬件平台设计和开发计算机视觉的算法,并在决策树、随机森林、支持向量机和人工神经网络等机器学习算法方面有丰富的经验。目前他在孟买的阿迪亚(Aditya)图像和信息技术中心(印度Sun Pharmaceutical Advance Research Center的一部分)为医学图像数据设计计算机视觉和机器学习算法。同时,他也会使用一些集成算法和深度学习模型来工作。

鲁本·奥利瓦·拉莫斯(Ruben Oliva Ramos)是一位计算机系统工程师,拥有墨西哥拉萨尔大学巴西欧分校计算机和电子系统工程专业的硕士学位——细分专业是电信技术和网络连接(teleinformatics and networking)。他在开发网络应用方面有超过5年的经验,他所开发的这些网络应用用来控制和监控与树莓派、Arduino软件相连接的设备。此外,他在使用网络框架和云服务搭建物联网应用上也有超过5年的经验。

鲁本目前是墨西哥拉萨尔大学巴西欧分校机器电子学专业的老师,教授“设计和制造机器电子学系统”这门课的硕士课程。他在墨西哥的Centro de Bachillerato Tecnologico Industrial 225工作,教授电子学、机器人学、控制、自动化和微控制学的课程。

鲁本还是技术人员、顾问和开发者,主要领域为各式各样的系统监控和数据记录器,包括Android、iOS系统、Windows电话、HTML5、PHP、CSS、Ajax、JavaScript、Angular、ASP.NET数据库(SQlite、MongoDB和MySQL)、Web Servers、Node.js、IIS、硬件编程(Arduino、树莓派、Ethernet Shield、GPS和GSM/GPRS)以及ESP8266。

鲁本还著有《使用JavaScript进行物联网编程》(Internet of Things Programming with JavaScript)一书。

感谢我的妻子Mayte,和我们两个可爱的儿子Ruben和Dario。感谢我的爸爸(Ruben)、我亲爱的妈妈(Rosalia)和我所深爱的哥哥(Juan Tomas)、我的姐姐(Rosalia)。感谢他们在我审阅这本书的时候所给予的全部支持,感谢他们支持我追逐自己的梦想,感谢他们能够原谅我因每日的忙碌而没有时间陪伴他们。

胡安·托马斯·奥利瓦·拉莫斯(Juan Tomás Oliva Ramos)是墨西哥瓜纳华托大学环境学专业的工程师,拥有管理工程和质量的硕士学位。他在专利管理和开发、技术创新方面以及基于项目的统计控制制订解决方案方面拥有超过5年的经验。

自2011年起,他就是一个统计学、创业、科技项目发展的老师,主要关注通过技术实现各类项目进程中的创新和进步。他是一名创业导师、科技管理顾问,并且在Instituto Tecnologico Superior de Purisima del Rincon创立了一个新的科技管理和创业部门。

胡安著有Wearable Designs for Smart Watches, Smart TV's and Android Mobile Devices一书。他已经开发了一系列通过编程和自动化技术用来加速工作流的产品原型,并且注册了专利。

非常有幸能有机会审阅这本书,感谢鲁本的邀约。感谢我的妻子Brenda、我们两个童话般的小公主Regina和Renata以及我尚未出世的孩子Tadeo。是他们给了我力量,给了我快乐,还给了为他们追求幸福的强大动力。

普拉桑特·维尔马(Prashant Verma)于2011年开始了他的IT职业生涯,当时他是爱立信公司(Ericsson)的Java开发人员。在从事几年的Java EE工作后,他转行到了大数据领域,并且一直在使用最流行的大数据工具(如Hadoop、Spark、Flume、Mongo和 Cassandra),也会用到Scala。普拉桑特是qa infotech公司的首席数据工程师,主要从事用机器学习技术解决在线学习问题的工作。

普拉桑特在电信和在线学习领域为多家公司工作过,闲暇之余还担任自由顾问。他还担任了Spark For Java Developer一书的顾问。

感谢Packt出版社给我机会去审阅这本书,也感谢我的上司和家人在此期间给予我莫大的理解和支持!


从犯错和经验中学习是人类的一项基本能力,机器能有这样的能力吗?机器学习(machine learning)算法赋予了机器从经验中学习的能力。机器学习赋予了计算机无须显示编程即可自主学习的能力。机器学习算法通过学习原始数据,从原始数据集中提取规律,发现模式,构建模型,然后用这个模型对新的数据进行预测。

MATLAB为机器学习领域提供了必要的工具。用户可以借助MATLAB环境提供的强大的交互式图形界面,非常轻松地解决机器学习问题。

本书在陈述每个主题前,都会对这个主题的理论基础进行精炼的概述,然后用实际案例举例。通过阅读本书,读者能够应用机器学习方法并充分利用MATLAB的功能解决实际问题。

第1章:MATLAB机器学习初体验。本章先对机器学习的基础概念进行概述,然后快速介绍几种不同类型的机器学习算法。除此之外,本章还会涉及MATLAB环境的部分介绍、背景和基础概念。最后,我们还会探索MATLAB为机器学习领域提供的必要工具。

第2章:使用MATLAB导入数据和组织数据。本章主要使用MATLAB导入数据和组织数据。我们会介绍存储数据的几种不同形式以及将数据集导入/导出MATLAB的方法,最后还会分析如何以正确的形式组织数据,以便用于之后的数据分析。

第3章:从数据到知识发掘。从这一章开始,我们从数据中提取有用信息。我们从对基本的变量类别进行分析和逐步清洗数据入手,介绍了为分析和建模准备最合适数据的几种方法,最后以数据可视化结尾——这对理解数据起着至关重要的作用。

第4章:找到变量之间的关系——回归方法。本章介绍了MATLAB用于回归分析的工具箱。我们从工具箱的用户界面开始学习,继而深入到如何使用内置函数进行回归分析(包括拟合、预测和结果可视化)。

第5章:模式识别之分类算法。之前的章节一直在介绍频率视角下的监督学习,从本章开始增加了概率论、贝叶斯视角下的机器学习算法以及非监督学习的内容。除了基于决策树的频率视角下的分类器,我们还将介绍如何使用最近邻算法进行无监督分类,以及基于贝叶斯理论的后验概率分类器。

第6章:无监督学习。本章着重介绍无监督学习和聚类分析。在这一章中,我们将介绍如何把数据集归类到群、如何对相似的事物分簇。我们先介绍基于层级的聚类算法,接着将扩展到基于原型(prototype-based clustering)的聚类方法,如k均值和k邻近算法。

第7章:人工神经网络——模拟人脑的思考方式。本章讲述如何使用人工神经网络对数据进行拟合、分类以及聚类,其中介绍了一系列帮助提高训练效率、评估网络性能的预处理方法、参数调优方法及网络结构可视化方法。

第8章:降维——改进机器学习模型的性能。本章讲述如何构建最能够表示数据集的特征矩阵,其中介绍了对数据集的降维变换的方法,以及对数据集进行特征提取的方法。

第9章:机器学习实战。本章着重讲述机器学习方法在实际生活中的应用。我们首先会完成一个真实的拟合任务,接着介绍如何使用神经网络进行分类,最后以一个聚类任务结尾。通过学习本章的内容,读者将了解如何在实际应用中分析、使用监督学习和非监督学习算法。

为了能运行本书中的MATLAB机器学习代码,读者需要安装MATLAB(推荐使用最新版本,写作本书时使用了R2017a)以及如下工具箱:统计机器学习工具箱(statistics and machine learning toolbox)、神经网络工具箱(neural network toolbox)和模糊逻辑工具箱(fuzzy logic toolbox)。

本书的目标人群包括数据分析员、数据科学家、学生或任何希望学习机器学习算法以及构建数据处理、预测应用的人群。良好的数学和统计学(大学工科水平)背景非常有助于本书的学习。

在本书中,我们用各种不同的文本格式来区分不同种类的信息。下面列举了这些文本格式的例子并对它们的含义做出解释。

下面是一个代码段的例子:

PC1 = 0.8852* Area + 0.3958 * Perimeter + 0.0043 * Compactness +
  0.1286 * LengthK + 0.1110 * WidthK - 0.1195 * AsymCoef + 0.1290 *
  LengthKG

任何命令行的输入或者输出采用如下形式:

>>10+90
ans =
 100

新的术语重要的词汇以黑体表示。在诸如MATLAB的界面、菜单、对话框中显示的词汇在本书正文中以这种形式出现:“在帮助页面中的一个引用页”。


警告和重要的提示以这种图形出现。



小技巧以这种图形出现。


本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。

本书为读者提供源代码。要获得以上配套资源,请在异步社区本书页面中单击 ,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎读者将发现的问题反馈给我们,帮助我们提升图书的质量。

如果读者发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对读者提交的勘误进行审核,确认并接受后,将赠予读者异步社区的100积分(积分可用于在异步社区兑换优惠券、样书或奖品)。

我们的联系邮箱是contact@epubit.com.cn。

如果读者对本书有任何疑问或建议,请发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果读者有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/ selfpublish/submission即可)。

如果读者来自学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果读者在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请将怀疑有侵权行为的链接发邮件给我们。这一举动是对作者权益的保护,也是我们持续为读者提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。

异步社区

微信服务号


本章主要内容

“为什么你这台机器听不懂我的命令呢?”“什么叫‘你这台机器’?你当我是只猴子吗?”这是电影《机械纪元》中主演与机器人的一段对话。在这部电影中,机器人被设定遵守两条不可更改的原则:不可以伤害人类;不可以自我修复。为什么人类要限制机器人的自我修复能力呢?因为,有强大自我学习能力的机器人也许终将统治这个世界。

至少,这是电影中所发生的。

那么,当我们提到“自我学习能力”的时候,它到底指的是什么呢?暂且将其定义为,机器[1]能够通过自身已有的行为活动,改善自身表现的能力。这种能力能够帮助人类解决某些特定问题,例如从大量的数据中提取知识。本章将对机器学习的基本概念进行介绍,接着将快速浏览不同种类的算法。除此之外,本章也会简要介绍MATLAB环境的基础知识。最后,我们将介绍MATLAB提供的几个核心的机器学习工具箱。

学完本章的内容,读者可以了解不同的机器学习算法以及MATLAB提供的实现这些算法的工具。

定义机器学习不是一件简单的事情。我们先来看看机器学习领域的大牛们(见图1.1)是如何定义的。

图1.1 机器学习历史

机器学习:研究如何让计算机在未被明确编写指令的情形下能够自主学习的领域。

——亚瑟·L. 塞缪尔(Arthur L. Samuel),1959

另一个定义为:

“机器学习”是指使系统能够在下一次更有效地执行同一任务(或采样于同一总体的任务)的自我适应和自我调整的能力。

——赫伯特·亚历山大·西蒙(Herbert Alexander Simon),1984

还有一种定义为:

假设对于任务T,有相对应的经验E以及评价指标P,那么机器学习指的是能够在执行任务T时通过学习经验E可以提高评价指标P的一种程序。

——汤姆·M. 米切尔(Tom M. Mitchell),1998

这些定义的共同点是,它们都指向了一种在没有任何外界帮助的情况下,从经验中学习的能力。这正是许多情况下人类学习的方式,那为何我们不能让机器[2]也具有同样的能力呢?

机器学习是一门由计算机科学、统计学、神经生物学和控制理论衍生出的交叉学科。它在一些领域中扮演了至关重要的角色,并且已经彻底地改变了人们对编程的理解。如果之前我们要解决的问题是“如何给计算机编写程序”,那么现在我们的问题是“如何让计算机自己给自己编写程序”?

因此,机器学习可以被视为赋予计算机“智能”的基础理论。

与大多数人的直觉一致,机器学习的发展与对人类学习方式的研究紧密相关。人类直觉、智能的基础是大脑及其中的神经元,相应地,计算机进行决策的基础可以是人工神经网络(Artificial Neural Network,ANN)。

机器学习使我们能够从数据集中找到描述此数据集的模型。例如,给定一个系统,我们可以从中自动建立输入变量到输出变量的对应关系。其中一种方法是首先假设数据的产生是遵循某种由参数指定的机制的,只是参数的具体值是未知的。[3]

这一过程参考的统计学方法有归纳(induction)、演绎(deduction)和回溯(abduction),它们的关系如图1.2所示。

图1.2 皮尔斯三角,关于3种推理
方法的推理模式关系

从已观测到的数据集中抽象出通用的法则称为归纳;与之相反,演绎是指应用通用的法则预测一组变量[4]的值。归纳是科学研究中的基本方法,它能够从观测到的现象中总结出通用的法则(这些法则通常用数学语言来描述)。

观测结果包含一组变量值,这组数据能够描述观测到的现象[5]。总结出的模型[6]可以继续对新观察到的数据进行预测。从一组观测结果到总结模型,再到使用模型对新观察到的数据进行预测的过程,称为推断[7]

因此,归纳学习的精髓在于从已观测数据中寻找可被泛化(generalization)到未观测数据集(新加入的数据),以预测模型。例如,基于过往股票价格数据以及涨跌情况,我们可以对一个线性分类方程进行参数优化,并将优化后的模型用于预测未来股票的涨跌情况。泛化性能的好坏取决于从历史数据中得到的模型,并在新数据上预测结果的优劣。这种预测并非总能奏效,但至少有希望得到好的结果。

归纳学习可被简单地分为如下两类。

(1)基于样本学习:例如,通过学习正样本(positive sample)——即属于某分类的样本,以及负样本(negative sample),能够获得关于这个二分类问题的知识(即模型或参数)。

(2)学习规律:此类方法的目标是在给定数据集中寻找样本间的“规律”(即共同特征)。

图1.3展示了归纳学习的分类。

图1.3 归纳学习的分类

读者可能会有这个疑问:为什么机器学习算法要优于传统算法和模型[8]呢?传统算法和模型失败的原因有很多,其中代表性的原因如下所示。

(1)人类对许多问题的本身已很难描述:例如,我们很容易识别出自己熟悉的人的声音,但是应该没人能够描述出识别这些声音所经过的一系列的运算步骤。

(2)实践中大量的未知变量(参数):例如,当你面临从文档中识别字符这一任务时,为模型指定所有相关的参数是特别复杂的。除此之外,同样的参数表达在同样的上下文环境中是成立的,但是在不同的方言中,仅用一个参数来表达是不够的。(因此需要更多的参数。)

(3)缺乏理论:例如,当你面临需要准确预测金融市场表现这一任务时,就会有这个问题,而这类问题是缺乏对应的数学理论支撑的。

(4)个性化定制的需求:在实际应用中,能否选取数据中有用的特征[9]在很大程度上取决于个人对问题的理解程度。

图1.4展示了归纳学习和演绎学习的异同。

图1.4 归纳学习和演绎学习的异同[10]

机器学习算法的能力来源于算法的质量[11],这正是过去这些年科学家着力更新、改进的内容。这些算法根据使用的输入数据、训练方式以及学习到的模型的输出结果,可分为如下3类。

(1)监督学习:这类算法根据一系列样本(每个样本的输入有对应的输出)的观测结果建立从输入到输出的映射关系,最终构建一个预测模型。

(2)非监督学习:这类算法只需一系列样本点的输入,不需要样本事先标注出对应的输出。算法学习的信息能够构建一个描述性模型[12],一个经典的例子是搜索引擎[13]

(3)强化学习:这种算法能够通过多次迭代并观察每次迭代后环境产生的反馈进行学习。事实上,每次迭代后的输出结果和模型采取的行动都会对环境产生影响,而环境也会针对这些影响进行反馈。这类算法多用于语音识别和文本识别[14]

图1.5描述了不同机器学习算法间的关系。

图1.5 机器学习算法分类

监督学习同时用样本的输入集合I和每个样本对应的标签集合O作为输入数据,能够建立从输入I到标签O的映射关系f,即模型与参数间的关系。用于求解模型、参数的数据集称为训练集(training set)。监督学习的训练流程如图1.6所示。

图1.6 监督学习训练流程

所有监督学习算法的训练都基于以下这个论断:如果一个算法拥有足够大的训练集,那么经过训练后,它能够建立一个映射关系B—— 这个映射关系能够无限逼近于潜在的真实映射关系A[15]

在用于预测问题时,监督学习假设相似的输入有相似的输出。也就是说,当B足够接近A时,在新数据上应用时,给BA同一输入,应该产生相似的输出结果。[16]

总体来说,在实际应用中这两个假设并不总是成立的。显然,这种算法的最终表现在很大程度上取决于输入数据集的质量。如果输入数据集只包含少量样本,那么训练得到的模型就没有学习到足够经验以进行正确预测。相反,过多的冗余样本将导致优化的模型过于复杂,会降低模型的执行速度。

此外,在实际开发中我们发现,监督学习算法对数据集中的噪声、奇异值非常敏感。即使很小比例的奇异值,也将导致整个系统产生极大偏误,并给出错误预测。[17]

在监督学习中,我们可以根据输入数据的特点、学习任务的不同,将其分成两类。当需要输出离散类型的数据和对数据集中的样本进行归类时,此类问题称为分类问题;当需要输出连续的结果时,这类问题称为回归问题。

非监督学习的目标是自动从数据集中提取信息,整个过程中没有事先对数据集给出任何先验假设。与监督学习不同,训练数据集只包含样本的输入,不包含对应的输出。非监督学习的目标是能够自动在数据集中发现有用的信息,例如聚类(根据样本间的相似特点将样本组合在一起),典型的应用是搜索引擎。[18]

非监督学习算法的有效性在很大程度上取决于从数据集中抽取到的信息质量。这些算法通过比较数据集中样本间的相似和不同之处来进行学习。图1.7展示了监督学习和非监督学习的例子。

图1.7 监督学习vs. 非监督学习

非监督学习在处理数值型数据集时具有很好的表现,但当处理非数值型数据集时,精确度会下降一些。总体来说,非监督学习适合处理含有顺序的,或者能够被明显划分成组并被明确辨识的数据集。

强化学习的目标是构建一种算法,这类算法通过多次迭代和观察每次迭代后环境产生的反馈进行学习。这类算法借助模型输出决策所引起的外部环境反馈进行交互式学习。当模型给出正确决策时,外部环境会给予正向奖励;当出错时,外部环境会给予负向惩罚。算法的学习目标是最大化奖励。

监督学习好比一位“老师”[19],通过标注数据来教学生(算法)学习。然而,不是对于所有问题都可以有这种“老师”。很多情况下,即使人类也只能给出定性的信息(好/坏、成功/失败等)。

这类定性信息称为“增强信号”(reinforcement signal)。在这种情况下,模型只能得到每次学习结果的增强信号,无法获取任何关于如何优化智能体(agent)表现(模型参数)的信息。因为我们无法针对结果定义损失函数(cost function),所以也就无法计算出梯度(gradient)以供模型优化参数。强化学习的解决办法是创建聪明的智能体并在外部环境中不断试错,来从经验中学习。

图1.8展示了强化学习的流程。

图1.8 强化学习与环境间的交互

前面我们了解了3类机器学习算法的异同。现在是时候回答这个问题了:如何根据具体需求选择相应算法呢?

然而,这个问题没有针对所有情形都普遍适用的答案,最好的答案可能是:看情况。对于不同情况都需要考虑哪些因素呢?需要考虑的主要因素来源于数据集,包括数据集的大小、质量高低以及数据间隐含的联系。同时,也需要考虑任务的目的、算法是如何编写的、有多长时间去训练这些算法等。总之,没有统一的标准,确定一个算法选取是否合理的唯一办法就是通过使用一下试试效果。

不过,为了弄明白最适合需求的算法是什么,我们可以进行一些预备分析。通过分析数据集、现有的工具(算法)、任务目标(输出结果)的基础性质,我们能够得到许多挑选算法的有用信息。

从分析数据集这个方法出发。我们可以从两个不同的角度挑选算法——输入和输出。[20]

(1)根据算法的输入进行挑选。

(2)根据输出进行挑选。

图1.9展示了基于已有的数据在挑选算法时可以参考的两个角度。

图1.9 预备分析

在了解了数据集的基本性质的基础上,我们可以进一步根据已有算法分析哪些算法适合我们的输入数据集,能够给出想要的输出结果,从而缩小目标算法的挑选范围。

在了解了数据集和有了明确的算法范围后,我们需要训练这些算法,评估各个算法的表现。我们把选择的算法应用到手头的数据集上。接下来,通过一系列精心选择的衡量算法表现的指标,我们能够对这些算法的表现进行比较,最终选出最合适的算法。

我们已经了解了挑选算法的标准和步骤,现在应该学习如何构建机器学习模型了。构建一个机器学习模型的流程可以分为以下几步,读者应该重视这一流程。[21]

(1)收集数据。毫无疑问,一切都源自数据[22],问题在于如何获取如此多的数据。实践中,获取这些数据可能需要经过冗长的步骤,例如有的数据是通过一系列实地测量得到的,有的是通过一对一的面谈得到的。无论如何,在收集数据的过程中,一定要注意选取合适的形式保存记录(如数据库),以利于接下来的分析。


如果没有特别需求,互联网上现存的大量公开数据就够用了,如加州大学尔湾分校机器学习数据集(UCI Machine Learning Repository)这一非常大的机器学习数据集,这使我们可以节省收集数据的精力和时间。


图1.10展示了构建机器学习模型的步骤。

(2)准备数据。在收集数据后,我们需要对原始数据进行一些处理。例如,很可能为了使数据集对于模型可用,调整数据集的数据格式。模型可能要求数据格式为整型、字符型或其他特殊格式[23]。接下来我们会专门介绍这些技巧,其中预处理数据一般要比收集数据简单。[24]

图1.10 构建机器学习模型的流程

(3)观察数据。至此,我们需要对数据集进行观察,例如确保数据可用(大致准确、没有大量的缺失值)。各种类型的图表可以辅助观察。我们能够辨别样本间所包含的模式、联系以及是否存在一些奇异值。绘制出不同维度的图表同样有助于观察数据。[25]

(4)训练(train)算法。现在,我们真正开始介绍如何构建机器学习模型。在这一步中,我们需要对模型[26]进行定义和训练[27],以使模型能够逐渐从训练数据集中抽取信息。我们将在后面的章节具体阐述这些概念。需要指出的是,训练阶段仅存在于监督学习中,对于非监督学习而言,是不存在训练阶段的。因为在非监督学习的输入数据中没有标签,所以无从训练。

(5)验证(validate)算法。在这一步骤中,我们使用上一步训练得到的模型进行验证[28],看模型是否真正有效。验证目标是评估训练得到的模型在多大程度上逼近了真实系统[29]。对于监督学习,有样本标签来帮助我们衡量结果。对于非监督学习,可能需要借助其他指标来衡量。无论属于哪种情况,如果模型没有达到预期效果,那么将返回步骤4,更改、重新训练新模型,并执行步骤5。

(6)测试(test)算法。在这一步骤中,我们将模型应用到真实数据集[30]上,以此评估整个算法流程的逼近效果。

(7)评估和改进模型:至此,我们验证了模型确实有效,同时了解了模型的表现。现在需要更新我们对模型、问题的理解,并尝试基于已有信息作进一步改进。

我们对机器学习已经有了基本的了解:机器学习的任务是什么、都有哪些算法、如何选择算法以及构建机器学习模型的流程。我们现在终于可以开始学习使用MATLAB实现这些功能的方法了。

使用MATLAB提供的工具构建机器学习模型来解决问题是极其方便的。MATLAB提供了非常强大的交互式界面、丰富的函数算法库、各种封装完善的App,这些可以帮助我们应用机器学习算法。

(1)聚类(clustering)、分类(classification)和回归(regression)算法。

(2)神经网络(neural network)App、曲线拟合App(curve fitting App)和分类器App(classification learner App)。

MATLAB是专为解决科学问题和进行科学计算而编写的软件平台,其中计算、可视化、编程等步骤都被精心集成在易于使用的开发环境中。这些科学问题和MALTAB提供的解决方案在MATLAB开发环境下都被表示为与问题相关的数学符号和公式。[31]

“MATLAB”这一名称由矩阵实验室(matrix laboratory)的首字母缩写得来。MATLAB最初的编写目标是为了方便线性代数和矩阵的操作,近年来快速增加了科学计算各个领域的丰富内容。MATLAB语言、开发环境设计本身是基于矩阵运算的,而矩阵是表达数学计算最自然的方式。MATLAB的桌面环境非常利于快速编写、验证模型和可视化数据等工作。集成在其中的与图像相关的工具有利于我们加深对数据集的理解。

MATLAB的开发环境如图1.11所示。

图1.11 MATLAB桌面

MATLAB以丰富、强大、精确、高质量的工具箱(toolbox)而著称。这些工具箱是由MATLAB函数(M文件)组成的,涵盖了诸多领域。对于很多领域的很多模型、算法,它都封装了专门的函数以供用户方便地调用并解决对应领域的问题,如图1.12所示。

图1.12 MATLAB中封装的部分App

MATLAB有两个专门为解决机器学习问题而编写的工具箱,它们是统计机器学习工具箱和神经网络工具箱。前者更专注于机器学习领域广泛应用的统计学[32]方法[33]和算法,后者是专门为人工神经网络(Artifical Neural Network,ANN)而编写的。在后续章节中,我们会逐一介绍这些工具箱的强大功能。

为了能够高效执行,包括MATLAB在内的所有软件都对计算机的软件和硬件有一些要求。MATLAB专业版和学生版可以运行在各个主流操作系统上,例如Linux、macOS和Windows。绝大多数近年的计算机都可足够支持运行MATLAB。

在Windows平台上安装MATLAB的要求如下所示。

(1)操作系统:Windows 10、Windows 8.1、Windows 8、Windows 7 Service Pack1、Windows Server 2016、Windows Server 2012 R2、Windows Server 2012和Windows Server 2008 R2 Service Pack 1。

(2)处理器:任何Intel或者AMD的x86-64架构的处理器;支持AVX2指令集的处理器;Polyspace用户,推荐使用四核及以上处理器。

(3)磁盘空间:仅包含MATLAB的基本环境,需要2GB,若还安装常用的工具箱(典型安装),则需要4~6GB。

(4)内存:最低要求为2GB。如果使用Simulink,则需要4GB;Polyspace用户推荐每核拥有4GB可用内存。

(5)显卡:对显卡没有明确要求。推荐使用支持OpenGL 3.3、拥有1GB显存的GPU硬件加速显卡。

Windows平台的安装要求如图1.13所示。

图1.13 Windows平台的安装要求

在安装MathWorks公司[34]的产品时,要求有一个通过购买产品或申请试用后下载获得的有效软件版权许可证[35]。为了从官网下载MathWorks公司的产品,我们必须有一个MathWorks公司的账户或者注册一个账户。

一旦下载了MathWorks安装向导,我们就可以运行安装向导并安装想要使用的产品。运行安装向导的要求如下所示。

(1)MathWorks账号的邮箱地址和密码(安装时需要登录账户)。

(2)安装相关产品的许可证。如果对许可证有任何疑问,请咨询系统管理员。

(3)安装过程中可能需要关闭杀毒软件和网络防火墙。这些软件可能造成安装失败或降低安装速度。

安装过程中要遵循安装向导的指示,安装结束后,我们就有一个能够运行的MATLAB了。

统计机器学习工具箱几乎包含了所有常用算法,其中的函数、App集成了对数据进行分析、描述、建模等功能。在开始分析数据集时,统计机器学习工具箱提供了丰富的统计指标和图表以帮助用户了解数据集。更进一步,拟合数据的概率分布、生成随机数据、假设检验等功能也得到了强大的支持。最后,借助回归、分类算法,我们能够对数据集进行拟合并构建预测模型。

对于数据挖掘任务,这个工具箱提供了特征选择(feature selection)、逐步回归、主成分分析(Principal Component Analysis,PCA)、正则化(regularization)和其他降维方法[36]。这些方法可以用于重要变量和重要数据关系的挖掘。

这个工具箱同时支持成熟的监督学习、非监督学习算法,包括支持向量机(Support Vector Machine,SVM)、决策树(decision tree)、k邻近算法(k-Nearest Neighbor,kNN)、k邻近样本中心算法(k-medoids)、层次聚类法(hierarchi calclustering)、高斯混合模型(Gaussian Mixture Model,GMM)和隐马尔可夫模型(Hidden Markov Model,HMM)。许多统计和机器学习算法可以用于大到无法在内存中存储的数据集的计算。Math Works官网对统计机器学习工具箱的功能展示,如图1.14所示。

图1.14 统计机器学习工具箱

以下是对这个工具箱中关键功能的简介,其中包含机器学习领域的几个主要方向。

(1)回归问题:包括对线性、广义线性、非线性、鲁棒性、正则化等回归问题,以及方差分析(analysis of variance,ANOVA)、重复测量分析(repeated measures analysis)、混合效应模型(mixed-effectsmodels)。

(2)处理大数据相关的算法:包括降维算法、描述性统计指标、k均值聚类、线性回归、逻辑回归(logistic regression)和判别分析(discriminant analysis)。

(3)多变量、单变量概率分布,随机和准随机(quasi-random)数据的生成,马尔可夫链抽样。

(4)多种假设检验:分布、弥散度(dispersion)、位置,实验设计方法包括优化、阶乘、响应曲面的设计。

(5)分类学习器App和监督学习的算法:包括支持向量机、促进式(boosted)决策树、袋装(bagged)决策树、k邻近算法、朴素贝叶斯(naive bayes)、判别分析、高斯过程回归。

(6)非监督学习:包括k均值聚类算法(k-means)、k邻近样本中心算法(k-medoids)、层次聚类法、高斯混合模型和隐马尔可夫模型。

(7)基于贝叶斯方法的机器学习模型超参数(hyper parameter)优化。

关于统计机器学习工具箱可用的一些参考资料如图1.15所示。

图1.15 统计机器学习工具箱的可用资料

在讨论统计机器学习工具箱之前,我们首先应该了解如何先格式化数据再将其输入至MATLAB处理。统计机器学习工具箱只支持某些特定的数据类型作为输入变量。如果选用了不支持的数据类型,那么MATLAB可能会报错或者返回错误结果。

1.支持的数据类型

(1)单精度(single precision)或者双精度(double precision)的数值型标量、向量、矩阵或数组。

(2)包含字符向量的cell数组(cellstr)、字符数组(char)、逻辑值数组(logical)、分类数组(categorical),以及数值型数组,比如含有分组信息的类型变量的数值型数组single/double。

(3)一些函数支持表格类数组;table数据类型可以存储上面介绍的任意数据类型。

(4)一些添加了GPU加速支持的函数可以支持GPU数组(gpuArray)。

2.不支持的数据类型

(1)复数。

(2)自定义数据类型,比如,一个变量既是一个对象,也是双精度型的。

(3)用于非分组数据的有符号(signed)或者无符号(unsigned)整型数,例如unint8int16。

(4)稀疏矩阵(sparse matrix)。应用时,稀疏矩阵需要使用full函数转化为matrix类型。

在之前的章节中,我们分析了统计机器学习工具箱的主要功能以及支持的数据类型。现在,我们可以理所应当地问:对于MATLAB提供的这些函数,我们真正能做什么?在本节中,我们将着重讲述这个工具箱中重要的函数,并以实际应用场景进行举例。下面来看一些应用程序。

1.数据挖掘与数据可视化

数据挖掘是指使用几个领域[37]的交叉方法,从大量的数据集中发现隐含关系的过程。通过这个过程,我们能够从多种角度分析数据集并提取有用信息。这些信息能帮助我们更好地理解目标问题和挑选模型算法。

MATLAB提供了许多数据挖掘工具。尤其是统计机器学习工具箱,它集成了多种从数据集中提取有用信息的工具。

(1)绘制统计数据图表的交互式图形界面。

(2)针对大型数据优化的和计算统计指标的函数。

图1.16是一个多元(multivariate)数据集可视化的例子。

图1.16 可视化多元数据集

举个例子,我们能够使用交互性图表,通过统计绘图,从数据可视化探索开始我们的分析。MATLAB提供了大量的图表工具,尤其是统计机器学习工具箱提供了概率分布图(probability plot)、箱形图(boxplot)、柱状图(histogram)、散点柱状图(scatter histogram)、三维柱状图(3D histogram)、控制图(control chart)、分位图/QQ图(quantile-quantile plot)等。对于多元变量的绘制,MATLAB还提供了额外的树状聚类图(dendrogram)、双标图(biplot)、并行坐标图(parallel coordinate chart)和安德烈图(Andrews plot)。

在一些情形中,我们必须对多元变量进行可视化。许多统计分析算法都要求有自变量(predictor variable, independent variable)和因变量(dependent variable,response variable)两个输入变量。它们之间的关系很容易用二维散点图、柱状图、箱形图等表示。含有3个变量的时候,相似的图表也很容易扩展到三维。然而,对于许多包含多个变量的数据集而言,可视化会变得更困难。MATLAB中添加了许多对多变量进行可视化的支持,如图1.16所示。

完成上述步骤后,我们需要从描述性统计指标中提取有用的信息。描述性统计功能囊括了一系列的方法和工具,可以帮助我们描述、展示、总结数据集统计特性,并获取最重要的统计指标。统计机器学习工具箱中包含以下函数用于计算统计指标。

(1)集中趋势(central tendency):平均数(mean)、中位数(median)、众数(mode)等。

(2)度量(dispertion)、极差(range)、方差(variance)、标准差(standard deviation)、平均绝对离差(mean absolute deviation)、绝对中位差(median absolute deviation)。

(3)线性相关(linear correlation)系数和等级相关或秩相关(rank correlation)系数。

(4)缺失值处理。

(5)分位数(quantile)、百分位数(percentile)估计。

(6)使用核光滑(kernel-smoothing)方法进行密度估计(density estimation)。

2.回归分析

回归分析常用于分析变量间的关系,其目的是建立由一个或多个自变量到因变量的函数映射关系。统计机器学习工具箱中包含如下模型支持。

(1)线性回归(Linear regression)。

(2)非线性回归(Nonlinear regression)。

(3)广义线性回归(Generalized linear model)。

(4)混合效应模型(mixed-effects model)。

图1.17所示的是线性回归模型的散点图(scatter plot)。

散点图有助于理解变量间的联系。在图1.17中,横坐标显示的是自变量X,纵坐标显示的是因变量Y。通过回归模型,我们能够拟合两个变量间的变化关系。如图1.17所示,简单的线性方程足以拟合线性关系明显的样本集。

图1.17 线性回归方程及样本散点图

3.分类模型

分类模型属于监督学习中的一大类模型,它们的任务是预测给定样本的类别信息。

统计机器学习工具箱提供了大量的App和函数来实现含参数、不含参数的分类模型。

(1)逻辑回归(logistic regression)。

(2)促进式决策树和袋装决策树(包括AdaBoost、LogitBoost、GentleBoost和RobustBoost)。

(3)朴素贝叶斯分类。

(4)k邻近算法分类。

(5)判别分析(包括线性和二次型)。

(6)支持向量机(SVM)(二分类和多分类)。

使用分类学习应用程序能够交互式地浏览数据集、选取特征、配置交叉验证(cross-validation)参数、训练模型参数、评估结果,其包含如下功能。

(1)导入数据,设定交叉验证参数。

(2)浏览数据,选择特征值。

(3)选用各类分类算法来训练模型。

(4)比较和评估模型。

(5)共享已训练好的模型(兼容计算地机视觉应用和信号处理应用的格式)。

通过使用分类学习应用程序,我们能够非常方便地挑选算法、训练和验证模型。训练完成后,比较不同模型的验证误差,以供用户挑选表现最好的模型和参数组合。

图1.18所示的就是分类学习应用程序。

图1.18 分类学习应用程序截屏,其中有不同分类算法的历史执行记录

4.聚类分析

聚类分析是无监督学习中的一大类方法。笼统地说,聚类学习的目标是通过观察数据集中的统计特征,计算以某种形式定义的距离概念,最小化簇内距离和最大化簇间距离,从而实现对数据集的自动聚类。聚类分析中的距离常使用一些定义好的统计学指标[38]的相似度进行计量。

统计机器学习工具箱包含以下聚类算法的支持。

(1)k均值聚类算法。

(2)k邻近样本中心算法。

(3)层次聚类法。

(4)高斯混合模型。

(5)隐马尔可夫模型。

当不知道聚类的数量时,我们可以使用聚类评估技术[39]根据特定指标来确定数据中存在的聚类数量。

图1.19展示了一些聚类分析的结果。

图1.19 聚类算法展示

除此之外,统计机器学习工具箱提供了用来展示层次二分类聚类树的树状聚类图。我们可以很方便地通过优化叶节点顺序来改善聚类效果。最后,对于每一簇,我们可以基于多元方差分析计算的均值,来绘制树状聚类图。

5.降维

降维分析是将含有多个变量的高维数据转化为较低维数据[40],同时尽量保留原有信息的过程。降维方法[41]能够改进模型预测结果,提高模型可解释程度(降低模型复杂度),还能够避免过拟合(over-fitting)。统计机器学习工具箱集成了多种降维算法,这些算法可以分为特征提取(feature extraction)和特征选择(feature selection)两类。特征选择方法试图选取原特征矩阵中最能代表整体数据集的子集,特征提取方法则试图通过降维把原有数据转化为新的特征[42]

该工具箱对特征选择提供如下支持。

(1)逐步回归(stepwise regression):依次增加或删除特征,直到预测精度没有改进为止。这种方法尤其适合线性回归和广义线性回归算法。

(2)顺序化特征选择(sequential feature selection):等价于逐步回归算法,适用于任何监督学习算法。[43]

(3)促进式决策树和袋装决策树:利用袋外(out-of-bag)误差计算变量的重要性。

(4)正则化:通过将冗余特征权重(系数)减至0来消除冗余特征。

此外,该工具箱还添加了对特征提取算法的支持。

(1)主成分分析:通过投影到独特的正交基底上来汇总维度较少的数据。

(2)非负矩阵因式分解(non-negative matrix factorization):当模型术语必须代表非负数量(如物理量)时使用。

(3)因子分析(factor analysis):用于构建数据关联的解释模型。

图1.20展示了逐步回归的例子。

图1.20 逐步回归的例子

人工神经网络是受人脑启发,以多层或每层多个人工神经元(artificial neuron)构成的网络模型。每个神经元与相邻层的神经元都有多个输入和输出链接,单个神经元将相邻输入神经元的输出加总后对激活函数(activate function)执行运算。人工神经网络通过训练,能够自我学习数据集的特征,对复杂问题进行有效拟合,非常适合应用于传统计算机算法无法明确表述的复杂的问题。

神经网络工具箱提供了各类相关的算法、预训练(pre-trained)网络模型,以及用于构建、训练、可视化和仿真神经网络的App。通过应用这些工具,我们能够方便地解决分类、回归、聚类、降维、时间序列预测、动态系统建模以及控制问题。

拥有少数几层隐含层(hidden layer)的神经网络称为浅层神经网络(shallow neural network),拥有多层隐含层的神经网络称为深度神经网络(deep neural network)[44]。深度神经网络包括卷积神经网络(Convolutional Neural Network,CNN)、自编码网络(auto-encoder)等,适用于分类、回归及特征学习。对于中等规模的数据集,我们可以通过迁移学习的方式,使用MATLAB自带的预训练网络,快速应用深度神经网络,节省训练时间和改善预测结果。对于大规模数据,我们可以使用MATLAB提供的并行计算工具箱借助GPU来加速网络训练。通过MATLAB分布式计算服务器(MATLAB Distributed Computing Server),我们可以将计算任务分配到集群中的各个节点以进一步加速。

神经网络工具箱主要涵盖了以下功能。

(1)基于卷积神经网络(用于分类和回归)、自编码网络(用于特征值学习)的深度学习模型。

(2)基于预训练卷积神经网络和Caffe model zoo[45]的迁移学习。

(3)基于单节点、集群、云的多CPU、GPU模型训练和推断。

(4)非监督学习算法包括自组织映射网络(self-organizing map)和竞争层(competitive layer)。

(5)监督学习算法包括多层前馈(multilayer feedforward)神经网络、径向基函数(Radial Basis Function,RBF)神经网络、学习向量量化(Learning Vector Quantization,LVQ)神经网络、延时神经网络、非线性自回归神经网络、循环神经网络(Recurrent Neural Network,RNN)。

(6)用于数据拟合、模式识别和聚类的App。

(7)预处理、后处理、神经网络的可视化、训练和评估神经网络。

MATLAB官网对神经网络工具箱的功能展示如图1.21所示。

图1.21 神经网络工具箱的功能展示

机器学习是由统计学、概率论、代数、计算机科学等诸多学科组成的交叉学科。这些学科交叉在一起,赋予机器学习算法从原始数据集中进行迭代式学习、寻找样本间的隐藏模式以及构建智能应用的能力。尽管机器学习算法直接提供了强大的学习能力,但是了解这些算法背后其他学科的理论支撑和数学含义,能够极大加深我们对算法的理解和应用。

在机器学习中,统计学、概率论和代数知识非常重要,主要体现在以下几点。

(1)根据特征数量、训练时间、参数个数、模型复杂度以及任务要求的精度选取适当算法。

(2)配置验证算法参数,设置模型的超参数。

(3)发现过拟合及拟合不足问题。

(4)设置合理的置信区间。

MATLAB为统计分析、线性代数的运算提供了很多函数,例如,使用MATLAB计算描述性统计指标非常简单。用户可以度量集中趋势、分散度、弥散度、分布形状、相关性、协方差、分位数、百分位数等诸多统计指标,还可以建立表单(tabulate)数据和跨表单(cross-tabulate)数据,并且对分组后的数据计算描述性统计指标。

值得注意的是,MATLAB语法规定,任何对NaN(MATLAB中表示空值的关键字)执行的数值运算都将返回NaN。统计机器学习工具箱中的函数对NaN进行了特殊优化。当输入数据中包含NaN时,这些函数将忽略NaN,直接使用非空值数据进行计算。

更强大的是,MATLAB提供了非常方便的可视化工具以帮助我们可视化数据集的统计特征、分布特征,并能够与其他数据集、概率分布进行比较。不仅可以对单个变量的分布问题绘制散点图、箱形图、柱状图,对双变量问题同样也可以绘制这些图表。对于多变量的问题,我们可以通过绘制多元图表(安德烈图、字符图等方法)进行可视化。最后,我们还可以定制化图表,其中包括内嵌最小二乘线、辅助线和注释等信息。

对于线性代数,MATLAB同样提供了非常多的函数支持。线性代数是研究数值矩阵和进行线性运算(线性方程组)的学科。MATLAB提供了丰富且极易使用和理解的向量、矩阵操作运算支持。

MATLAB对如下功能提供函数支持:矩阵操作和矩阵变换、线性方程组、矩阵分解、特征值和特征向量、矩阵分析和向量微积分、标准形和特殊矩阵以及矩阵函数。

有了这些支持,在MATLAB中进行线性代数的运算会变得极为简单,如图1.22所示。

图1.22 使用柱状图进行概率密度函数估计

在本章中,我们领略了机器学习世界的强大功能,并了解了几种主流算法及其适用情景;学习了如何对数据集进行预分析以及如何选择算法,并了解了构建机器学习模型的详细步骤。

接着,我们将视线转移到了MATLAB上,介绍了MATLAB的安装须知,强调了MATLAB在机器学习领域(如分类、回归、聚类和深度学习)中的诸多支持,还包括自动化模型训练和由代码生成的App。

最后,我们着重介绍了统计机器学习工具箱和神经网络工具箱,展示了其中包含的工具以及这些工具的适用场景,也展示了统计学和线性代数在机器学习中的重要作用以及MATLAB对这些学科的相关支持。

在下一章中,我们将学习如何使用MATLAB的工作区(workspace)、如何导入/导出数据、如何组织数据以及如何根据使用需求将数据整理为特定格式。

[1] 译者注:算法。

[2] 译者注:算法。

[3] 译者注:机器学习方法能够自动从数据集中拟合出描述此数据集的模型。例如,给定数据集,然后从中自动建立输入数据到输出数据的映射关系,一大类方法是参数估计方法。参数估计是指首先假设输入数据到输出数据间存在某种形式的映射关系(如高斯分布),然而我们并不知道这种映射关系的具体参数,因此需要通过学习数据集中的信息对参数进行拟合。

[4] 译者注:未知变量。

[5] 译者注:根据这组数据。

[6] 译者注:估计出的模型。

[7] 译者注:对于这部分,作者写得过于晦涩且并非机器学习的经典分类方法,因此在翻译时我加入了一些例子以说明和其他经典教材上的解释,翻译参考中文教材《机器学习》(周志华版)。

[8] 译者注:如基于规则的方法。

[9] 译者注:特征工程。

[10] 译者注:本节所介绍的归纳与演绎是科学推理的两大基本手段。发展到目前的机器学习是更偏向于归纳学习的,即通过样本学习规律。

[11] 译者注:泛化(generalization)能力。

[12] 译者注:描述这个数据集样本间某种关系的模型。

[13] 译者注:可以通过网页间的相互引用关系、文本内容等,自动将不同网站进行归类。

[14] 译者注:还有游戏角色的开发。

[15] 译者注:从概率论的角度来说,如果数据集中的所有样本都是从同一分布P(A)中抽样得到的,那么通过向监督学习算法输入足够的样本,算法优化后得到的分布P(B)能够无限逼近真实分布P(A)。

[16] 译者注:从概率论的角度来说,将模型P(B)应用在新数据上时,其输出结果应当与真实分布P(A)的输出结果相似。

[17] 译者注:这段话太片面,在频率视角下和概率视角下的最大似然估计方法、贝叶斯方法中的高斯分布(单极值点)的确存在这个问题。但是对于多数模型,添加先验概率后的后验概率分布在很大程度上解决了这个问题。对于多极值点的模型,高斯混合分布的鲁棒性是非常高的。因为这段话我不太认同,所以在这里专门添加了译者注。

[18] 译者注:搜索引擎的学习算法能够通过网页间的相互引用关系、文本内容等,自动将不同网站分类。当用户输入搜索关键词时,算法同样可以将用户输入的指令进行归类,并将属于同一类别的网页返回给用户。在整个过程中,算法都没有得到任何有关类别的信息,但通过计算样本间的相似度,算法能够自动建立样本间的联系。

[19] 译者注:是指数据集中含有标注。

[20] 译者注:这两个角度虽然都属于数据集的性质范围,但不是同一层次上的问题。这里的“输入”指的是算法接收的训练数据集的性质,比如数据集中的样本点是否都有对应的标签。输出是指对于给定算法的数据集(如训练数据集)中的输入值,对应的输出值的性质,是连续、离散抑或是组成的簇(见下文)。

[21] 译者注:在下面的步骤中,除了构建机器学习模型的部分(主要是步骤4和步骤5),对数据集的预处理、执行结果的评估和模型改进同样至关重要。

[22] 译者注:切记,在机器学习领域,数据集质量的高低直接决定结果的好坏。

[23] 译者注:数据去量纲化等。

[24] 译者注:一般而言,有固定的模式可循。

[25] 译者注:步骤5、步骤6、步骤7并不是经典方法。理论上应该分为训练、验证和测试这3个步骤。原书中步骤6和步骤7的解释几乎混淆了,因此对步骤5、步骤6、步骤7进行了适当调整,把书中的训练、测试和验证对应改成了训练、验证和测试,然后进行了翻译。

[26] 译者注:目标函数、限制条件。

[27] 译者注:采取某种优化算法对模型参数在训练数据集中进行求解。

[28] 译者注:应用在外部的、新添加的、模型没有见过的数据集上。在机器学习领域中,这一步的数据集特指验证集。

[29] 译者注:从概率角度而言,是指数据的真实分布。

[30] 译者注:在机器学习领域中特指这一步的数据集为测试集。

[31] 译者注:MATLAB语言设计得非常贴近数学公式本身,便于快速实现科学计算。MATLAB帮助文档同样含有丰富的数学概念。

[32] 译者注:还有概率论。

[33] 译者注:统计机器学习方法。

[34] 译者注:开发MATLAB的公司。

[35] 译者注:很多大学都已经为学生购买了教育版的许可证。

[36] 译者注:这里的PCA属于降维方法之一。

[37] 译者注:如人工智能、机器学习、统计学和数据库。

[38] 译者注:离散度、信息熵。

[39] 译者注:MATLAB提供了专门的evalclusters函数。

[40] 译者注:将高维矩阵变化为低维矩阵。

[41] 译者注:减少数据中的冗余信息。

[42] 译者注:矩阵变换等方法会将原有特征矩阵去除冗余信息并生成新的特征矩阵。

[43] 译者注:相当于专为普遍适用监督学习而改进的逐步回归算法。

[44] 译者注:现在也普遍称为深度学习模型(deep learning model)。

[45] 译者注:Caffe是深度学习领域最流行的框架之一,model zoo是Caffe的模型库。


本章主要内容

如今,每天都有大量的数据产生。智能手机、信用卡、电视机、计算机、传感器、公共与私人交通等设备都在不间断地产生数据,而这些只是冰山一角。这些数据被存储起来,用于各种目的,比如使用机器学习算法进行数据分析。

在第1章中,我们分析了构建机器学习模型的流程。流程最开始的部分便是收集数据、组织数据(导入数据和预处理数据)。这一步对所构建模型的正常运行和得到正确结果是至关重要的。

在本章中,我们会介绍如何使用MATLAB导入数据和预处理数据。读者首先应该熟悉MATLAB的工作区,因为它可以让这些操作变得尽可能简单。然后,我们将介绍数据的不同格式和如何把这些数据导入/导出MATLAB。除此之外,我们还会介绍专门处理分组变量和类别数据的数据类型,如何把各类数据(元胞数组、结构体数组、表单数据)从MATLAB工作区中导出并以MATLAB兼容的数据类型进行存储。最后,我们介绍了如何以正确的格式组织数据,以用于下一步的数据分析。

学完本章后,读者应该可以正确导入、格式化和组织数据,并能顺利过渡到流程的下一步,即通过数据分析观察和探索数据。

MATLAB是一个基于矩阵的交互式工作环境,而矩阵是表达数学计算最自然的方式。更重要的是,MATLAB是专为各学科的技术、数学问题和系统仿真而设计的编程语言,其中集成的图像工具有助于用户方便地从数据中观察和获取有用的信息,各类工具箱包含的丰富函数库则有助于用户我们迅速上手。

安装成功后,双击MATLAB图标或者在系统命令行下输入matlab并按Enter键,可启动MATLAB。第一次启动时,MATLAB会以默认的布局向用户展示一系列子面板,其中包含各种组件,以便用户操作。MATLAB R2017a在Windows 10系统上的桌面如图2.1所示。

图2.1 Windows 10系统上MATLAB R2017a的桌面

MATLAB桌面包含以下面板。

(1)当前文件夹(current folder):展示了当前路径下所存储的文件和文件夹(用户可以改变当前路径)。

(2)命令窗口(command window):在这个面板中,在命令提示符(>>)处可以输入任何MATLAB命令或者表达式,方便用户交互式地输入命令。

(3)工作区(workspace):展示已经创建或者通过从数据文件、其他程序中导入而得到的变量。

(4)命令历史记录(command history):展示已经输入命令的历史记录,用以直接快速调用展示的命令。[1]

想要对MATLAB桌面有一个全面的了解,我们可以使用如下命令。

(1)help:在命令窗口中展示所有主要的帮助信息。

(2)lookfor:在所有帮助条目中搜索一个关键词。

(3)demo:打开MATLAB帮助页面,其中包含产品的使用例子。

(4)doc:打开MATLAB帮助页面,其中包含各类文档的索引。

在命令提示符处输入quit或者exit,或者用鼠标单击桌面右上角红色的“关闭”按钮,即可关闭MATLAB。MATLAB工具栏如图2.2所示。

图2.2 MATLAB工具栏

MATLAB现在使用经典的功能分区界面(ribbon interface)是Windows系统中一些应用所带的GUI界面。如图2.2所示,位于桌面的顶端是MATLAB工具栏。这个工具栏将MATLAB的功能用一系列选项卡组织起来。每个选项卡被划分到不同的功能区,每个功能区都包含类似相关功能的控件。这些控件包含各种按钮、下拉菜单等用户界面接口,使用这些控件在MATLAB中可以进行相关操作。[2]

比如,HOME选项卡中包含对文件、变量、代码进行操作的控件,PLOTS选项卡包含一些画图的控件,APPS选项卡中包含调用MATLAB应用的一些控件。

使用MATLAB最初步最简单的方式是把它当作一个计算器。比如,想要得到10和90两个数字之和,则只需将光标放置于命令提示符(>>)的右方,输入10+90然后按下Enter键,即可得到结果。

>>10+90
ans =
 100
>>

在MATLAB桌面中完成数学运算的过程如图2.3所示。

图2.3 在MATLAB桌面中完成数学运算

MATLAB完成数学运算并把结果赋值给变量ans。虽然我们没有指定将运算结果赋值给某一个变量,但是MATLAB会使用默认变量ans——它是“answer”这个单词的简写。

接下来,每执行一次这样的运算命令而又没有指定赋值变量时,MATLAB都会执行一次这样的默认赋值操作,因此上一次ans变量中的值会被这一次的运算结果所覆盖。


为了避免失去之前的运算结果,每一次运算后,我们都会定义新的赋值变量。


运算完成后,MATLAB会在工作区窗口中显示ans变量,会在命令历史记录窗口中显示这一次命令的历史记录(见图2.3)。

为了定义一个能够存储数据内容的变量,我们使用赋值语句。比如,创建两个变量FIRSTSECOND的语句如下:

>> FIRST = 10
FIRST =
 10
>> SECOND = 90
SECOND =
 90
>>

现在将两个变量相加,并且结果存入第三个变量THIRD中:

>> THIRD = FIRST + SECOND
THIRD =
 100
>>

我们已经知道,由于MATLAB中的基本元素是矩阵,因此所有输入信息都以矩阵形式进行存储。因此,变量FIRSTSECONDTHIRD都只包含一个元素的矩阵。创建一个只有1行并包含10个元素的矩阵(行向量),将元素以中括号括住,以空格或者逗号分隔:

>> vector = [10 20 30 40 50 60 70 80 90 100]
vector =
 10 20 30 40 50 60 70 80 90 100
>>

类似地,为了创建一个有多行的矩阵,我们用分号来分隔行:

>> matrix = [10 20 30; 40 50 60 ;70 80 90]
matrix =
 10 20 30
 40 50 60
 70 80 90
>>

为了访问矩阵中的元素,我们可以使用索引(indexing)。就像下面所示的代码,通过指定行和列的下标,选择矩阵中第一行和第二列的元素:

>> matrix (1,2)
ans =
 20
>>

为了选择矩阵中的多个元素,我们应使用冒号(:)运算符,使用start:end这种形式指定一个区间。比如选定矩阵中的前三行中第三列的所有元素:

>> matrix (1:3,3)
ans =
 30
 60
 90
>>

省略startend,我们会得到这个维度的所有元素。因此,上面例子的结果也可以用如下这种方式来获得:

>> matrix (:,3)
ans =
 30
 60
 90
>>

冒号运算符也能够创建一个由等差数列组成的向量,形式为start:step:end。如下代码创建了一个包含0~20的所有偶数的矩阵:

>> vector_even = 0:2:20
 vector_even =
 0 2 4 6 8 10 12 14 16 18 20
>>

为了管理工作区中的数据,whowhosclear这3个命令非常有用。whowhos能够以不同的详细程度列出工作区中的内容;clear可以删除所有变量,清空工作区,使用命令查看已经创建的变量。

>> who
Your variables are:
FIRST SECOND THIRD matrix vector
vector_even
>> whos
 Name   Size Bytes Class Attributes
 FIRST   1x1 8 double
 SECOND   1x1 8 double
 THIRD 1x1 8 double
 matrix 3x3 72 double
 vector        1x10 80 double
 vector_even 1x11 88 double
>>

whos的返回结果实际上就是MATLAB工作区中变量的详细信息,如图2.4所示。

想要清空工作区,可以使用clear命令:

>> clear
>> who
>>

在上面的例子中,我们用who来确定工作区被清空了。请谨慎使用clear,因为所清除的变量可能无法恢复。如果之后还会使用变量,则在退出MATLAB前,一定要记得使用save命令保存工作区中的变量,如图2.4所示。

图2.4 工作区变量列表

>> save filename.mat

使用save命令,将工作区中的所有内容压缩到一个文件中,文件扩展名是.mat,这称作MAT-文件。想要将一个MAT-文件中的内容恢复到工作区中,可以使用load命令:

>> load filename.mat

MATLAB提供了大量的函数来执行特定的运算任务。比如,可以调用函数mean()来计算矩阵中元素的平均值,注意将该函数的输入参数放入圆括号中:

>> vector
vector =
 10 20 30 40 50 60 70 80 90 100
>> mean(vector)
ans =
 55
>>

在外部存储设备和数据分析环境之间交换数据,这在数据分析中扮演着重要的角色。数据分析的第一步是将收集的数据导入MATLAB中进行分析,数据分析的最后一步是将结果导出。根据数据的不同格式,有相对应的不同方法在MATLAB环境中导入和导出数据。在本节中,我们将介绍数据导入。

我们既可以交互式地向MATLAB中导入数据,也可以通过程序语句导入数据。[4]交互式地导入数据时,数据可以来源于硬盘上的文件或者系统剪贴板。

从硬盘的文件中导入数据可以是如下方式的任意一种。

(1)在HOME选项卡的Variable功能区中,单击ImportData

(2)在当前文件夹面板中双击文件名。

(3)在命令窗口面板中调用函数uiimport()。

从剪切板导入数据可以是如下方式的任意一种:

(1)单击工作区面板标题栏上的三角形图标并且选择Paste

(2)在命令窗口面板中调用函数uiimport()。

上述两种方法都可以打开导入向导。对初学者而言,导入向导非常有用,它能根据数据的性质提供不同的导入方式,在数据导入过程中给予各种帮助。我们能够从多种的类型文件(包括图片、音频、视频数据等)中进行导入。导入向导能够显示文件内容,可供用户选择导入的数据,去掉不需要的数据。

导入向导中使用的命令可以被存入一个MATLAB函数或者脚本文件中。用户可以保存这个文件,在导入相似的文件时,可以重复使用它。这里用一个实际例子来说明导入向导是如何工作的。比如想要导入一个电子表格到MATLAB工作区中(表格中每一个字段对应一个变量),使用导入向导完成这项工作的步骤如下。

下面的步骤说明了通过导入工具导入文本数据(电子表格)的过程。

(1)打开导入向导

(2)通过单击ImportData按钮,打开ImportData的对话框。

(3)选择想要导入的文件(在这里,选择IrisData.csv),然后打开MATLAB的IMPORT工具,如图2.5所示。[5]

图2.5 导入工具窗口

(4)IMPORT工具(见图2.5)中包含对所选择文件中数据的预览:用户可以只选择需要的数据,或者直接导入整个文件。

(5)在功能区中Imported Data(见图2.5)的OutputType这个标签下,用户可以选择导出数据的方式。

(6)这里选择下拉菜单中的Columnvectors这个选项。

(7)现在单击Importselection按钮(见图2.5),IMPORT会在工作区中创建相应的变量。

检查工作区中是否出现了相应的变量,可以确认操作是否成功,如图2.6所示。在上面的步骤中,我们得到了6个新的变量:PetalLengthPetalWidthSepalLengthSepalWidthSpeciesVarName1。它们分别对应着选中文件的6列。为了分析每一个变量中的内容,我们可以在命令窗口的命令提示符(>>)下直接输入变量名进行调用,也可以直接在工作区中双击这个变量名。它会打开变量窗口(variables window),显示变量的值。

图2.6 变量的检查

确保变量被正确导入MATLAB后,用户就能够使用这些变量进行运算或者操作了。

如前所述,通过程序语句可以向MATLAB中导入数据。这种数据导入方式非常重要,因为这可以把这些程序插入到脚本中,然后通过调用脚本来快速运行,而使用导入向导需要用户一步步地进行操作。通过程序语句来导入数据需要借助MATLAB提供的导入函数。每个导入函数都有其适用的数据类型,因此选择合适的导入函数非常关键。

1.从文件中加载变量

本书之前已经出现过相关的例子。使用函数load()save()加载和存储工作区中的数据,代码如下:[6]

>> save filename.mat
>> load filename.mat


注意,这两个函数可以对.mat文件进行操作,也可以对ASCII文本文件进行操作。


上面的代码展示了如何加载一个.mat文件。这是一个特定文件格式,可以存储工作区中的内容。现在我们简单介绍一下如何加载ASCII文本文件。对于这个任务,根据文件分割符(将文本文件中的值进行分隔的符号)的不同,可以选用不同的函数。如果文件中包含一些以空格、逗号、分号或者制表符(Tab)相分隔的数值,就可以使用函数load()。比如一个文本文件matrix.txt的内容如下:

10 20 30
40 50 60
70 80 90

通过以下语句将matrix.txt中的内容读取到一个MATLAB矩阵:

>> load matrix.txt
>> matrix
matrix =
 10 20 30
 40 50 60
 70 80 90
>>

2.读取ASCII分隔的文件

上面的例子中,加载文件只需要使用函数load(),不需要进行额外的操作。MATLAB加载文件后,自动将数据内容读取到一个与文件名相同的变量中。我们还可以使用更加灵活的dlmread()函数,使用户能够指定文件中的分隔符并且指定导入哪部分数据。函数要求加载的文件必须是数值型的,以matrix.txt文件为例:

10;20;30
40;50;60
70;80;90

使用函数dlmread()读取这样的ASCII分隔的文件(ASCII-delimitedfile):

>> MatrixTxt=dlmread('matrix.txt',';')
MatrixTxt =
 10 20 30
 40 50 60
 70 80 90
>>

只导入文件中的前两行前两列:

>> MatrixTxt2=dlmread('matrix.txt',',','A1..B2')
MatrixTxt2 =
 10 20
 40 50
>>


函数dlmread()可以对含有非数值型数据的文件进行操作,只要指定导入的行和列中所包含的数据仅有数值型数据即可。


3.读取逗号分隔值文件

假设有如下matrix.csv文件:

10,20,30
40,50,60
70,80,90

这是一种特殊的文件类型,数值都以逗号隔开,这称为逗号分隔值(Comma Separated Value,CSV)文件。MATLAB提供函数csvread()来读取这种文件类型,可以指定只导入文件中的部分数据,只要保证指定部分只包含数值即可。使用的例子如下:

>> MatrixCsv=csvread('matrix.csv')
MatrixCsv =
 10 20 30
 40 50 60
 70 80 90
>>

用户通过这个函数可以选定导入哪些行哪些列。如下命令只导入文件matrix.csv中一定范围内的数据:

>> MatrixCsv2=csvread('matrix.csv',0,0,[0,0,1,2])
MatrixCsv2 =
 10 20 30
 40 50 60
>>

现在对上面例子中函数调用的参数进行解析,从而理解如何指定导入数据的范围:

csvread('matrix.csv',0,0,[0,0,1,2])

第一个参数是文件名,第二个参数指定从哪一行开始读取,第三个参数指定从哪一列开始读取[7]。第四个参数是一个矩阵,它指定了读取哪些范围内的值。现在对这个矩阵的含义进行分析。

[0,0,1,2]

矩阵中第一个数和第二个数代表指定范围左上角的数的偏移量,第三个数和第四个数代表指定范围右下角的数的偏移量。在这个例子中,0、0表示坐上角这个数的行、列偏移量都为0,即选中的是文件中第一行第一列的元素;1、2表示右下角这个数的行、列偏移量分别为1、2,即选中的是文件中第二行和第三列的元素。[8]

4.读取电子表格

另一种常见的文件格式是电子表格,这里特指由Excel创建的表格。MATLAB用函数xlsread()来导入这类文件中的数据。这个函数能够将文件中混合在一起的数值型数据和文本型数据导入到不同的矩阵中。以表格文件capri.xlsx为例,其中包含着卡普里岛(一个那不勒斯湾的迷人小岛)2016年8月份的温度数据(以℃为单位)。Temp工作表中有如下数据(为了节省空间只列出前5天的数据)。

Day

TMean

Tmax

Tmin

1

26

24

29

2

26

24

29

3

26

24

30

4

27

24

30

5

26

23

28

使用函数xlsread()来导入数据。第一个参数是文件名,第二个参数是工作表名:

>>values = xlsread('capri.xlsx','Temp')
values =
1 26 24 29
2 26 24 29
3 26 24 30
4 27 24 30
5 26 23 28
>>

在上面的例子中,MATLAB会去掉工作表中第一行的表头文本数据,只保留数值型数据并将其存储到结果中。为了获取完整的信息,我们将数值数据和表头的文本数据都导入——这需要在调用xlsread()的时候指定两个输出参数:

>>[values,headertxt ]= xlsread('capri.xlsx','Temp')
values =
1 26 24 29
2 26 24 29
3 26 24 30
4 27 24 30
5 26 23 28
>> headertxt=
'Day''TMean''Tmin''Tmax'
>>

上面的例子中得到了两个变量,其中一个矩阵(values)包含所有数值型数据,另一个元胞数组(headertxt)包含表头的文本型数据。用户也可以指定导入部分数据,在下面的例子中,xlsread()函数只读取了这个电子表格中前两行的数值型数据:

>>row1_2 = xlsread('capri.xlsx','Temp', 'A2:D3')
row1_2 =
1 26 24 29
2 26 24 29
>>

类似地,可以只读取指定列的数值型数据:

>>column_C = xlsread('capri.xlsx','Temp', 'C2:C6')
column_C =
24
24
24
24
23
>>

5.读取字符串和数值混合的文件

生活中除了数字,还有很多东西是不可或缺的。通常用户需要处理的文件既包含数值型数据又包含文本型数据。在MATLAB中,只有一部分导入函数能够同时处理字符串和数字,如readtable()。这个函数将文件读取到一个table中。为了理解这个函数是如何工作的,我们分析了一个包含近两年参观意大利博物馆的游客人数的数据文件,如图2.7所示。

图2.7 参观意大利博物馆的游客人数

函数readtable()通过从文件中读取面向列的数据来创建table。支持的文件类型包含以下内容。

(1)带分隔符的文本文件:.txt.dat.csv

(2)电子表格文件:.xls.xlsb.xlsm.xlsx.xltm.xltx.ods

readtable()为该文件中的每列在返回的table中创建一个变量,并从文件的第一行中读取变量名称。默认情况下,如果整列均为数值,则已创建的变量为双精度型,如果列中的任意元素不是数值,则为包含字符向量的元胞数组。

本例的数据文件包含在museum.xls中,代码如下:

>> TableMuseum = readtable('museum.xls')
TableMuseum =
 10×5 table
N Museum City Visitors_2016 Visitors_2015
__ _________________________ ________ _____________ ____________
1 'Colosseo e Foro Romano' 'ROMA' 6.4089e+06 6.551e+06
2 'Scavi di Pompei' 'POMPEI' 3.2837e+06 2.934e+06
3 'Galleria degli Uffizi' 'FIRENZE'2.0106e+06 1.9718e+06
4 'Galleria dell'Accademia…''FIRENZE' 1.4612e+06 1.4154e+06
5 'Castel Sant'Angelo' 'ROMA' 1.2344e+06 1.0473e+06
6 'Venaria Reale' 'VENARIA' 1.012e+06 5.8079e+05
7 'Museo Egizio di Torino' 'TORINO' 8.8146e+05 8.6354e+05
8 'Circuito Museale Boboli …''FIRENZE' 8.521e+05 7.7293e+05
9 'Reggia di Caserta' 'CASERTA' 6.8307e+05 4.972e+05
10 'Galleria Borghese' 'ROMA' 5.2794e+05 5.0644e+05

也可以创建一个table,并且不将列标题作为变量名称:

>> TableMuseum = readtable('museum.xls','ReadVariableNames',false)
TableMuseum =
 10×5 table
Var1 Var2 Var3 Var4 Var5
__ _________________________ ________ _____________ ____________
1 'Colosseo e Foro Romano' 'ROMA' 6.4089e+06 6.551e+06
2 'Scavi di Pompei' 'POMPEI' 3.2837e+06 2.934e+06
3 'Galleria degli Uffizi' 'FIRENZE' 2.0106e+06 1.9718e+06
4 'Galleria dell'Accademia…' 'FIRENZE' 1.4612e+06 1.4154e+06
5 'Castel Sant'Angelo' 'ROMA' 1.2344e+06 1.0473e+06
6 'Venaria Reale' 'VENARIA' 1.012e+06 5.8079e+05
7 'Museo Egizio di Torino' 'TORINO' 8.8146e+05 8.6354e+05
8 'Circuito Museale Boboli …''FIRENZE' 8.521e+05 7.7293e+05
9 'Reggia di Caserta' 'CASERTA' 6.8307e+05 4.972e+05
10 'Galleria Borghese' 'ROMA' 5.2794e+05 5.0644e+05

能够同时处理既包含数值型数据又包含文本型数据的文件的函数还有textscan()。这个函数将已打开的文本文件中的数据读取到cell数组,该文件由文件标识符(如fileID)来指示。用户需要使用fopen()打开文件并获取fileID,而不能打开文件直接对其操作。读取完文件后,请调用fclose(fileID)来关闭文件。

元胞数组是一种包含名为cell的索引数据容器的数据类型,其中每个元胞都可以包含任意类型的数据。元胞数组通常包含文本字符串列表(文本和数字的组合)、不同大小的数值数组等。

使用这个函数需要定义一个数据字段的格式(formatspecification,formatSpec)。每一个转换设定符(conversionspecifier)对应一个匹配的数据,比如:%s对应字符向量,%d对应整数,%f对应浮点数。

这里我们以Ferrari.txt文件作为例子,其中包含着5个最新的法拉利车型,文件内容如图2.8所示。

图2.8 5个最新的法拉利车型的信息

先指定数据字段的格式:

>> formatSpec = '%u%s%d%d';

然后以只读模式打开这个文件,并将文件标识符赋值给变量fileID

>> fileID = fopen('Ferrari.txt');

应用textscan()函数并且把结果赋值给变量Ferrari:

>> Ferrari = textscan(fileID,formatSpec);

使用完毕后关闭文件:

>> fclose(fileID)

至此,已经成功地导入了文件中的数据,让我们检查一下:

>>whos Ferrari
 Name Size Bytes Class Attributes
 Ferrari 1x4 635 cell

查看每个cell中的数据类型:

>> Ferrari
Ferrari = 1×4 cell array
 [5×1 uint32] {5×1 cell} [5×1 uint32] [5×1 uint32]

最后,检查其中的每一个条目:

>> celldisp(Ferrari)
Ferrari{1} =
2014
2015
2015
2016
2017
Ferrari{2}{1} =
Ferrari458SpecialeA
Ferrari{2}{2} =
Ferrari488GTB
Ferrari{2}{3} =
Ferrari488Spider
Ferrari{2}{4} =
FerrariJ50
Ferrari{2}{5} =
Ferrari812Superfast
Ferrari{3} =
4497
3902
3902
3902
6496
Ferrari{4} =
605
670
670
690
800

在MATLAB中,许多导入数据的函数都有对应的函数帮助用户导出数据。在本章的开头,我们已经看到了使用save命令可存储供日后使用的数据:

>> save filename.mat


上面的命令将工作区中的所有内容压缩后存储到一个带有.mat扩展名的文件中。这一文件称作MAT-文件。


函数dlmwrite()让用户能够处理由指定分隔符分隔的文本文件。用户使用这个函数能把矩阵写入一个ASCII分隔的文件中。这里使用由随机数字组成的矩阵来体验一下这个函数:

>> MyMatrix = rand(5)
MyMatrix =
 0.7577 0.7060 0.8235 0.4387 0.4898
 0.7431 0.0318 0.6948 0.3816 0.4456
 0.3922 0.2769 0.3171 0.7655 0.6463
 0.6555 0.0462 0.9502 0.7952 0.7094
 0.1712 0.0971 0.0344 0.1869 0.7547

现在把矩阵MyMatrix写入一个名为MyMatrix.txt的文件中,使用默认的分隔符(,):

>> dlmwrite('MyMatrix.txt', MyMatrix)

显示文件中的数据内容:

>> type('MyMatrix.txt')
0.75774,0.70605,0.82346,0.43874,0.48976
0.74313,0.031833,0.69483,0.38156,0.44559
0.39223,0.27692,0.3171,0.76552,0.64631
0.65548,0.046171,0.95022,0.7952,0.70936
0.17119,0.097132,0.034446,0.18687,0.75469

使用函数xlswrite()可把数据导入一个电子表格文件中。这个函数把矩阵写入Excel电子表格中。可以新生成一个随机矩阵来体验一下这个函数,注意,新的随机矩阵中的数字是不同的,因为函数rand()每次调用都会随机的数值:

>> MyMatrix = rand(5)
MyMatrix =
 0.2760 0.4984 0.7513 0.9593 0.8407
 0.6797 0.9597 0.2551 0.5472 0.2543
 0.6551 0.3404 0.5060 0.1386 0.8143
 0.1626 0.5853 0.6991 0.1493 0.2435
 0.1190 0.2238 0.8909 0.2575 0.9293

MyMatrix写入一个名为MyMatrix.xls的文件中:

>> xlswrite('MyMatrix.xls', MyMatrix)

想要将MATLAB中的数据导出到.csv文件中,可使用函数csvwrite()。下面仍然会使用一个随机矩阵的例子:

>> MyMatrix = rand(5)
MyMatrix =
 0.3500 0.3517 0.2858 0.0759 0.1299
 0.1966 0.8308 0.7572 0.0540 0.5688
 0.2511 0.5853 0.7537 0.5308 0.4694
 0.6160 0.5497 0.3804 0.7792 0.0119
 0.4733 0.9172 0.5678 0.9340 0.3371

MyMatrix写入一个名为MyMatrix.csv的文件中:

>> csvwrite('MyMatrix.csv', MyMatrix)

以上例子执行完毕后,可以查看当前文件夹来检查是否3种文件都已经正确创建了(见图2.9)。

图2.9 从MATLAB中导出数据

图像、视频、音频文件现在是人们生活中不可分割的一部分。基于现在的先进技术和设备,我们能够获取、存储和操作这些数据。在机器学习应用中,它们通常也被作为输入数据。机器学习算法能够从中提取很多不易察觉的信息。在本节中,我们学习如何在MATLAB环境下处理这些文件。

光栅图[9]由带颜色的像素点网格组成。在MATLAB中,图像能够被表示成为一个二维矩阵,矩阵中的每一个元素对应图像中的一个像素点。比如,一个800像素×600像素的图像(包含600行和800列各类颜色的像素点)会被MATLAB存储为一个600×800的矩阵。在某些情况下,我们需要第三维来存储颜色的深度。比如,对于RGB图像,需要指定红、绿、蓝3个颜色通道值以构建一个彩色图像。

MATLAB提供了几种函数来处理和展示图像,下面给出了图像处理中几个最常见函数的描述。

(1)imread:从图形文件中读取图像。

(2)imwrite:将图像写入图形文件。

(3)image:显示图像(创建图像对象)。

(4)imfinfo:从图形文件中获取图像信息。

(5)imagesc:归一化数据然后显示图像[10]

(6)ind2rgb:将索引图像转化为RGB图像。

用户可以使用函数imread()将图像导入MATLAB中。这个函数接收图形文件的文件名作为函数参数,然后获取这个图形文件的图像内容:

>> Coliseum = imread('coliseum.jpg');

这是一张罗马斗兽场的美丽图片,也被称作福雷维安圆形剧场(Flavian Amphi theatre),它是意大利罗马的一个椭圆形露天剧场。这个文件的分辨率是1650像素×1042像素(见图2.10),因此得到的矩阵的大小是1650×1042×3。

图2.10 把图像导入MATLAB

使用函数imwrite()可将图像导出MATLAB。这个函数可以将变量中的图像数据写入用户指定的文件。导出文件的格式由用户指定的文件扩展名来决定。这个导出的新文件会被放在用户指定的文件存储路径中。导出图像的色深(bit-depth)由图像数据的数据类型和导出文件的格式共同决定。导出图像的代码如下:[11]

>>imwrite(Coliseum,'coliseum.jpg');

执行上述代码,导出的是一张罗马斗兽场的美丽图片,作为一个样例图形文件,可读取图像到MATLAB。

在接下来的章节中,我们会在实际例子中使用这里所给出的部分函数。如果读者需要全面掌握这些操作,那么一定要参考MATLAB的帮助手册。

音频数据能够用几种文件格式来存储。不同文件格式之间的区别取决于数据压缩的程度——压缩程度会对音频质量有影响。MATLAB提供了一些用于处理音频文件的函数,把数据写入音频文件,获取有关音频文件的信息,从音频文件中读取数据,借助音频输入设备录制音频数据,播放音频文件。下面给出了最常用的音频操作的函数。

(1)audioread:读取音频文件。

(2)audioinfo:获取有关音频文件的信息。

(3)audiowrite:将数据写入音频文件。

(4)audiodevino:获取音频设备的相关信息。

(5)audioplayer:创建播放音频的对象。

(6)auidorecorder:创建录制音频的对象。

(7)sound:将信号数据矩阵转换为声音。

(8)soundsc:缩放数据并作为声音播放。

(9)beep:产生操作系统蜂鸣声。

函数audioread()能够读取音频文件。这个函数支持WAVE、OCG、FLAC、AU、MP3和MPEG-4AAC文件格式。这里将导入一个简短的音频文件,这是NASA记录的阿波罗13号的原始录音,其中有航天史上那句著名的话:“休斯敦,我们有麻烦了。”(Hoston,we have a problem):

>>[apollo13,Fs] = audioread('apollo13.wav');

上面的例子生成了两个变量:一个是音频数据的矩阵apollo13;另一个是采样率Fs。我们同样能够交互式地读取音频文件:单击HOME选项卡下的ImportData,或者双击当前文件夹的文件名就可读取文件。可以利用上面的两个变量,使用MATLAB的播放器播放这个音频文件:

>> sound(apollo13,Fs)

可以使用audioplayer()函数对播放过程进行更多的控制。这个函数允许用户暂停、恢复播放、定义回调函数。为了使用这些特性,我们需要创建一个audioplayer对象,然后调用这个对象的方法去播放音频:

>> Apollo13Obj = audioplayer(apollo13,Fs);
>> play(Apollo13Obj);

现在我们在MATLAB工作区中有了音频文件的数据——以矩阵apollo13的形式存在——我们可以使用函数audiowrite()导出它:

>> audiowrite('apollo13.wav',apollo13,Fs)

这个命令把数据写入名为apollo13.wav的WAVE文件中,文件放置于当前文件夹下。这个函数同样也能以其他文件格式写入音频文件,如OCG、FLAC和MPEG-4 AAC。最后我们可以使用函数audioinfo()获取有关文件apollo13.wav的信息:

>> InfoAudio = audioinfo('apollo13.wav')

到目前为止,我们在组织数据时大多使用标准矩阵。这些矩阵是能有效存储大量数据对象的数据结构,如数值矩阵和字符矩阵。然而,这样的矩阵不适用于数据对象中既有数字也有字符串的情况。MATLAB编程环境提供的许多数据结构(如元胞数组和结构体数组)能够解决这个问题。

元胞数组是一种包含名为cell的索引数据容器的数据类型,其中每个cell都可以包含任意类型的数据。元胞数组通常包含文本字符串列表、文本和数字的组合或不同大小的数值数组。

创建一个元胞数组后,能够使用元胞数组构造运算符{},下面例子中的元胞数组包含了家庭成员的姓名和年龄:

>> MyFamily = {'Luigi', 'Simone', 'Tiziana'; 13, 11, 43}
MyFamily =
 2×3 cell array
 'Luigi' 'Simone' 'Tiziana'
 [ 13] [ 11] [ 43]

如所有MATLAB中的矩阵一样,元胞数组同样是长方形的,即每一行都含有相同数量的cell。比如,在上面的例子中我们创建的MyFamily元胞数组是一个2×3的矩阵。

为了对元胞数组中的数据执行数学运算,我们必须访问它的内容。有两种方式可以访问元胞数组中的元素。

(1)将索引括在圆括号()中以引用元胞的集合,例如定义这个元胞数组的一个子集。

(2)将索引括在大括号{}中以引用各个元胞中的文本、数字或其他数据。

如下代码获取了一个元胞的集合:

>> MyFamily2= MyFamily(1:2,1:2)
MyFamily2 =
 2×2 cell array
 'Luigi' 'Simone'
 [ 13] [ 11]

上面的代码创建了一个新的元胞数组,它包含MyFamily这个初始元胞数组的前两行。现在我们展示如何通过大括号{}访问单个元胞中的内容。继续使用之前创建的元胞数组,抽取出最后一个元胞中的内容:

>> LastCell= MyFamily{2,3}
LastCell =
 43
>> class(LastCell)
ans =
double

通过这种方式,我们创建了一个双精度类型的数值变量。我们可以使用相同的语法去更改一个cell中的内容:

>> MyFamily2{2,2}=110
MyFamily2 =
 2×2 cell array
 'Luigi' 'Simone'
 [ 13] [ 110]

如果想要访问多个元胞中的内容,那么请使用大括号。MATLAB会以逗号分隔的列表(comma- separatedlist)形式返回这些元胞的内容:[12]

>> MyFamily{1:2,1:3}
ans =
 'Luigi'
ans =
 13
ans =
 'Simone'
ans =
 11
ans =
 'Tiziana'
ans =
 430

可以使用如下命令把上面产生的列表分配给与元胞数量相同的变量:

>> [r1c1, r2c1, r1c2, r2c2, r1c3, r2c3]= MyFamily{1:2,1:3}
r1c1 =
 'Luigi'
r2c1 =
 13
r1c2 =
 'Simone'
r2c2 =
 11
r1c3 =
 'Tiziana'
r2c3 =
 430

在上面的例子中,每个变量都对应着各个元胞中的数据内容,它们有着相同的数据类型。因此,对应着第一行元胞的变量是char类型,对应着第二行元胞的会是双精度类型。可以进行如下检查:

>> class(r1c1)
ans =
 'char'
>> class(r2c1)
ans =
 'double'

如果每个元胞包含相同类型的数据,则可以通过将数组串联运算符[]应用于这个逗号分隔的列表来创建单个变量:

>> Age = [MyFamily{2,:}]
Age =
 13 11 43

可以使用数组串联运算符[]串联元胞数组。在下面的例子中,我们用分号分隔符将第一个元胞数组(MyFamily)和另一个包含成员性别的元胞数组垂直串联起来:

>> MyFamily=[MyFamily;{'M','M','F'}]
MyFamily =
 3×3 cell array

 'Luigi' 'Simone' 'Tiziana'
 [ 13] [11][ 43]
 'M''M' 'F'

结构体数组(structure array)和元胞数组非常类似,因为它们都能将不同数据类型的数据组织在单一变量中。和元胞数组的不同之处在于,结构体数组的数据是由称作字段(field)的名称指定的,而不是由数字索引指定的(每一个字段都能包含任意类型和大小的数据)。它使用原点表示法而不是用大括号{}索引来访问其中的数据。下面举例说明如何创建一个包含零售商客户数据的结构体数组,数据中包含如下字段:nameamountdata(包含不同类型物品的购买数量)。这是一个多字段的结构体数组。先定义字段和其对应的值,然后创建结构体数组(见图2.11):

>> field1 = 'Name';
>> value1 = {'Luigi','Simone','Tiziana'}
>> field2 = 'Amount';
>> value2 = {150000,250000,50000};
>> field3 = 'Data';
>> value3 = {[25, 65, 43; 150, 168, 127.5; 280, 110, 170],[5, 5, 23; 120,
118, 107.5; 200, 100, 140],[15, 45, 23; 160, 158, 12; 230, 140, 160]};

>> customers = struct(field1,value1,field2,value2,field3,value3)
customers =
 1×3 struct array with fields:
 Name
 Amount
 Data

如图2.11所示,我们能够看到由之前代码创建的结构体数组。

图2.11 结构体数组[13]

如前所述,用户可以使用原点表示法来访问结构体数组中的数据:

>> customers(1).Name
ans =
 'Luigi'

>> customers(1).Amount
ans =
 150000

>> customers(1).Data
ans =
 25.0000 65.0000 43.0000
 150.0000 168.0000 127.5000
 280.0000 110.0000 170.0000

在上面的例子中,圆括号内的数字是行记录的索引结构体数组。customers数组中的每一行记录都是一个struct类的结构体[14]。与其他MATLAB数组类似,结构体数组可以为任意大小:

>> class(customers)
ans =
 'struct'

结构体数组具有下列属性。

(1)数组中的所有记录都具有相同数目的字段。

(2)所有记录具有相同的字段名称。

(3)不同记录中的同名字段可包含不同类型或大小的数据。

当插入一条新记录时,在数组中新记录的任何未指定字段均包含空数组:

>> customers(4).Name='Giuseppe';
>> customers(4)
ans =
 struct with fields:
 Name: 'Giuseppe'
 Amount: []
 Data: []

现在看一下如何根据第一个顾客的数据创建一个条形图(见图2.12):

>> bar(customers(1).Data)
>> title(['Data of first customer: ', customers(1).Name])

要想访问字段的一部分内容,则请根据字段中数据的大小和类型添加合适的索引。比如只访问前两个客户的Data字段:

>> customers(1:2).Data
ans =
 25.0000 65.0000 43.0000
 150.0000 168.0000 127.5000
 280.0000 110.0000 170.0000

ans =
 5.0000 5.0000 23.0000
 120.0000 118.0000 107.5000
 200.0000 100.0000 140.0000

图2.12所示为第一个客户的Data字段的条形图。

图2.12 第一个客户的Data字段的条形图[15]

进一步来讲,如果只想访问Data字段中第一个客户的前两行和前两列的数据,那么使用以下方式:

>> customers(1).Data(1:2,1:2)
ans =
 25 65
 150 168

MATLAB中的table数据类型用来将混合类型的数据和元数据属性(如变量名称、行名称、说明和变量单位)收集到单个容器中。table数据类型适合表达表格数据,这些数据通常以列形式存储在文本文件或电子表格中。表中的每个变量可以具有不同的数据类型和大小,但每个变量必须具有相同的行数。table数据类型的一个典型用法是存储试验数据,使用行表示不同的观测结果,使用列表示不同的测量变量。

图2.13所示的是一个数据集例子。

现在让我们看一下如何利用MATLAB工作区中的变量创建一个表,并且如何对这个表进行可视化。我们还可以使用导入工具或者使用函数readtable()从已经存在的电子表格或者文本文件中创建一个table。当使用这些工具从外部文件中导入数据时,外部文件中的每一列对应着表中的表变量[16]。这里为了快速和方便地把数据导入表中,我们使用了MATLAB软件自带的数据例子。下面会直接把MATLAB软件自带的MAT-文件hospital.mat导入到工作区中,其中包含100个病人的医院数据。导入后能够在工作区中看到这些变量(见图2.13)。

图2.13 仿真的医院数据

>> load hospital
>> whos
 Name Size Bytes Class Attributes
 Description 1x23 46 char
 Hospital 100x7 46480 dataset

可以访问每个table变量中的数据,或者通过使用table变量名配合原点表示法只选择table变量中的一部分数据。在这个例子中,我们选择将原始表中每个字段的数据抽取为离散变量:

>> LastName=hospital.LastName;
>> Sex=hospital.Sex;
>> Age=hospital.Age;
>> Weight=hospital.Weight;

现在创建一个表格,并向它里面填充之前已经在工作区字段(列)中提取的数据LastNameSexAgeWeight。为了节省空间,这里只展示前5行的数据:

>> TablePatients = table(LastName,Sex,Age,Weight);
>> TablePatients(1:5,:)
ans =
 10×4 table
 LastName Sex Age Weight
 __________ ______ ___ ______
 'SMITH' Male 38 176
 'JOHNSON' Male 43 163
 'WILLIAMS' Female 38 131
 'JONES' Female 40 133
 'BROWN' Female 49 119

可以使用原点表示法添加新的字段。先从最开始的数据集中抽取血压(blood pressure)数据,然后把它拆分成为两个变量:

>> BlPrMax=hospital.BloodPressure(:,1);
>> BlPrMin=hospital.BloodPressure(:,2);

然后把这两个变量加入到table中:

>> TablePatients.BlPrMax=BlPrMax;
>> TablePatients.BlPrMin=BlPrMin;

为了确认刚才操作的正确性,我们打印3行数据进行检查:

>> TablePatients(1:5,[1 5:6])
ans =
 5×3 table
 LastName BlPrMax BlPrMin
 __________ _______ _______
 'SMITH' 124 93
 'JOHNSON' 109 77
 'WILLIAMS' 125 83
 'JONES' 117 75
 'BROWN' 122 80

使用函数summary()能够创建一个汇总表来查看table变量的数据类型、说明、单位和其他描述性统计指标:

>> summary(TablePatients)
Variables:
 LastName: 100×1 cell array of character vectors
 Sex: 100×1 categorical
 Values:
 Female 53
 Male 47
 Age: 100×1 double
 Values:
 Min 25
 Median 39
 Max 50
 Weight: 100×1 double
 Values:
 Min 111
 Median 142.5
 Max 202
 BlPrMax: 100×1 double
 Values:
 Min 109
 Median 122
 Max 138
 BlPrMin: 100×1 double
 Values:
 Min 68
 Median 81.5
 Max 99

分类数组(categorical array)旨在存储具有以下特征的数据:此类数据的值只能来自一个包含离散类别的有限集合。这些类别可以采用自然排序,也可以是非自然排序。如果分类数组中记录的属性是离散的,有不能排序的值,就说它是无序分类的(categorical unordered)。这些属性被赋值,除了能够区分类别,没有其他意义(如男人、女人这两个类别)。相应地,如果分类数组中记录的属性是离散的,能够进行排序,就说它是有序分类的(categorical ordered)。这些属性被赋值且能够比较它们之间的大小关系(如1、2、3、4)。

可以使用函数categorical()从一个数值数组、逻辑数组、元胞数组、字符数组或是一个已经存在的分类数组中创建分类数组。这里使用之前数据中的SexAge变量,它们包含医院中病人的性别和年龄。这些变量通过以下代码转化成一个分类数组:

>> SexC=categorical(Sex);
>> categories(SexC)
ans =
 2×1 cell array
 'Female'
 'Male'
>> AgeC=categorical(Age);
>> categories(AgeC)
ans =
 25×1 cell array
 '25''27''28''29''30''31''32''33''34''35''36''37''38''39'
'40''41''42''43''44''45''46''47''48''49'50'

我们注意到,SexC矩阵的类别是按字母顺序显示出来的(它是无序分类的),然而AgeC矩阵的类别是按开序显示出来的(它是有序分类的)。

在接下来的例子中。我们展示了如何从分箱(binning)后的数值型数据中创建一个有序分类数组。数据分箱是一种数据预处理方法,可以用来降低观测结果的误差。原始数据的值经过分箱后会分别落入给定的区间,这些值会转化为这个区间的代表值,这个值通常是区间的中心值。我们使用函数discretize()Age变量进行分箱,创建出一个分类数组。把[25,50]这个区间分为3个小区间(25~33,33~41,41~50),每个小区间都包含左边的端点不包含右边的端点。我们也会为每个小区间提供一个名字进行区分:

>> NameBin = {'FirstBin', 'SecondBin', 'ThirdBin'};
>> AgeBin = discretize(Age,[25 33 41 50],'categorical',NameBin);

这样,我们就创建了一个100×1的分类数组。这个数组有3个类别:

FirstBin < SecondBin < ThirdBin

最后使用函数summary()打印每个类别中数据点的数量:

>> summary(AgeBin)
 FirstBin 27
 SecondBin 33
 ThirdBin 40

在本章中,我们首先探索了MATLAB桌面,并且介绍了如何轻松地和它交互;其次简要介绍了MATLAB工具栏,并且说明了它是如何由一系列选项卡组织起来的,然后我们把MATLAB当作一个简单的计算器并且学习了如何操作矩阵。

之后我们探索了MATLAB的导入功能——能够读取数据源中的不同输入类型,还介绍了如何交互式地或者通过程序语句将数据导入MATLAB,以及如何从工作区中导出数据以及处理媒体文件。

最后,我们介绍了数据组织的内容,以及如何使用元胞数组、结构体数组、table和分类数组。

在下一章中,我们会介绍机器学习领域中的不同数据类型,以及如何清洗数据和辨识丢失的数据。除此之外,我们还会讲述如何处理异常值和派生数据,以及最常见的描述性统计方法和某些数据分析方法。

[1] 译者注:使用鼠标选择命令,即可以直接执行。

[2] 译者注:在MATLAB界面中,这些控件一般都有对应的图标。

[3] 译者注:这里作者将MATLAB的导入向导(Import Wizard)和导入工具(Import Tool)混用了。更严格的区分是:导入向导专门导入图片、音频、视频;导入工具专门导入文本数据。但是调用两者的方式完全相同,只是适应的场景不同。更多信息请查阅MATLAB帮助文档。

[4] 译者注:本节中的导入向导就是交互式地导入数据。

[5] 译者注:这里的图中没有给出这个文件,MATLAB也不包含这个数据文件,因此这里的例子是有问题的。

[6] 译者注:这里load和load()是同一个函数,save和save()是同一个函数,loadfilename.txt是函数的命令形式。load('filename.txt')是函数的调用形式。关于load、save函数的更多信息参见MATLAB帮助文档。

[7] 译者注:第二个参数指定行的偏移量,第三个参数指定列的偏移量。两个参数为0表示行列偏移量均为0,即从文件的第一行第一列开始读取。

[8] 译者注:左上角和右下角的含义是这两个数的位置,它们刚好界定了一个矩形,这个矩形包含的数就是选中的数。

[9] 译者注:也称作像素图、位图和点阵图。

[10] 译者注:显示经过标度映射的颜色图像。

[11] 译者注:色深是指使用多少位来定义一个像素点。色深越大,可以表示的色彩就越多。通常情况下,图像的像素值范围为0~255,其色深就是8。RGB图像的色深为24,8位表示R、8位表示G、8位表示B。

[12] 译者注:在上面的代码中,元胞的内容是按列产生的,即先顺序执行完第一列,再执行之后的列,依此类推。

[13] 译者注:这里图中的显示和代码的执行结果不同,按书中的代码,Data字段应该是3×3的double而不是3×9的double。

[14] 译者注:由结构体(structure)构成的数组通常称为结构体数组。

[15] 译者注:这里显示的和实际代码的运行结果不符合,原因和图2.11相同。

[16] 译者注:即每列中的测量变量。


相关图书

ChatGPT原理与应用开发
ChatGPT原理与应用开发
动手学机器学习
动手学机器学习
机器学习与数据挖掘
机器学习与数据挖掘
机器学习公式详解 第2版
机器学习公式详解 第2版
自然语言处理迁移学习实战
自然语言处理迁移学习实战
AI医学图像处理(基于Python语言的Dragonfly)
AI医学图像处理(基于Python语言的Dragonfly)

相关文章

相关课程