天天看點

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

任何機器學習項目初期的核心部分都是與管理和了解所收集的資料有關的。盡管你可能發現這些工作不像建立和部署模型那樣令人有成就感(建立和部署模型階段就開始看到了勞動的成果),但是忽視這些重要的準備工作是不明智的。

任何學習算法的好壞取決于輸入資料的好壞。在很多情況下,輸入資料是複雜的、淩亂的并且取自多種不同管道和格式。因為這些複雜性,是以投入機器學習項目中的很大一部分精力要花在資料準備和探索中。

本章從3個方面來讨論這些主題。第一節讨論r用來存儲資料的基本資料結構。學完這一節後,在你建立和管理資料集時,你就對這些資料結構非常熟悉了。第二節是實踐,這節讨論從r中輸入或者輸出資料的幾種常用函數。第三節通過探索一個真實世界資料集的例子來說明了解資料的方法。

學完本章後,你将了解:

基本的r資料結構以及如何使用它們來存儲和提取資料。

如何把常見來源格式的資料導入r。

了解并可視化複雜資料的典型方法。

因為r考慮資料的方式定義了你應該考慮資料的方式,是以在進入資料準備工作之前,了解基本的r資料結構是很有幫助的。然而,如果你已經對r的資料結構很熟悉了,你完全可以跳過這部分,直接學習資料預處理部分。

在程式語言中有多種形式的資料結構,在應用到特定的任務時,它們各有優勢和劣勢。因為r是一個在統計資料分析中廣泛運用的程式語言,是以r所用的資料結構的設計目的是使它易于處理這類工作。

在機器學習中經常使用的r資料結構是:向量、因子、清單、數組、矩陣和資料框。每種資料類型都針對一類具體的資料管理任務,是以知道它們如何與r項目互相互動是至關重要的。

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語言(原書第2版)》一 第2章 資料的管理和了解

因為r中的向量有固有的順序,是以其資料能通過計算向量中各個元素的序号來通路,序号是從1開始算起的,并且在向量名字的後面用方括号括起這個序号(例如,[和])。例如,為了獲得溫度向量中jane doe或者序号為2的病人的體溫,隻要簡單地輸入:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

為了從向量中提取資料,r提供了各種友善的方法。一個範圍内的值可以通過冒号(:)操作符獲得。例如,為了獲得jane doe 和steve graves 的體溫,輸入:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

通過指定一個負的序号可以把該項排除在輸出資料之外。要想排除jane doe的體溫資料,輸入:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

最後,可以通過一個邏輯向量來辨別每一項是否包含在内,有時候這也是很有用的。例如,需要包括前兩個溫度讀數,但是排除第三個,就可以輸入:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

正如你将看到的,向量是很多其他r資料結構的基礎。是以,了解不同類型的向量操作對在r中操作資料是很重要的。

下載下傳例子代碼

本書第2版新增加了一個下載下傳網站,你可以通過github網站:

如果你回憶第1章的内容,用類别值來代表特征的屬性稱為名義屬性。盡管可以用一個字元向量來存儲名義屬性資料,但r提供了一個資料結構專門來表示這種屬性資料。因子是向量的一個特例,它單獨用來辨別分類或者有序變量。在前面建構的醫學體檢資料集中,可以用一個因子來表示性别(gender),因為它有兩個類别:male和female。

為什麼不用字元向量呢?使用因子的一個優勢在于類别标簽隻存儲一次。例如,不存儲male、male、female,計算機隻要存儲1、1、2,這樣可以減少存儲同樣資訊所需要的記憶體容量。另外,許多機器學習算法用不同的方式來處理名義資料和數值資料。經常需要把變量編碼為因子,這樣r函數才能合理地處理分類資料。

因子不應該用來處理不是真正分類資料的字元向量。如果一個向量主要存儲類似名字或辨別字元串這樣的唯一值,那麼還是把它作為字元向量。

要把字元向量轉換成因子,隻需要應用factor()函數。例如:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

注意,當john doe和jane doe的性别資料顯示出來後,r輸出關于gender因子的額外的資訊。變量levles(水準)由factor(因子)可能取的類别值組成,在這個例子中是male或者female。

當建立因子時,可以增加沒有在資料中出現的其他水準。假設增加表示血型變量的另一個因子,如下所示:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

