《机器学习与R语言(原书第2版)》一 第2章 数据的管理和理解

本节书摘来自华章出版社《机器学习与R语言(原书第2版)》一书中的第2章,第2.1节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问“华章计算机”公众号查看。

第2章

数据的管理和理解

任何机器学习项目初期的核心部分都是与管理和理解所收集的数据有关的。尽管你可能发现这些工作不像建立和部署模型那样令人有成就感(建立和部署模型阶段就开始看到了劳动的成果),但是忽视这些重要的准备工作是不明智的。
任何学习算法的好坏取决于输入数据的好坏。在很多情况下,输入数据是复杂的、凌乱的并且取自多种不同渠道和格式。因为这些复杂性,所以投入机器学习项目中的很大一部分精力要花在数据准备和探索中。
本章从3个方面来讨论这些主题。第一节讨论R用来存储数据的基本数据结构。学完这一节后,在你创建和管理数据集时,你就对这些数据结构非常熟悉了。第二节是实践,这节讨论从R中输入或者输出数据的几种常用函数。第三节通过探索一个真实世界数据集的例子来说明理解数据的方法。
学完本章后,你将理解:
基本的R数据结构以及如何使用它们来存储和提取数据。
如何把常见来源格式的数据导入R。
理解并可视化复杂数据的典型方法。
因为R考虑数据的方式定义了你应该考虑数据的方式,所以在进入数据准备工作之前,理解基本的R数据结构是很有帮助的。然而,如果你已经对R的数据结构很熟悉了,你完全可以跳过这部分,直接学习数据预处理部分。

2.1 R数据结构

在程序语言中有多种形式的数据结构,在应用到特定的任务时,它们各有优势和劣势。因为R是一个在统计数据分析中广泛运用的程序语言,所以R所用的数据结构的设计目的是使它易于处理这类工作。
在机器学习中经常使用的R数据结构是:向量、因子、列表、数组、矩阵和数据框。每种数据类型都针对一类具体的数据管理任务,所以知道它们如何与R项目相互交互是至关重要的。

2.1.1 向量

R的基本数据结构是向量。向量存储一组有序的值,称为元素。一个向量可以包含任意数量的元素。然而,所有的元素必须是一样的类型,比如,一个向量不能同时包含数字和文本。可以应用命令typeof(v)来确定向量v的类型。
在机器学习中常用的几种向量类型包括:integer(整型,没有小数的数字)、double (双精度浮点类型,即包含小数的数字)、character(字符型,文本数据)或者logical(逻辑型,取值为TRUE或者FALSE)。还有两个特殊的值:NULL,用来表明没有任何值;NA,用来表明一个缺失值。
有些R函数把integer和double类型的向量都报告为numeric,而其他函数则对这两种类型加以区别。因此,尽管所有double类型的向量是numeric类型,但并非所有numeric类型的向量是double类型。
手工输入大量的数据会单调乏味,但是一些简单的向量还是可以用组合函数c()来创建。向量也能通过使用箭头运算符“<-”来给它赋一个名字,这是R的赋值运算符,与很多其他程序语言中的赋值运算符“=”的使用方法差不多。
例如,我们构建多个向量来存储3个体检病人的诊断数据。创建一个字符向量subject_name,它包含3个病人的姓名;一个数值向量temperature,它包含每个病人的体温;以及一个逻辑向量flu_status,它包含每个病人的诊断情况(如果病人患有流感则取值为TRUE,否则为FALSE)。创建这3个向量的代码如下所示:

因为R中的向量有固有的顺序,所以其数据能通过计算向量中各个元素的序号来访问,序号是从1开始算起的,并且在向量名字的后面用方括号括起这个序号(例如,[和])。例如,为了获得温度向量中Jane Doe或者序号为2的病人的体温,只要简单地输入:

为了从向量中提取数据,R提供了各种方便的方法。一个范围内的值可以通过冒号(:)操作符获得。例如,为了获得Jane Doe 和Steve Graves 的体温,输入:

通过指定一个负的序号可以把该项排除在输出数据之外。要想排除Jane Doe的体温数据,输入:

