data.tableパッケージで大規模データをサクッと処理する

27
data.tableパッケージで ⼤規模データをサクッと処理する 2013年11⽉9⽇ 第35回Tokyo.R @sfchaos

description

 

Transcript of data.tableパッケージで大規模データをサクッと処理する

Page 1: data.tableパッケージで大規模データをサクッと処理する

data.tableパッケージで⼤規模データをサクッと処理する

2013年11⽉9⽇第35回Tokyo.R

@sfchaos

Page 2: data.tableパッケージで大規模データをサクッと処理する

1

⾃⼰紹介�TwitterID:@sfchaos

�お仕事:データマイニング

Page 3: data.tableパッケージで大規模データをサクッと処理する

2

1. イントロダクション

Page 4: data.tableパッケージで大規模データをサクッと処理する

3

データフレームは,Rの最重要なデータ構造の⼀つ

データフレームとは,Excelのワークシートのような

⾏列形式のデータ構造

Page 5: data.tableパッケージで大規模データをサクッと処理する

4

例えば,いつもよく出てくるirisデータセット

> head(iris) Sepal.Length Sepal.Width Petal.Length Petal.Width Species1 5.1 3.5 1.4 0.2 setosa2 4.9 3.0 1.4 0.2 setosa3 4.7 3.2 1.3 0.2 setosa4 4.6 3.1 1.5 0.2 setosa5 5.0 3.6 1.4 0.2 setosa6 5.4 3.9 1.7 0.4 setosa

アヤメの茎の⻑さ・幅と種類に関するデータ

Page 6: data.tableパッケージで大規模データをサクッと処理する

5

reshape2パッケージ,plyrパッケージなどを⽤いることにより,

ピボットテーブルなどの柔軟な処理も可能

Page 7: data.tableパッケージで大規模データをサクッと処理する

6

天下のExcel様もgkbrのデータフレーム!!

with data.frame

Page 8: data.tableパッケージで大規模データをサクッと処理する

7

そんなデータフレームも,結構処理が遅いことがある

⽶国の1990年の国勢調査データ

出典:US Census(1990) Data Sethttp://archive.ics.uci.edu/ml/datasets/US+Census+Data+%281990%29

> # データの読み込み> system.time(usc.df <-

read.csv("../data/USCensus1990.data.txt")) ユーザ システム 経過 65.588 3.152 68.868

Page 9: data.tableパッケージで大規模データをサクッと処理する

8

こんなとき,data.tableパッケージが役⽴つかもしれない

出典:http://cran.r-project.org/web/packages/data.table/index.html

> library(data.table)data.table 1.8.10 For help type: help("data.table")> system.time(usc.dt <-

fread("../data/USCensus1990.data.txt")) ユーザ システム 経過 3.244 0.040 3.300

Page 10: data.tableパッケージで大規模データをサクッと処理する

9

data.tableパッケージを⽤いることにより,以下のような処理を⾼速に実現

� データの読み込み� 条件に合致した要素の抽出� 層別の集計� テーブルのジョイン 等

Page 11: data.tableパッケージで大規模データをサクッと処理する

10

2. data.tableパッケージひとめぐり

Page 12: data.tableパッケージで大規模データをサクッと処理する

11

データ分析の流れ

データデータの

⼊⼒データ

加⼯・集計結果の出⼒ 結果マイニング

データの⽣成

外部からデータを読み込むケース

データを⽣成するケース

data.tableパッケージの守備範囲

Page 13: data.tableパッケージで大規模データをサクッと処理する

12

各⼯程の処理例とdata.tableの関数

⼯程 処理 通常のRの関数

データフレームからのデータ変換 --

複数のリストの結合

⾏の重複のチェック �duplicated

データの加⼯・集計グループ化の処理 �添字表記[[]], by引数

�rbindlstテーブルのジョイン �merge

キーの付加 �setkey --

data.tableの関数

�data.table

�duplicated

--�merge

�do.call("rbind", リスト)�do.call("cbind", リスト)

部分集合の取り出し �subset �subset

データの⼊⼒・変換 データの読み込み �fread �read.csv/read.table�scan 等

※data.tableパッケージについては, 他にも様々な関数がある

Page 14: data.tableパッケージで大規模データをサクッと処理する

13

データの⼊⼒� データ読み込み(fread関数を使⽤)> library(data.table)data.table 1.8.10 For help type: help("data.table")> system.time(usc.dt <-

fread("../data/USCensus1990.data.txt")) ユーザ システム 経過 3.244 0.040 3.300

Page 15: data.tableパッケージで大規模データをサクッと処理する

14

データの⼊⼒� ⽐較)データ読み込み(通常のread.csv関数)> # データの読み込み> system.time(usc.df <-

read.csv("../data/USCensus1990.data.txt")) ユーザ   システム  経過 65.588 3.152 68.868

fread関数を⽤いることで20倍以上の⾼速化

Page 16: data.tableパッケージで大規模データをサクッと処理する

15

データの⼊⼒� 読み込んだデータテーブルの確認(⾏頭・⾏末)> head(usc.dt) caseid dAge dAncstry1 dAncstry2 iAvail iCitizen iClass dDepart ...1: 10000 5 0 1 0 0 5 3 ... 2: 10001 6 1 1 0 0 7 5 ... 3: 10002 3 1 2 0 0 7 4 ... 4: 10003 4 1 2 0 0 1 3 ... 5: 10004 7 1 1 0 0 0 0 ... 6: 10005 1 1 2 0 0 0 0 ...> tail(usc.dt) caseid dAge dAncstry1 dAncstry2 iAvail iCitizen iClass dDepart ...1: 2468279 3 3 1 0 0 1 5 ...2: 2468280 7 1 2 0 0 0 0 ...3: 2468281 1 1 2 0 0 0 0 ...4: 2468282 3 3 1 0 0 1 2 ...5: 2468283 6 0 1 0 0 1 3 ...6: 2468284 2 3 1 0 4 0 0 ...