注意,當我們為3個病人定義blood(血型)因子時,我們用levels參數來說明一個額外的向量,該向量給出了4個可能的血型。是以,即使資料僅包含o型、ab型和a型,但所有的4種血型和輸出給出的blood因子存儲在一起。存儲額外的水準使得未來增加具有其他血型類型的資料成為可能。它也保證了盡管血型b沒有記錄在我們的資料中,但是當我們建立血型類型表時,我們知道類型b是存在的。

因子資料結構還允許包含關于名義變量類别的順序資訊,這給出了存儲有序資料的友善方式。例如,假設我們有病人symptoms(症狀)的資料,按照嚴重程度的水準升序排列:從mild(不嚴重)、moderate(中等)到severe(嚴重)。我們通過下述方式來呈現有序資料:以期望的順序給出因子的level(水準),從最低到最高的升序方式來列出有序資料,并設定ordered參數的值為ture。如下所示:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

由此産生的symptoms因子現在就包含了我們需要的順序資訊。與之前的因子不同,這個因子的水準值由<符号分隔,它表明了從不嚴重到嚴重的序列順序:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

有序因子的一個有用的特性是進行你期望的邏輯測試工作。例如,可以檢驗病人的症狀是否比moderate(中等)還嚴重。

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

能夠對有序資料模組化的機器學習算法将期望輸入資料為有序因子,是以確定對你的資料進行相應的編碼。

清單是一個與向量類似的資料結構,因為它用來存儲一個元素的有序集合。然而,向量要求所有元素都必須是同一種類型,清單允許收集不同類型的元素。由于這個靈活性,清單一直用于存儲不同類型的輸入和輸出資料,以及機器學習模型所使用配置的結構參數的集合。

例如,考慮我們建構的體檢病人的資料集,3個病人的資料存儲在6個向量中。如果我們要顯示關于john doe(對象1)所有的資料,我們需要輸入6條r指令:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解
《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

顯示一個病人的醫療資料看上去像是一個龐大的工程。清單結構使我們能夠把所有病人的資料放到一個我們能夠重複使用的對象中。

與使用c()建立一個向量類似,清單使用list()函數建立,如下面例子中所示。一個明顯的不同是,當清單建立以後,序列中的每一個成分幾乎都有一個名字。名字不是必需的,但是它使得接下來能夠通過名字通路清單中的值,而不是通過位置序号。為了給第一個病人的所有資料建立一個含有名字成分的清單,輸下面的代碼:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

現在病人的資料被收集到subject1清單中了。

注意,取值是由前面指令中指定的名字辨別的。然而,清單也能用類似通路向量的方法來通路。為了擷取temperature的值,采用下面的指令:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解
《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

在清單對象上應用向量風格的運算符得到的結果是另一個清單對象,它是原始清單的一個子集。例如,上面的代碼傳回具有唯一temperature成分的一個清單。為了以簡單資料類型傳回一個單一的清單項,在嘗試選取清單成分時應用雙方括号([[和]]))。例如,下面代碼傳回一個長度為1的數值向量:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

為了清晰起見,通過在清單對象名的後面附加一個$符号和值的名字來直接通路清單成分通常會更簡單,例如:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

與雙方括号類似,它以簡單資料類型傳回清單成分(這裡是長度為1的數值向量)。

通過名字來通路值的方式能保證檢索正确的項,即使以後清單元素的順序發生改變。

也可以通過指定一個名字的向量來擷取清單中的多個清單項。下面傳回subject1清單的一個子集,它包含temperature和flu_status成分:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

整個資料集可以用清單和清單的清單來建構。例如,你可以考慮建構subject2和subject3清單,然後将它們組合為一個名為pt_data的單一清單對象。然而,以這種方式建構資料集是很常用的,是以r專門為這個任務提供了一種專用的資料結構(即資料框)。

到目前為止,機器學習中使用的最重要的r資料結構就是資料框。因為它既有行資料又有列資料,是以它是一個與電子表格或資料庫相類似的結構。在r術語中,資料框定義為一個向量清單或者因子清單,每一列都有相同數量的值。因為資料框準确來說是一個向量類型的對象的清單,是以它結合了向量和清單兩個方面的特點。