最后,可以通过一个逻辑向量来标识每一项是否包含在内,有时候这也是很有用的。例如,需要包括前两个温度读数,但是排除第三个,就可以输入:

正如你将看到的,向量是很多其他R数据结构的基础。因此,了解不同类型的向量操作对在R中操作数据是很重要的。
下载例子代码
你能用你的账号在网站http://www.packtpub.com下载你已经购买的所有Packt出版的书的例子代码文件。如果你是在其他地方购买这本书的,你可以通过访问http://www.packtpub.com/support网站并且注册,通过电子邮件的形式把文件直接发给你。
本书第2版新增加了一个下载网站,你可以通过GitHub网站:
https://github.com/dataspelunking/MLwR/来获取本书的例子代码。登录本网站获取最新的R代码、事件追踪和公用wiki。请加入本社区。

2.1.2 因子

如果你回忆第1章的内容,用类别值来代表特征的属性称为名义属性。尽管可以用一个字符向量来存储名义属性数据,但R提供了一个数据结构专门来表示这种属性数据。因子是向量的一个特例,它单独用来标识分类或者有序变量。在前面构建的医学体检数据集中,可以用一个因子来表示性别(gender),因为它有两个类别:MALE和FEMALE。
为什么不用字符向量呢?使用因子的一个优势在于类别标签只存储一次。例如,不存储MALE、MALE、FEMALE,计算机只要存储1、1、2,这样可以减少存储同样信息所需要的内存容量。另外,许多机器学习算法用不同的方式来处理名义数据和数值数据。经常需要把变量编码为因子,这样R函数才能合理地处理分类数据。
因子不应该用来处理不是真正分类数据的字符向量。如果一个向量主要存储类似名字或标识字符串这样的唯一值,那么还是把它作为字符向量。
要把字符向量转换成因子,只需要应用factor()函数。例如:

注意,当John Doe和Jane Doe的性别数据显示出来后,R输出关于gender因子的额外的信息。变量levles(水平)由factor(因子)可能取的类别值组成,在这个例子中是MALE或者FEMALE。
当创建因子时,可以增加没有在数据中出现的其他水平。假设增加表示血型变量的另一个因子,如下所示:

注意,当我们为3个病人定义blood(血型)因子时,我们用levels参数来说明一个额外的向量,该向量给出了4个可能的血型。因此,即使数据仅包含O型、AB型和A型,但所有的4种血型和输出给出的blood因子存储在一起。存储额外的水平使得未来增加具有其他血型类型的数据成为可能。它也保证了尽管血型B没有记录在我们的数据中,但是当我们创建血型类型表时,我们知道类型B是存在的。
因子数据结构还允许包含关于名义变量类别的顺序信息,这给出了存储有序数据的方便方式。例如,假设我们有病人symptoms(症状)的数据,按照严重程度的水平升序排列:从MILD(不严重)、MODERATE(中等)到SEVERE(严重)。我们通过下述方式来呈现有序数据:以期望的顺序给出因子的level(水平),从最低到最高的升序方式来列出有序数据,并设置ordered参数的值为TURE。如下所示:

由此产生的symptoms因子现在就包含了我们需要的顺序信息。与之前的因子不同,这个因子的水平值由<符号分隔,它表明了从不严重到严重的序列顺序:

有序因子的一个有用的特性是进行你期望的逻辑测试工作。例如,可以检验病人的症状是否比moderate(中等)还严重。

能够对有序数据建模的机器学习算法将期望输入数据为有序因子,所以确保对你的数据进行相应的编码。

2.1.3 列表

列表是一个与向量类似的数据结构,因为它用来存储一个元素的有序集合。然而,向量要求所有元素都必须是同一种类型,列表允许收集不同类型的元素。由于这个灵活性,列表一直用于存储不同类型的输入和输出数据,以及机器学习模型所使用配置的结构参数的集合。
例如,考虑我们构建的体检病人的数据集,3个病人的数据存储在6个向量中。如果我们要显示关于John Doe(对象1)所有的数据,我们需要输入6条R命令:

显示一个病人的医疗数据看上去像是一个庞大的工程。列表结构使我们能够把所有病人的数据放到一个我们能够重复使用的对象中。
与使用c()创建一个向量类似,列表使用list()函数创建,如下面例子中所示。一个明显的不同是,当列表建立以后,序列中的每一个成分几乎都有一个名字。名字不是必需的,但是它使得接下来能够通过名字访问列表中的值,而不是通过位置序号。为了给第一个病人的所有数据创建一个含有名字成分的列表,输下面的代码:

现在病人的数据被收集到subject1列表中了。
注意,取值是由前面命令中指定的名字标识的。然而,列表也能用类似访问向量的方法来访问。为了获取temperature的值,采用下面的命令:


在列表对象上应用向量风格的运算符得到的结果是另一个列表对象,它是原始列表的一个子集。例如,上面的代码返回具有唯一temperature成分的一个列表。为了以简单数据类型返回一个单一的列表项,在尝试选取列表成分时应用双方括号([[和]]))。例如,下面代码返回一个长度为1的数值向量:

为了清晰起见,通过在列表对象名的后面附加一个$符号和值的名字来直接访问列表成分通常会更简单,例如:

与双方括号类似,它以简单数据类型返回列表成分(这里是长度为1的数值向量)。
通过名字来访问值的方式能保证检索正确的项,即使以后列表元素的顺序发生改变。
也可以通过指定一个名字的向量来获取列表中的多个列表项。下面返回subject1列表的一个子集,它包含temperature和flu_status成分:

整个数据集可以用列表和列表的列表来构建。例如,你可以考虑构建subject2和subject3列表,然后将它们组合为一个名为pt_data的单一列表对象。然而,以这种方式构建数据集是很常用的,所以R专门为这个任务提供了一种专用的数据结构(即数据框)。

2.1.4 数据框

到目前为止,机器学习中使用的最重要的R数据结构就是数据框。因为它既有行数据又有列数据,所以它是一个与电子表格或数据库相类似的结构。在R术语中,数据框定义为一个向量列表或者因子列表,每一列都有相同数量的值。因为数据框准确来说是一个向量类型的对象的列表,所以它结合了向量和列表两个方面的特点。
下面为前面用到的病人数据集构建一个数据框。这里我们使用前面创建的病人数据向量,data.frame()函数把它们组合成一个数据框:

你可能在上述代码中注意到一些新的东西。它加入了一个新的参数stringAsFactors= FALSE。如果不指定这个选项,R将自动把每个字符向量转化为因子。
这个特性有时候是有用的,但有时候又是不需要的。例如,这里,subject_name字段显然不是分类数据,因为姓名不是类别值。因此,只有在对项目有意义时,将stringsAsFactors选项设置为TRUE才能将字符转化成因子。
当我们显示pt_data数据框时,我们可以看到它的结构与先前使用的数据结构略有不同:

与一维向量、因子和列表相比,数据框是二维的,因此它显示为矩阵格式。在数据框中,病人的每个数据向量为一列,每个病人的数据是一行。用机器学习术语来讲,数据框的列代表特征或属性,行代表案例。
为了提取整列(即整个向量)数据,利用数据框就是向量列表这一事实。与列表相类似,提取一个单独元素最直接的方法是通过名字来引用它。例如,为了提取subject_name向量,输入如下命令:

与列表相类似,可以用名称向量从一个数据框中提取多列数据:

当我们通过这种方式访问数据框时,输出的结果还是一个数据框,它包含目标列所有行的数据。你也可以输入命令pt_data[2:3]来提取temperature和flu_status列。但是,通过名字访问列数据将产生清晰、容易维护的R代码,如果未来对数据框重新结构化代码也不会失效。
为了提取数据框中的值,我们可以用前面学过的访问向量中值的方法,但是有一个很重要的不同。因为数据框是二维的,所以它需要指定要提取数据的行和列。格式为[rows,colums],先指定行号,接着是一个逗号,再指定列号。和向量一样,行号和列号都是从1开始计数。
例如,为了提取病人数据框中第一行、第二列的值(John Doe的体温值),使用下面命令:

如果需要提取多于一行或者一列的数据,可以指定所需要数据的行号向量和列号向量。下面的语句将从第1、3行以及第2、4列中提取数据:

要提取所有行或者列,只要让行或者列的部分空白就行了。例如,提取第一列中所有行的数据:

提取第一行中所有列的数据,命令如下:

提取所有数据,命令如下:

前面学习的访问列表和向量中值的方法也可以用来提取数据框的行和列。例如,列数据除了能通过位置访问外,也能通过名称访问,并且负号也能用来排除特定行或者列的数据。因此,命令:

等价于:

为了熟练运用数据框,可以尝试用前面的病人数据来练习这些操作。或者,如果用你自己的数据集进行练习就更好了。这些操作类型对我们以后将学习的章节中的内容是很重要的。

2.1.5 矩阵和数组

除了数据框以外,R还提供了用于存储表格形式数据的专用数据结构。矩阵是一种表示行和列数据的二维表格数据结构。和向量类似,R矩阵能包含任何一种单一类型的数据,但是大多数情况下矩阵是用来做数学运算的,因此矩阵通常存储数值数据。
要想创建一个矩阵,仅需要向matrix()函数提供一个数据向量,紧跟着用一个参数指定行数(nrow)或者列数(ncol)。例如,要想创建一个2×2矩阵,用于存储1~4的数字,那么可以使用nrow参数要求将数据分为两行:

这与用ncol = 2产生的矩阵是等价的:

你将会注意到R先载入矩阵的第一列,然后载入第二列。这称为按列顺序,这是R载入矩阵的默认方法。
为了改变这种默认的设置,在创建矩阵时可以设置参数byrow = TRUE按照行载入矩阵。
为了进一步说明这个概念,观察当我们在矩阵中加入更多值以后会发生什么。
一共有6个值,要求2行将创建一个具有3列的矩阵:

类似地,要求2列将创建一个具有3行的矩阵:

与数据框一样,矩阵中的值也能用[rows,column]这样的方式来提取。例如,m[1, 1]
返回值1,m[3, 2]从矩阵m中提取值6。另外,也可以提取矩阵的整行或者整个列,例如:

与矩阵结构非常接近的是数组,它是一个多维数据表。矩阵含有值的行和列;一个数组包含值的行、列以及任意多层。尽管在后面的章节中我们偶尔会使用矩阵,但是数组的使用超出了本书的学习范围。

时间: 2024-10-03 09:16:23

《机器学习与R语言(原书第2版)》一 第2章 数据的管理和理解的相关文章

《机器学习与R语言(原书第2版)》一2.3 探索和理解数据

本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第2章,第2.3节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问"华章计算机"公众号查看. 2.3 探索和理解数据 在收集数据并把它们载入R数据结构以后,机器学习的下一个步骤是仔细检查数据.在这个步骤中,你将开始探索数据的特征和案例,并且找到数据的独特之处.你对数据的理解越深刻,你将会更好地让机器学习模型匹配你的学习问题. 理解数据探索的最好方法就是通过例子.在

《代码之殇》(原书第2版)——第3章 根除低下的效率 2006年7月1日

2006年7月1日:"停止写规范书,跟功能小组呆在一起" 我不是项目经理(Program Manager,PM),我也从来没有担任过项目经理,我将来也不可能成为一名项目经理.这并不是因为我个人对项目经理的抵触,其实,我的朋友之中不乏出色的项目经理.很显然,我没有权利去教导项目经理应该怎么去做他们的工作. 尽管如此,项目经理应该停止写规范书.就这么简单!他们在浪费我的时间,浪费组织的时间,浪费整个公司的时间.你几乎可以听到残留着的.细微的.嘎吱嘎吱的声音,因为规范书像白蚁一样在一口一口咬

《代码之殇》(原书第2版)——第3章根除低下的效率 2007年2月1日

2007年2月1日:"糟糕的规范书:该指责谁?" 规范书基本上都是可怕的.不仅仅指项目管理规范书,而且也包括开发规范书和测试规范书.我说的"可怕",主要是指难以撰写,难以使用,而且难以维护.你要知道,这很可怕!规范书往往还是不完善的,组织得很差,并且没有得到充分的复审.规范书永远都是这个样子,也看不到有任何变好的迹象. 为此,我想要指责项目经理,部分原因是因为我喜欢这么做,但更主要的还是因为他们是糟糕规范书的始作俑者.然而,事实不允许我指责项目经理.人人都在写糟糕的