Page 17: data.tableパッケージで大規模データをサクッと処理する

16

データの⼊⼒� 読み込んだデータテーブルの確認(サイズ,表頭・表側)> dim(usc.dt)[1] 2458285 69> dimnames(usc.dt)[[1]]NULL

[[2]] [1] "caseid" "dAge" "dAncstry1" "dAncstry2" "iAvail" "iCitizen" [7] "iClass" "dDepart" "iDisabl1" "iDisabl2" "iEnglish" "iFeb55" [13] "iFertil" "dHispanic" "dHour89" "dHours" "iImmigr" "dIncome1" [19] "dIncome2" "dIncome3" "dIncome4" "dIncome5" "dIncome6" "dIncome7" [25] "dIncome8" "dIndustry" "iKorean" "iLang1" "iLooking" "iMarital" [31] "iMay75880" "iMeans" "iMilitary" "iMobility" "iMobillim" "dOccup" [37] "iOthrserv" "iPerscare" "dPOB" "dPoverty" "dPwgt1" "iRagechld"[43] "dRearning" "iRelat1" "iRelat2" "iRemplpar" "iRiders" "iRlabor" [49] "iRownchld" "dRpincome" "iRPOB" "iRrelchld" "iRspouse" "iRvetserv"[55] "iSchool" "iSept80" "iSex" "iSubfam1" "iSubfam2" "iTmpabsnt"[61] "dTravtime" "iVietnam" "dWeek89" "iWork89" "iWorklwk" "iWWII" [67] "iYearsch" "iYearwrk" "dYrsserv"

表側はつかない

Page 18: data.tableパッケージで大規模データをサクッと処理する

17

データの⼊⼒� メモリ上に⽣成されたデータテーブルのリストの確認

> tables() NAME NROW MB[1,] usc.dt 2,458,285 648 COLS [1,]

caseid,dAge,dAncstry1,dAncstry2,iAvail,iCitizen,iClass,dDepart,iDisabl1,iDisabl2

KEY[1,] Total: 648MB

オブジェクト名

⾏数

表側(の⼀部)

Page 19: data.tableパッケージで大規模データをサクッと処理する

18

データの変換� データフレームからデータテーブルへの変換(data.table関数)

> system.time(usc.dt <- data.table(usc.df)) ユーザ システム 経過 1.180 1.072 2.255

Page 20: data.tableパッケージで大規模データをサクッと処理する

19

データ加⼯・集計� キーの付加(setkey関数)> # キーの付加(dAge, dIncome1をキーにする)> setkeysetkeysetkeysetkey(usc.dt, dAge, dIncome1)> # オブジェクトのリストの中にもキーが表⽰されている> tables() NAME NROW MB[1,] usc.dt 2,458,285 648 COLS [1,]

caseid,dAge,dAncstry1,dAncstry2,iAvail,iCitizen,iClass,dDepart,iDisabl1,iDisabl2

KEY [1,] dAge,dIncome1Total: 648MB

キーが付加された

Page 21: data.tableパッケージで大規模データをサクッと処理する

20

データ加⼯・集計� バイナリサーチを⽤いた⾼速な要素抽出> # 2つのキーの値によりデータの要素へのアクセスが可能> system.time(x <- usc.dt[1, 1]) ユーザ システム 経過 0.000 0.000 0.001

> # ⽐較: 通常のデータフレームを⽤いた場合> system.time(y <- usc.df[usc.df$dAge==1 &

usc.df$dIncome1==1, ]) ユーザ システム 経過 1.536 0.096 1.637

dAge=1 かつdIncome1=1の

⾏の取得

Page 22: data.tableパッケージで大規模データをサクッと処理する

21

データ加⼯・集計� グループ化処理による集計> # キーの値ごとの層別集計> system.time(x <- usc.dt[, sum(dIncome1), by=dAge]) ユーザ システム 経過 0.032 0.000 0.033

> x dAge V11: 0 02: 1 03: 2 890434: 3 4620805: 4 6383236: 5 5255497: 6 4153738: 7 74411

第2引数には集計処理を,by引数には集計軸を指定

Page 23: data.tableパッケージで大規模データをサクッと処理する

22

データ加⼯・集計� グループ化処理による集計> > > > # ⽐較: 通常のデータフレームを⽤いた場合> system.time(y <- tapply(usc.df$dIncome1, usc.df$dAge,

sum)) ユーザ システム 経過 1.580 0.004 1.584> y 0 1 2 3 4 5 6 7 0 0 89043 462080 638323 525549 415373 74411

Page 24: data.tableパッケージで大規模データをサクッと処理する

23

その他の機能� テーブルの⾼速ジョイン(merge関数)

� テーブルの要素の抽出(subset関数)

� リファレンスによるオブジェクトの要素の値変更 等

Page 25: data.tableパッケージで大規模データをサクッと処理する

24

3. まとめ

Page 26: data.tableパッケージで大規模データをサクッと処理する

25

�データフレームは,とても便利なRのデータ構造だが,⼤規模データの読み込みや処理が遅いことがある.

�そんなときは,data.tableパッケージを⽤いて,データの読み込み,集計,検索などの⾼速化を検討すべし.

Page 27: data.tableパッケージで大規模データをサクッと処理する

26

� data.tableパッケージについては,R⾔語上級ハンドブックにより詳しい説明があります.