下面為前面用到的病人資料集建構一個資料框。這裡我們使用前面建立的病人資料向量,data.frame()函數把它們組合成一個資料框:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

你可能在上述代碼中注意到一些新的東西。它加入了一個新的參數stringasfactors= false。如果不指定這個選項,r将自動把每個字元向量轉化為因子。

這個特性有時候是有用的,但有時候又是不需要的。例如,這裡,subject_name字段顯然不是分類資料,因為姓名不是類别值。是以,隻有在對項目有意義時,将stringsasfactors選項設定為true才能将字元轉化成因子。

當我們顯示pt_data資料框時,我們可以看到它的結構與先前使用的資料結構略有不同:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

與一維向量、因子和清單相比,資料框是二維的,是以它顯示為矩陣格式。在資料框中,病人的每個資料向量為一列,每個病人的資料是一行。用機器學習術語來講,資料框的列代表特征或屬性,行代表案例。

為了提取整列(即整個向量)資料,利用資料框就是向量清單這一事實。與清單相類似,提取一個單獨元素最直接的方法是通過名字來引用它。例如,為了提取subject_name向量,輸入如下指令:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

與清單相類似,可以用名稱向量從一個資料框中提取多列資料:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

當我們通過這種方式通路資料框時,輸出的結果還是一個資料框,它包含目标列所有行的資料。你也可以輸入指令pt_data[2:3]來提取temperature和flu_status列。但是,通過名字通路列資料将産生清晰、容易維護的r代碼,如果未來對資料框重新結構化代碼也不會失效。

為了提取資料框中的值,我們可以用前面學過的通路向量中值的方法,但是有一個很重要的不同。因為資料框是二維的,是以它需要指定要提取資料的行和列。格式為[rows,colums],先指定行号,接着是一個逗号,再指定列号。和向量一樣,行号和列号都是從1開始計數。

例如,為了提取病人資料框中第一行、第二列的值(john doe的體溫值),使用下面指令:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

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

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

要提取所有行或者列,隻要讓行或者列的部分空白就行了。例如,提取第一列中所有行的資料:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

提取第一行中所有列的資料,指令如下:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

提取所有資料,指令如下:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

前面學習的通路清單和向量中值的方法也可以用來提取資料框的行和列。例如,列資料除了能通過位置通路外,也能通過名稱通路,并且負号也能用來排除特定行或者列的資料。是以,指令:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

等價于:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

為了熟練運用資料框,可以嘗試用前面的病人資料來練習這些操作。或者,如果用你自己的資料集進行練習就更好了。這些操作類型對我們以後将學習的章節中的内容是很重要的。

除了資料框以外,r還提供了用于存儲表格形式資料的專用資料結構。矩陣是一種表示行和列資料的二維表格資料結構。和向量類似,r矩陣能包含任何一種單一類型的資料,但是大多數情況下矩陣是用來做數學運算的,是以矩陣通常存儲數值資料。

要想建立一個矩陣,僅需要向matrix()函數提供一個資料向量,緊跟着用一個參數指定行數(nrow)或者列數(ncol)。例如,要想建立一個2×2矩陣,用于存儲1~4的數字,那麼可以使用nrow參數要求将資料分為兩行:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

這與用ncol = 2産生的矩陣是等價的:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

你将會注意到r先載入矩陣的第一列,然後載入第二列。這稱為按列順序,這是r載入矩陣的預設方法。

為了改變這種預設的設定,在建立矩陣時可以設定參數byrow = true按照行載入矩陣。

為了進一步說明這個概念,觀察當我們在矩陣中加入更多值以後會發生什麼。

一共有6個值,要求2行将建立一個具有3列的矩陣:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

類似地,要求2列将建立一個具有3行的矩陣:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

與資料框一樣,矩陣中的值也能用[rows,column]這樣的方式來提取。例如,m[1, 1]

傳回值1,m[3, 2]從矩陣m中提取值6。另外,也可以提取矩陣的整行或者整個列,例如:

《機器學習與R語言(原書第2版)》一 第2章 資料的管理和了解

與矩陣結構非常接近的是數組,它是一個多元資料表。矩陣含有值的行和列;一個數組包含值的行、列以及任意多層。盡管在後面的章節中我們偶爾會使用矩陣,但是數組的使用超出了本書的學習範圍。

繼續閱讀