《代码之殇》(原书第2版)——第2章 过程改进,没有灵丹妙药 2006年3月1日

2006年3月1日:"敏捷子弹" 我很难做出判断.也许你可以帮我.我不能断定以下两种观点,哪种更糟心:一种观点认为使用"敏捷"方法,并且恨不得微软在全公司范围内采用它,用它解决我们面临的所有麻烦:另一种观点认为敏捷是被一些无知的学者鼓吹出来的,它实际上是一种改头换面的愚昧方法,它让开发者不用承担任何责任.这是个两难的决定,两种观点都会使我有种作呕的感觉. 作者注:这是我最喜欢的栏目之一,因为其间爱恨交错不能自已.尽管它并不完美,但我在这个主题上的评论还是相当公允的.

ROS机器人程序设计(原书第2版)第1章 ROS Hydro系统入门

第1章 ROS Hydro系统入门 欢迎开始阅读本书第1章.本章将介绍如何安装ROS系统,它是一种新的标准化机器人系统软件框架.本书是基于ROS Fuerte的<ROS机器人程序设计>一书的升级版.通过ROS,你可以使用大量的示例代码和开源程序轻松地完成机器人编程和控制.同时,你还能够理解如何使用各种传感器与执行器,并为你的机器人增加新的功能,如自动导航和视觉感知等.得益于开源理念,以及持续开发最先进算法并不断提供新功能的开源社区,ROS不断进步完善. 通过本书,你将学习到如下内容: 在特定版

《代码之殇》(原书第2版)——第1章 项目管理失当,2008年9月1日

2008年9月1日:"我得估算一下" 尽管"你的任务估算是怎么产生的?"这样的疑问总是列在诸如"不要对你的项目经理或同事抱怨"的话题之首.但当我与刚出道的工程师们讨论问题时,首先的话题不是估算,而是职业发展和一些大众话题.这就是为什么问题总是在高谈阔论中变得无法控制.估算就是在预测未来,有太多的问题是未知而不可预见的,因而想为一个精神错乱的暴君提供一个精确的估算简直不可能.是不是?肯定是这样的,对吧? 错了.估算来自于软件工程师在规范的基础上对最

代码之殇》(原书第2版)——第1章 项目管理失当 2010年5月1日

2010年5月1日:"敏捷的团队合作" 我用Scrum已经7年了,而后面6年我一直写关于它的文章.Scrum的概念太吸引人了--规则多变.自我管理的团队在短而固定的周期内周而复始地进行一系列小环节(或功能)工作,并不断提升水平.很多微软团队的成功都来自于此.让人犯昏的是高层的项目经理与团队层的Scrum工程师仍存在严重隔阂. 很多高层及中层的项目经理认为Scrum是混乱的.随意的.危险的并毫无意义的,会使大家对计划失去信心:而很多Scrum迷认为项目计划是种浪费,会引起混乱,毫无价值,

ROS机器人程序设计(原书第2版)第3章 可视化和调试工具

第3章 可视化和调试工具 ROS附带了大量功能强大的工具,帮助用户和开发人员可视化和调试代码,以便检测并解决软硬件问题.其中包括消息日志系统(类似log4cxx).诊断消息.可视化以及检测工具.这些工具展示了哪些节点正在运行和它们是如何连接的.   本章我们还会展示如何用GDB调试器调试ROS节点,介绍用于日志记录的API,以及如何设置日志记录级别.接着,我们将解释如何用ROS工具集检测哪些进程正在运行以及它们之间通信的内容.例如,在下图所示的系统可视化图中可以看到正在运行的节点以及用连线表示的

《算法导论(原书第3版)》一本章注记

本章注记 关于算法的一般主题存在许多优秀的教科书,包括由以下作者编写的那些:Aho.Hopcroft和Ullman[5,6],Baase和Van Gelder[28],Brassard和Bratley[54],Dasgupta.Papadimitriou和Vazirani[82],Goodrich和Tamassia[148],Hofri[175],Horowitz.Sahni和Rajasekaran[181],Johnsonbaugh和Schaefer[193],Kingston[205],Kl