第四章 导入数据
数据具有不同的来源和格式。借助R软件的高扩展性能,Rattle提供了与各种格式数据源的接口。能与使用R软件实属幸运,因为R系统属开源系统,因而,可以非常方便地与其它应用进行协作通信。R语言支持多种数据格式的直接导入。
不同软件之间最常用的数据通信格式是逗号分隔文件(CSV)。这些文件的扩展名是.csv。这是一种面向行列的简单文本格式,其中各列以逗号隔开。这类文件可以用来在电子表格、数据库、气象观测站以及其它应用之间进行数据导入和导出。如果对列分隔符稍作改变,比如替换为制表符,就得到通常以txt为扩展名的文本文件。
这些简单的数据格式(csv和txt文件)未包括元数据信息。这意味着文件中对文件中所包含的数据的结构进行描述的信息。当其它软件读入此类数据时,需要对此进行假设。
其它类型的数据源提供了描述数据的信息,因而,我们的软件读入这类数据时不需要猜测其读入的内容。属性关联文件格式(4.2节)通常以.arff为扩展名,它在csv格式的基础上增加了元数据。
从数据库中直接提取的数据通常会提供元数据信息。开放数据库互联(ODBC)标准提供了一个从多种数据库中获取数据的开放式接口,而R软件对此提供了相应的支持。这允许我们与多种数据源包括Microsoft excel,microsoft access ,SQL server Oracle MySQL,Postgre以及SQLite进行直接通信。4.3节会介绍 RODBC。
没有必要在 Rattle 中提供在R中载入数据的所有功能。然而,我们可以用底层的R命令字载入数据,并在Rattle中进行检索,这部分内容详见4.4节。
R包本身也是提供了丰富的数据集。虽然许多数据集可能跟我们选定的主题无关,但我们可以借助他们来体验R中的数据挖掘过程。通过 rattle 界面的library 按钮或者 data 菜单下的 soource 可以查看到包含在当前库中的数据集列表。这部分内容详见 4.6节。
通过相关机制将数据载入rattle之后,我们需要定义数据集中各个变量的角色,同时,需要设定数据集中各条观测值在数据挖掘过程中的使用方式。这些信息会记录在rattle界面上,而rattle本身也提供了诸多有用的默认设置。
选定数据集,并执行 Data 菜单之后,将看到针对数据的文本性描述。 图4.1显示的是载入 weather.csv 文件之后的Rattle应用界面,weather.csv 是 rattle 包自带的一个样例数据集。打开R软件,载入 rattle包 ,启动 rattle 应用,再点击 Execute 按钮请求加载 weather 数据集即可得到上述结果:
library(rattle)
rattle()
图4.1 载入 weather.csv 数据集
本章将概述各种源数据格式并讨论如何导入它们以进行数据挖掘。此外,还将讨论 Rattle 提供的关于数据挖掘过程中如何使用数据的设定。
4.1 CSV 数据
最简单、最常用的一种数据交换格式是逗号分隔文件(CSV)格式。这种格式的文件已日渐成为在不同软件应用中交换数据的标准格式。其以 CSV 为扩展名,可以在电子表格、数据库包括 LibreOffice ,Calc ,Gnumeric,Microsoft Excel,SAS/Enterprise Miner,Teradata,Netezza 和其它软件应用中导入和导出。基于此,CSV 格式非常适宜用来向 rattle 中导入数据。这种数据文件的缺点是没有包含显式的元数据信息(元数据,又叫数据的数据,包括数据文件中的数据类型是数值型还是分类型等信息)。由于缺失元数据信息,R 软件有时候会搞错数据中某特定列的数据类型。不过,问题不大,在使用R载入数据时,我们可以帮助其识别数据类型信息。
数据定位和数据载入
通过Data菜单下的 Speadsheet 选项,可以直接导入 CSV 数据。点击 Filename 按钮(图4.2)会看到文件选择对话框(图4.3)。浏览到要载入的CSV文件,选中之后点击 Open 按钮。
图4.2 Data菜单的SpreadSheet选项,对文件名字进行了高亮。点击该按钮可以打开文件选择器
现在要做的是将数据载入到 rattle 中。通常,我们通过点击 Execute 按钮(也可以点F2)来完成这一过程。这一操作会将文件内容从硬盘读入到计算机的内存里,然后,可以作为 Rattle中的数据集来使用了。
Rattle提供来多个CSV格式的示例文件,其中包括weather.csv数据文件。在安装Rattle时,该文件已经同时安装。使用system.file()函数可以知道该文件的具体地址,在R控制台运行下面的命令:
system.file("csv", "weather.csv", package="rattle")
返回的地址信息取决于用户的操作系统以及R的安装方式。上面得到的地址是一个标准安装的Ubuntu GNU/Linux 系统的相对位置。
提示:在Rattle中点击两下鼠标(Execute和Yes)即可再次载入该文件。接着,点击Filename按钮(显示为weather.csv)一个文本浏览器,此时窗口的顶部显示的是文件地址。
我们可以用file.show()函数查看文件内容。这一操作会弹出一个显示文件内容的窗口:
fn <- system.file("csv", "weather.csv", package="rattle")
file.show(fn)
撇开R和Rattle,我们可以用随便一个文本编辑器直接查看文件内容。对于不熟悉CSV类型文件的用户来说,这非常有用。我们可以看到文件的头部内容如下所示:
Date,Location,MinTemp,MaxTemp,Rainfall,Evaporation...
2007-11-01,Canberra,8,24.3,0,3.4,6.3,NW,30,SW,NW...
2007-11-02,Canberra,14,26.9,3.6,4.4,9.7,ENE,39,E,W...
2007-11-03,Canberra,13.7,23.4,3.6,5.8,3.3,NW,85,N,NNE...
图4.3CSV文件选择器只显示文件夹中扩展名为.csv的文件。通过选择右小角下拉式菜单,我们可以只显示扩展名为.txt(以制表符作为分隔符的文件常以此为扩展名)或者其他任意扩展名的文件。
CSV文件通常是一个在标题行列出所有变量名字,并以逗号作为分隔符的普通文本文件。可推想得知标题行后面的部分是按行排列的观测值记录。每条观测值内部以逗号作为分隔符,也即每个变量对应的观测值都以逗号进行分隔。
可以使用read.csv()函数将CSV文件载入到Rattle中。查看Log菜单中的内容可以了解操作过程。从Log菜单,我们可以看到下面的内容:
crs$dataset <- read.csv("file:.../weather.csv",na.strings=c(".", "NA", "", "?"),strip.white=TRUE)
为了简化输出结果,这里省略来weather.csv文件对应的完整路径的部分内容。因而,复制黏贴来运行上述命令将会报错。一个替代做法是将Log菜单中对应的命令行复制到R控制台。
上述函数的执行结果是数据集本身被载入到内存中,并可以用crs$dataset对其加以引用。
函数的第二个参数(na.strings=)列出了四个字符串,如果变量的取值为其中之一,则其将被转化为R中的缺失值(NA)。里出的四个字符串涵盖了大多数用来表示缺失值的符号。比如,SAS用点(.)来表示缺失值,而R用特殊字符串“NA”来表示缺失值。其它软件以更简单的空字符表示缺失值,还有一些(包括机器学习软件C4.5)使用问号(“?”)表示缺失值。
我们也可能用到strip.white=参数,将该参数设定为TRUE,将删除文件中的空白(比如,空格和制表符等)。这会使源CSV文件的逗号对齐,从而便于人眼查看,同时能较好地支持缺失值。
使用read.csv()函数时不需要如此复杂。如果要将一个CSV文件载入R中(请用文件的实际路径替换代码中的…),运行下面的命令即可:
ds <- read.csv(".../weather.csv")
也可以直接从互联网上载入数据。例如,可以从togaware.com上读取weather数据集:
ds <- read.csv("http://rattle.togaware.com/weather.csv")
第2章中讲道,如果未通过Filename按钮指定其它数据文件,则Rattle会自动加载包中提供的是示例数据文件(weather.csv)。这是最简单的一种导入数据到Rattle中的方法,其对学习Rattle界面大有帮助。
选定要载入的文件之后,务必记得点击Excute按钮,这样才能真正将数据载入到Rattle。接下来,Data菜单的主文本面板会发生变化,列出所有的变量、对应的类型、其在建模过程中的角色以及其他有用信息,如图4.1所示。
将数据从文件导入到Rattle之后,会创建一个数据集,接下来我们就可以探索数据了。第2章曾讲到,我们可以在控制台中查看文件头部的内容。下面我们只显示数据集的前五个变量以及前六个观测值:
head(crs$dataset[1:5], 6)
Date Location MinTemp MaxTemp Rainfall
1 2007-11-01 Canberra 8.0 24.3 0.0
2 2007-11-02 Canberra 14.0 26.9 3.6
3 2007-11-03 Canberra 13.7 23.4 3.6
4 2007-11-04 Canberra 13.3 15.5 39.8
5 2007-11-05 Canberra 7.6 16.1 2.8
6 2007-11-06 Canberra 6.2 16.9 0.0
前文提及(2.9节),Rattle会将数据集保存在名为crs的环境里面,因此,在R中,我们可以直接用crs$dataset来引用该数据集。
在Rattle界面下,一旦载入数据集,就可以点击View按钮,以电子表格的形式来查看数据集。这一过程是通过调用RGtk2Extras包(Taverner等,2010)中的dfedit()函数来完成的。
数据格式微调
Rattle界面提供了很多调整读入CSV文件方式的选项。如图4.2所示,其中包括Separator和Header。
我们可以通过Separator的输入来选择字段分隔符。默认的分隔符是逗号。载入TXT文件时,由于其以制表符作为字段分隔符,因而,我们需要用表示制表符的专用码“\t”(在t前面加两个斜杠)来替换逗号。我们也可以令输入为空,此时,任意空白(比如,任意数量的空格或者制表符)将会视为分隔符。
从read.csv()函数的使用角度来说,输入分隔符的作用相当于在函数中包含适当的参数(使用sep=)。举个例子,比如,有一个以制表符作为分隔符的文件,名为“mydata.txt”,我们可以在函数中应用sep=:
ds <- read.csv("mydata.txt",sep="\t")
提示:注意直接在R中指定制表符作为分隔符时使用的是一个斜杠,而不是像Rattle界面中的两个斜杠。
另外一个在载入数据时十分有用的选项是Header复选框。通常,CSV文件会将第一行作为列名。这些名字将被R和Rattle认为是变量名。然而,并非所有的CSV文件都包括标题。对于这样的文件,不要勾选Header复选框。载入不包含标题的CSV文件时,R会自动生成一些列名。复选框会将输入转化为read.csv()函数中的header=参数。将header=设定为FALSE,则文件的第一行会被视为数据而不是标题行。假设我们有一个叫“mydata.csv”的文件,读入该文件的read.csv()命令是:
ds <- read.csv("mydata.csv",header=FALSE)
提示:数据中的每一行可以包含不同的列数,每一行的缺失列会从后面以NA补足。这是通过read.csv()函数中的fill=参数来完成的,该参数的默认值是TRUE。
基础数据描述
数据集载入Rattle之后,我们就可以将从上面的基础描述中感知到数据的特征。例如,在图4.1中,第一个变量Datebei 视为每个观测值的序号。该变量共有366个不同的取值,这与观测值数目相同。
数据集中所有观测值对应的Location变量只有一个取值。因此,其被视为常数,且不参与建模过程。也即该变量会在建模过程中被忽略。
图4.1看到,接下来的5个变量被标记为数值型变量,接着是分类变量WindGustDir等等。Commnent列标示的是所有取值的数目以及每个变量对应的缺失值的数目。比如说,Sunshine变量共有114个不同的取值和3个缺失值。本书第7章将讨论缺失值的处理问题。
4.2 ARFF数据
属性关系文件格式是一种由CSV文件以及文件顶部的数行元数据组成的一种文本文件格式。ARFF格式的文件最初是为机器学习软件Weka(Witten和Frank,2005)设计的,有很多数据都发布为这种格式。在Rattle中,我们可以通过ARFF选项(图 4.4)载入ARFF格式的数据,需要指定包含数据的文件名。
Rattle包提供了ARFF的文件的示例。载入ARFF之前,先启动Rattle并加载weather数据之后(2.4节),选择ARFF选项并点击Filename选择器,范围上一级目录,进入arff文件夹,选择要加载的数据。
图4.4 选择ARFF单选按钮加载ARFF文件
CSV文件和ARFF文件最大的区别在于是否有文件头部的数据描述区。数据描述区包含了数据集中每个变量的信息。weather数据集对应的ARFF格式的文件如下所示。注意,在ARFF格式的文件中,变量被视为属性。
@relation weather
@attribute Date date
@attribute Location {Adelaide, Albany, ...}
@attribute MinTemp numeric
@attribute MaxTemp numeric
...
@attribute RainTomrrow {No, Yes}
@data
2010-11-01,Canberra,8,24.3,0,...,Yes
2010-11-02,Canberra,14,26.9,3.6,...,Yes
2010-11-03,Canberra,?,23.4,3.6,...,Yes
...
数据描述区相当简单明了。以数据集的名字(用ARFF的术语,则是关系的名字)开头。接下来是描述每个观测值的变量名以及变量对应的数据类型。每一行对应一个变量定义(上例中省略了部分内容)。数值型变量被识别为数值型、实数型或者整形变量。对于分类数据,则列出了所有可能取值。另外两个能被ARFF识别的数据类型是字符串和日期。字符串类型的变量意味着其可以将字符串(或者文本序列)作为取值。而data数据类型可以指定日期的记录格式。默认格式遵循ISO-8601标准,型如"yyyy-MM-dd"‘T’HH:mm:ss"。
数据描述区下面是按行列示的具体观测值,以逗号作为分隔符,与CSV文件类似。
ARFF文件优于CSV数据文件的地方在于源数据信息。这一点对Rattle尤其有用,因为Rattle中分类数据的可能取值是由读入CSV文件时的数据决定的,所以,所有没有出现在数据中的分类变量的可能取值自然都丢掉了。当从ARFF文件中读入数据时,元数据会列出分类变量的所有可能取值,即使该取值在真是数据中并未出现。在第12章,探讨构建和部署随机森林模型时会专门讲到这个专题。
ARFF文件可以包括注释,注释行通常以“%”开头。包含的注释行能记录更多数据的额外信息,包括数据是如何得来的,来源是哪里以及如何引用数据等。
ARFF文件中的缺失值以记录为“?”。这可以被R中的read.arff()函数识别出来,我们将其视为跟Rattle中的NA相同。
综上,ARFF格式的文件,除了简单之外,与CSV相比有诸多优势。不过,CSV依旧是最常用的数据文件格式。
4.3 ODBC源数据
许多数据被存储在数据库或者数据仓库里。开源数据库连接标准(ODBC)被界定为访问数据库(也包括数据仓库)中数据的常用方法。其以查询关系型数据的结构性查询语言(SQL)为基础。下面讨论如何直接访问这些数据库中的数据。使用Rattle的ODBC选项(如图4.5),Rattle可以借助ODBC直接获取任意数据库的数据集。在GUI的底层,实际上是RODBC(Ripley和Lapsley,2010)提供了R与ODBC数据源的接口。
图4.5 通过ODBC数据库连接载入数据
通过ODBC访问数据的关键在于通过数据源名字(或者DSN)来识别数据源,不同的系统提供了不同的设定DSNs的机制。例如,在GNU/Linux操作系统下,使用unixodbc应用,系统的DSNs通常定义在/etc/odbcinst.ini和/etc/odbc.ini中。在微软Windows下面,控制面板提供了管理ODBC数据源的工具。
在Rattle中,我们通过在DNS文本输入框中输入名字来设置DSN(图4.5)。一般DSN指定之后,Rattle就尝试去建立连接。许多ODBC驱动在建立连接之前会要求输入用户名和密码。图4.6演示来输入类似信息的弹窗,这个例子中连接的数据仓库是Netezza。
在R中运行RODBC中的dobcConnect()函数可以直接建立连接。该函数建立了一个连接远程数据源的通道:
library(RODBC)
channel <- odbcConnect("myDWH", uid="kayon", pwd="toga")
与数据源建立连接之后,Rattle会自动查询数据库中的表名,并通过如图4.5中的下拉列表Table来访问查询得到的表。我们需要选择要加载的表。
R中为数不多的对ODBC连接进行微调的选项可以被Rattle调用。其中一个选项允许我们对从选中表中检索得到的行数进行限定。如果将行数限制设定为0,则检索会返回整个表。不方便的地方在于没有标准的SQL标准来对查询返回的行数进行限定。一些数据库系统(比如,Teradata和Netezza)的SQL关键字是LIMIT,Rattle借用来这一关键字。
RODBC提供了一系列可与数据库进行交互的R函数。例如,sqlTables()函数可以返回所有可用表的名字。我们为其传递一个前面创建的通道来与数据库进行通信:
tables <- sqlTables(channel)
如果查询连接的数据库中有个表叫clients,我们可用sqlColumns()函数得到该表的列名字段。
columns <- sqlColumns(channel, "clients")
有时,我们只想从数据库中加载某个特定的子集。这时,可直接通过SQL查询语句检索出想要的数据。例如:
query <- "SELECT * FROM clients WHERE cost > 2500"
myds <- sqlQuery(channel, query)
直接使用R为精确识别要加载的数据提供了更多的操作空间。我们可以用任意的SQL查询来替代前面的SELECT语句。对于熟悉SQL查询的来说,这提供了一个强大的机制使我们能够在数据载入之前对数据进行重新定义。
像上文这样,通过向通道直接发送SQL查询载入数据时,得到的数据将被保存为R中的数据集,我们可以用myds(根据前文定义)引用该数据集。通过Rattle中的R Dataset选项可以访问该数据集,下节将对此进行介绍。
4.4 R数据集——其他数据源
R可以以多种方式从多种数据源载入数据。前面已经介绍过从数据文件(CSV或者TXT文件)或者数据库直接载入数据的内容。然而,R还提供了更多从多种数据源导入数据的选项。
任何已经载入R中的数据集(技术上而言,是任意数据框)都可以作为Rattle进行数据挖掘的对象。选定Data菜单的R Dataset选项之后(图4.7),Data Name下拉菜单中会列出所有能被载入Rattle作为数据集的数据框名。
借助foreign包(DebRoy和Bivand,2011),可以直接将SPSS格式数据集(read.spss)、SAS XPORT格式数据集(read.xport())和DBF数据库文件(read.dbf())。要指出的是,SAS专属数据格式作为例外不能直接载入到R中,除非我们有SAS的许可,允许读入数据才行。
载入 SPSS 格式的数据集
举个例子,假设我们有一个从SPSS保存或者导出的数据文件。我们可以运行read.spss()函数导入数据:
library(foreign)
mydataset <- read.spss("file=mydataset.sav")
然后,如图4.7所示,我们看到数据框名mydataset,已经作为可用数据集出现在了R Dataset的下拉列表中。
图4.7 载入一个定义好的数据框作为Rattle可用的数据集
必须将供Rattle使用的数据集加载或者创建到运行Rattle的R会话(即我们加载了rattle包的那个R控制台)中才行。
从剪贴板读入数据
图4.8 选中电子表格的部分区域并复制到剪贴板
一个有时用起来很方便的有趣做法是,R可以通过系统剪贴板对数据进行复制和剪贴。通过这一机制,我们可以把数据从电子表格复制(跟通常的复制黏贴类似)到剪贴板上。然后,在R中,使用read.table()函数将数据“黏贴”到一个数据集中。
假设我们打开了一个如图4.8所示的电子表格。按常规做法,选取16行数据,包括表头,运行下述命令可将数据载入到R里:
expenses <- read.table(file("clipboard"),header=TRUE)
接下来,就可以在Rattle中使用expenses数据框了。
日期转换
默认情况下,上例中的Date变量在加载时被视为分类变量。在将其载入Rattle时,运行下面的命令,可以将其转化为日期类型,如图4.9所示:
expenses$Date <- as.Date(expenses$Date,
format="%d-%b-%Y")
head(expenses)
Date Expense Total
1 2005-11-17 19.5 19.5
2 2005-11-23 -15.0 4.5
3 2005-12-10 30.0 34.5
4 2006-01-23 -110.0 -75.5
5 2006-01-28 -20.0 -95.5
6 2006-02-14 -10.0 -105.5
图4.9 通过剪贴板的复制、黏贴操作从电子表格中载入数据框
直接从万维网读取数据
当今的很多数据都以万维网上的HTML格式提供。XML包(Lang,2011)提供了一系列直接从网上向R中导入数据的函数,然后,我们即可用Rattle(当然,也可以用R)对这些数据进行分析来。例如,我们读取谷歌列出的访问次数最多的网站列表数据,将其转化为数据框,以供Rattle使用。我们首先要载入XML包,并设定一些相关路径:
library(XML)
google <- "http://www.google.com/"
path <- "adplanner/static/top1000/"
top1000urls <- paste(google, path, sep="")
接下来可以用readHTMLTable()函数来读入数据,并提取相关表格、设定表格列名:
tables <- readHTMLTable(top1000urls)
top1000 <- tables[[2]]
colnames(top1000) <- c('Rank', 'Site', 'Category',
'Users', 'Reach', 'Views',
'Advertising')
运行head()函数可以查看表格上的前几行数据:
head(top1000)
Rank Site Category
1 1 facebook.com Social Networks
2 2 youtube.com Online Video
3 3 yahoo.com Web Portals
4 4 live.com Search Engines
5 5 wikipedia.org Dictionaries & Encyclopedias
6 6 msn.com Web Portals
Users Reach Views Advertising
1 880,000,000 47.2% 910,000,000,000 Yes
2 800,000,000 42.7% 100,000,000,000 Yes
3 660,000,000 35.3% 77,000,000,000 Yes
4 550,000,000 29.3% 36,000,000,000 Yes
5 490,000,000 26.2% 7,000,000,000 No
6 450,000,000 24% 15,000,000,000 Yes
4.5 R数据
通过RData File选项(如图4.10),可以直接从本地的二进制R数据文件(扩展名通常是RData)中载入数据。这类文件通常包括多个数据集(以压缩格式保存),且常常是从先前的R会话中保存得到(使用save()函数)。
载入RData之前要先识别包含数据的文件。数据文件识别完成,数据集即被载入,然后,我们需要选择其中一个可用数据框作为Rattle中的数据集载入。这一步是通过Data Name下拉列表来指定,完成后点击Execute按钮即可在Rattle调用相应的数据集了。
图4.10 从二进制R文件中载入数据集
图4.10演示了选择RData文件的过程。图中可见,该文件的名字是cardiac.RData。数据文件识别完成后,Rattle会在Data Name下拉列表中列示文件中查询到的所有可用的数据框名。我们可以从数据文件中选择risk数据集载入Rattle。
4.6 库
几乎所有的R包都附带有帮助演示函数功能的示例数据集。我们已经看到Rattle包含数据集包括weather,weatherAUS和audit数据集。我们可以探索那些已经安装在R库中的R包的数据集。
Data菜单的Library允许我们调用这为数众多的示例数据集。点击单选框将看到一个所有可用数据集的列表,可以通过Data name下拉列表对其进行访问。下拉列表中包含了数据集名字、对应的包以及针对数据集的简要描述。注意,这个下拉列表可能很长,具体长度取决于已安装的R包的个数。我们看个例子,演示下Rattle用来生成上述列表的R代码:
da <- data(package=.packages(all.available=TRUE))
sort(paste(da$results[, "Item"], " : ",da$results[, "Package"], " : ",da$results[, "Title"], sep=""))
...
[10] "Adult : arules : Adult Data Set"
...
[12] "Affairs : AER : Fair's Extramarital Affairs Data"
...
[14] "Aids2 : MASS : Australian AIDS Survival Data"
...
[19] "airmay : robustbase : Air Quality Data"
...
[23] "ais : DAAG : Australian athletes data set"
...
[66] "audit : rattle : Sample dataset for data mining"
...
[74] "Baseball : vcd : Baseball Data"
...
[1082] "weather : rattle : Sample dataset for ..."
...
在访问特定包的数据集之前,必须先用library()函数载入该包(Rattle里面会自动载入)。对于大多数R包(尤其是声明数据集延迟加载的R包,延迟加载意味着被引用时即被加载)而言,只需在R控制台键入相应的数据集名字即可调用数据。否则的话,访问数据之前要先用运行data()函数才行。我们需要为data()函数输入要加载的数据集名字。Rattle会自动处理这一过程,它会选择合适的操作来保证数据集可被访问。
4.7 数据选项
前文提及的Rattle中所有载入数据的选项,在载入数据集之后,会共享一系列选项。这些附加选项跟数据抽样以及分派变量的角色有关。下面从数据挖掘角度对此予以介绍。
数据分割
2.7节提及,Partition选项允许我们将数据集分割为训练集、交叉验证集和测试集。3.1节进一步定义了数据分割的概念。这些概念面向的是预测性数据挖掘。一般来说,我们会基于训练集来构建模型。
可用对评估数据集应用模型来评估模型的优劣(第15章)。构建模式时,没有用到评估数据集,因此评估数据集可以对模型针对新观测时的优劣提供一个大致的估计。基于评估结果,我们可以对模型参数进行调试以寻求改进模型性能。
一旦模型结果令人满意,或者从交叉数据集的评估结果来看效果良好的话,就可以用第三部分数据即测试集来对模型进行评估了。由于在此之前,模型从未用到测试集中的观测值。因此,测试集得出的模型性能可以较好的预示,一旦能够得到新的观测值,该模型针对新观测值时的表现。
数据分割和抽样的概念,不仅仅是一种针对预测性数据挖掘来分割数据的机制。统计学家将抽样拓展为一种基于小数据集进行分析,从而推断出有关总体结论的学问。统计领域有众多知识,来保证我们对围绕着数据分析所得结论的不确定性的正确认知。这种认识十分重要,但数据挖掘过程中并为突出这一点。
Rattle使用sample()函数来生成随机分割或者抽样。随机样本通常能以较大的几率来反应总体的分布。因此,将大数据集抽样为小数据集之后,再用第5章中的方法来探索数据会更容易。探索10000个观测值比探索1000000个观测时更具交互性和实用性。抽样的其他优点还包括可以对不同的样本进行分析和绘图,以测量结果的稳定性和统计精确度。模型构建,尤其是随机森林模型的构建(第12章),将受益于此。
当数据挖掘的可得数据量较为庞大,构建模型将耗费大量时间(数小时甚至数日)时,这种抽样方法也非常必要。将数据集抽样为较小的数据集,能让我们在构建模型时具有更多的互动可能。一旦从最初的互动建模中找出清洗数据和转换数据的方法,就可以着手实验模型了。得到基础模型参数后,就需要对更大规模的数据进行清洗、转换和建模。在模型计算的数小时里,我们可以暂停监督了。
抽样的缺点,尤其是数据挖掘过程中的抽样缺点在于小概率事件可能没有包含在抽出的样本里。稀有疾病的案例,在大量的电子资金转账过程中形成的少数坏账,也有可能缺失,但它们却是我们在数据挖掘过程中感兴趣的项目。这种问题称之为类平衡问题。
默认情况下,Rattle提供的随机分割会将数据集的70%作为训练集,15%作为交叉验证集,15%作为测试集(图4.11)。我们可以根据需要对该比例进行调整。对大数据进行一些探索性分析时会用到抽样。使用计算量比较大的模型(比如,支持向量机)对数据建模时也会用到抽样。
图4.11 对weather数据集进行抽样
抽样还是会用到随机数。任何随机数在生成之前都需要设定随机种子。使用相同的随机种子,将得到相同的随机数,从而使相关过程可重复。通过修改随机种子,可以选择不同的随机数,当我们需要测试模型对不同抽样数据的敏感度时这会非常有用。
Rattle中常用一个默认的随机种子,这使得建模过程可重复。该随机种子将传递给R中的set.seed()函数,并称为生成下一个随机数序列的种子。因此,如果每次都将随机种子设定为同一个数字,就能保证我们得到相同的随机数。
当情形相反时,我们会想在建模过程中将随机种子设定为不同的数字,并依此评估每个模型的表现。我们针对原数据集的不同随机抽样构建模型。如果不同模型显著不相同的话,我们就需要斟酌我们建模方法的稳健性了。我们将在第15章进一步讨论此内容。
变量在模型中的角色
构建模型时,每个变量都将扮演特定的角色。大多数变量会作为模型的输入,而其中一个变量将作为建模的目标变量。有些变量也会作为风险变因(risk variable)。风险变因在建模过程中不会用到。通常用来记录与风险或者输出相关的重要性程度。例如,在audit数据集中,记录的是以美元计价的会计调整值。衡量的是与该案例相关的风险大小。在weather数据集中,风险变因是第二天的降雨量——降雨量可视为风险的大小。15.4节有一个在Rattle中使用风险变量的例子,针对的是模型评估过程。
最后,也可以将一些变量标记为建模时候的可忽略变量。
在向Rattle载入数据时,我们需要确保每个变量在建模过程中扮演合适的角色。大部分变量的默认角色是输入变量。通俗来说,这些变量是用来预测目标变量的变量。
目标变量,如果数据集中有相关的目标变量的话,通常是预测性建模过程中令我们感兴趣的变量。也即,它是记录历史数据输出结果的变量。在weather数据集中,目标变量是RainTomrrow,数据集audit的目标变量时Adjusted。
Rattle使用简单的经验法则来确定一个变量是否作为目标变量。基本的经验法则是:取值较少(低于5个)的变量会被视为候选目标变量。因为很多公开数据集的最后一个变量通常是目标变量,因而,数据集的最后一个变量常常被视为候选目标变量。如果最后一个变量的取值大于5,Rattle将从第一个变量开始,顺序查找到取值低于5的变量,前提是存在这样的变量。只有标记一个变量为目标变量。
同时,只有一个取值的整数变量常被自动视为标记变量(Ident)。可以标记任意数量的变量作为标记变量。所有的标记变量在建模过程中都会被忽略。但在对数据集进行排序时会用到,当结果被输出到排序文件中时,可以通过标记变量识别观测值。
在针对特定任务建模时,并非所有变量都会被用到。可以用单选按钮Ignore来忽略这些变量。
向Rattle载入数据时,特定的特殊字符串会用来识别变量角色。例如,名字以ID开头的变量会被自动标记为标记变量。用户可以对此进行调整。
与此类似,名义以IGNOGE开头的变量将设定为忽略变量。RISK和TARGET的情形也与此类似。
无论何时,目标变量都被视为分类变量或者数值型变量。如果以数值型变量作为分类变量,当该变量取值小于10时,Rattle会自动将其视为分类变量(默认)。结合建模目的,这意味着只能对其构建分类模型。通过选择Data菜单下的Numeric按钮可以对该经验设置进行调整,从而能够对其构建回归类预测模型。
权重计算和角色
最后一个与Data菜单相关的确认选项是Weight Calculator和与之相关的Weight角色。一个变量可以用来表示与每个观测值相关的权重。Weight Calculator允许我们提供一个科包含多个变量以及标准化的公式来计算每个观测值的权重。以audit数据集为例,我们可使用一个包含调整金额的公式,这一公式将给具有较大调整金额的观测值以较大的权重。
4.8 命令汇总
本章用到的R包,命令,函数和数据集如下:
——–|———|——— 对象 | 包 | 对象描述 audit | 数据集 | rattle包示例数据 clients | 数据集 | 伪数据集 data() | 命令 | R载入数据 dfedit() | 命令 | 在电子表格中编辑数据框 file.show() | 命令 | 显示数据框 foreign | 包 | 多种数据格式的接口 library() | 命令 | 将包载入到R会话中 file.show() | 命令 | 显示文件夹内容 odbcConnect() | 函数| 连接数据库 paste() | 函数 | 合并字符串 rattle | 包 | 提供示例数据 read.arff() | 函数 | 读入ARFF类型的数据文件 read.csv() | 函数 | 读入逗号分隔符类型的数据文件 read.dbf() | 函数 | 从DBF数据库中读入数据 read.delim() | 函数 | 读入制表符分割型的数据文件 read.spss() | 函数| 读入SPSS相关的数据文件 read.table() | 函数 | 读入文本型数据文件 read.xport() | 函数 | 读入SAS导出的数据文件 readHTMLTable() | 函数 | 从万维网读取数据 risk | 数据集 | 伪数据集 RODBC | 包 | 提供数据库接口 sample() | 函数 | 对数据集进行抽样 save() | 命令 | 将R对象保存为二进制文件 set.seed() | 命令 | 重设生成随机数序列的种子 skel | 数据集 | archetypes包中附带的数据集 sqlColumns() | 函数 | 列示数据库表的列字段 sqlTables() | 函数 | 列出数据集中的表 system.file() | 函数 | 返回R安装路径或者包的路径 weather | 数据集 | rattle包中的数据集 XML| 包 | 读取或者生成XML或者HTML文件