Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

RのffでGLMしてみたけど...

10,429 views

Published on

第26回東京R勉強会の発表資料です

Published in: Education
  • Download The Complete Lean Belly Breakthrough Program with Special Discount. ●●● http://ishbv.com/bkfitness3/pdf
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

RのffでGLMしてみたけど...

  1. 1. あの素晴らしいffをもう一度 ~ffでGLM編~ 2012/09/08 Tokyo.R#26 和田 計也サイバー系
  2. 2. サイバー系 はじめに ※この発表は個人の 見解であり、所属す る組織の公式見解で はありません。2012/9/8 1
  3. 3. サイバー系 自己紹介  和田 計也(@wdkz)  静岡県袋井市出身  サイバー系企業でデータマイニングエンジニア職  前職はバイオベンチャー  バイオマーカ探索してた  学生時代は枯草菌の研究2012/9/8 2
  4. 4. サイバー系 皆様は今までに食べたパンの枚数を覚えているだろうか?  昨年の「部屋とYシャツと私」の大惨事を...  今回はもう一度ffライブラリについて紹介し、皆様にその 魅力をお伝えしたいと思います。2012/9/8 3
  5. 5. サイバー系 えっ、またff !?2012/9/8 4
  6. 6. サイバー系 今日のお話 1. ffについて 2. ffでGLM 3. 実践2012/9/8 5
  7. 7. サイバー系 今日のお話 1. ffについて 2. ffでGLM 3. 実践2012/9/8 6
  8. 8. サイバー系 改めてffとは?  Rのlibraryです memory-efficient storage of large data on disk and fast access functions  CRANにあります http://cran.r-project.org/web/packages/ff/index.html  Rの欠点(データは全てオンメモリ)をカヴァーできる  動作原理  必要なデータだけを都度メモリ上にもってくる  それ以外はディスク上に置いておく Rのオブジェクト2012/9/8 7
  9. 9. サイバー系 (参考)Rのデータの復習  vector・・・同一の型の値がn個連なってる x <- 1:10 #1, 2, 3, 4, 5, 6, 7, 8, 9, 10 y <- c(“A”, “T”, “G”, “C”) # A, T, G, C  matrix・・・行列なんだけど実体はベクトルだから値は同じ型で ないとダメだよ m <- matrix(1:10, nrow=2)  data.frame・・・いろんな型のvectorが(ただし長さは同じ) 集まって行列みたいになってる x <- c(2, 2, 3, 3) y <- c(“A”, “T”, “G”, “C”) d <- data.frame(x, y)2012/9/8 8
  10. 10. サイバー系 ffの使い方  ffライブラリはデータの種類が2つある  ff・・・vector, matrix  ffdf・・・data.frame  使い方 x.ff <- ff(0:1e+8) m.ff <- ff(0:1e+8, dim=c(20000,5000)) d.ffdf <- ffdf(x=ff(0:1e+8), y=ff(1e+8:2e+8)) #上記の場合、一旦メモリ上にベクトル作ってからffオブジェクト に変換されるので場合によっては爆死する。以下のようにファイ ルを読み込むほうがいい。(DBにJDBCで繋いでデータ取得して 直接ffオブジェクトにすることも可能) d2.ffdf <- read.csv.ffdf(“dio.csv”) #read.table.csv使うと、文字列は自動的にfactor型として読み込んで くれるから激しく便利です!2012/9/8 9
  11. 11. サイバー系 ff雑談  ffのここが親切 #巨大オブジェクトをうっかりタイプしてしまって #爆死した経験、一度はあると思います d.ffdf ってしても大丈夫☆  ディスク上の実体みてみる filename(d.ffdf) #ffdfの場合、1列が1ベクトルになっていてそれが1つのファイルになってます2012/9/8 10
  12. 12. サイバー系 ffの特長  更にffbaseというライブラリがあって、ff用の多数の便 利な関数を実装してくれている  bigmemoryより、データ加工等の自由度が高い!  RevoScaleRより、使い慣れた関数・引数で扱えるから変 なストレスとグッバイ  ffとffbaseライブラリでこんなにイロイロできます 1. Basic operations (c, unique, duplicated, ffmatch, ffdfmatch, %in%, is.na, all, any, cut, ffwhich, ffappend, ffdfappend) 2. Standard operators (+, -, *, /, ^, %%, %/%, ==, !=, <, <=, >=, >, &, |, !) on ff vectors 3. Math operators (abs, sign, sqrt, ceiling, floor, trunc, round, signif, log, log10, log2, log1p, exp, expm1, acos, acosh, asin, asinh, atan, atanh, cos, cosh, sin, sinh, tan, tanh, gamma, lgamma, digamma, trigamma) 4. Selections & data manipulations (subset, transform, with, within, ffwhich) 5. Summary statistics (sum, min, max, range, quantile, hist) 6. Data transformations (cumsum, cumprod, cummin, cummax, table, tabulate, merge, ffdfdply)2012/9/8 11
  13. 13. サイバー系 ffの欠点  ディスク上にファイルを多数生成するから遅い。  ffdf(data.frame)は多数のff(vector)の集合体であり、 カラム数ぶんだけff(vector)が存在するので、カラム数 ぶんのffファイルがtemp領域にできる。  適用させる関数に注意しないと巨大なデータがうっかりオ ンメモリになる  dio.ffdf$xはff型で返ってくるから大丈夫  dio.ffdf[,1]はオンメモリ(通常のvector)で返ってくるから爆死2012/9/8 12
  14. 14. サイバー系 今日のお話 1. ffについて 2. ffでGLM 3. 実践2012/9/8 13
  15. 15. サイバー系 ところで  こんなこと言っときながら  bigmemoryいいなって 思った時期もありました2012/9/8 14
  16. 16. サイバー系 biganalyticsライブラリ  bigmemoryだと、biganalyticsライブラリでglmができ るのか~と思って  biganalyticsのソースを見る bigglm.big.matrix = function( formula, data, chunksize=NULL, ..., fc=NULL, getNextChunkFunc=NULL) { ん、biglmだ と... ってことはbiganayticsはただのラッパー関数か require(biglm) getNextDataFrame = CreateNextDataFrameGenerator(formula, data, chunksize, fc, getNextChunkFunc, ...) return(bigglm(formula=formula, data=getNextDataFrame, chunksize=chunksize, ... )) }2012/9/8 15
  17. 17. サイバー系 biglmライブラリ biglm.Rのソースコード bigglm.function<-function(formula, data, family=gaussian(), weights=NULL, sandwich=FALSE, maxit=8, tolerance=1e-7, start=NULL, quiet=FALSE,...){ tt<-terms(formula) beta <- start etafun <- function(x) if(is.null(beta)) rep(0,nrow(x)) else x%*%beta converged<-FALSE for (i in 1:maxit){ firstchunk <- TRUE deviance<-0 rss<-0 data(reset=TRUE) n<-0 ffって書いてある! while(!is.null(chunk<-data(reset=FALSE))){ 以下略 ここでffdfをchunk単位に行分割して、通常のdata.frame にしてからwhileループのなかでQR分解をupdateして 最終的に解を出してる まあつまり、ff(というかffdf)のデータでGLMできるということだ2012/9/8 16
  18. 18. サイバー系 ちょっとコード修正 自分の環境だとどうしても以下の箇所でエラーが起きたの でコメントアウトしました # rval$call[[1]]<-as.name(.Generic) formula = Y~. みたいな目的変数以外全部説明変数ね、っ ていうformulaをサポートしてなかったからそこんとこ追 加しました if(any(as.character(as.formula(formula)) %in% “.”)){ Y <-as.character(as.formula(formula))[which(!as.character(as.formula(formula)) %in% c("~", "."))] formula <- as.formula(paste(Y, "~",paste(colnames(data)[which(!colnames(data) %in% Y)],collapse="+"), sep="")) }2012/9/8 17
  19. 19. サイバー系 ちょっとコード修正② 目的変数が因子型だとエラーになるので、そこ修正しました # z<- eta+(y-mu)/dmu ↓↓↓↓ ifelse(is.factor(y), z<- eta+(as.integer(y)-mu-1)/dmu, z<-eta+(y-mu)/dmu rbindが使えなかったので作りました  じつはそれっぽい関数としてffdfapendが用意されているのだが、 CRANからとれる現行のversion0.5だとffdf同士の結合ができない 。で、google codeからとれるversion0.6だとffdf同士の結合がで きるって触れ込みだったのだが、factor型の列があるとダメだった2012/9/8 18
  20. 20. サイバー系 今日のお話 1. ffについて 2. ffでGLM 3. 実践2012/9/8 19
  21. 21. サイバー系 使うデータ  使用するデータはもちろん、みんな大好きData Expo2009のAirline  1987~2008年のアメリカの旅客機のフライトデータ  カラムは以下の通りで、距離と時間以外は因子型で扱いました Name Description 1 Year 1987-2008 2 Month 1-12 3 DayofMonth 1-31 4 DayOfWeek 1 (Monday) - 7 (Sunday) 5 DepTime actual departure time (local, hhmm) 6 CRSDepTime scheduled departure time (local, hhmm) 7 ArrTime actual arrival time (local, hhmm) 8 CRSArrTime scheduled arrival time (local, hhmm) 9 UniqueCarrier unique carrier code 10 FlightNum flight number 11 TailNum plane tail number 12 ActualElapsedTime in minutes 13 CRSElapsedTime in minutes 14 AirTime in minutes 15 ArrDelay arrival delay, in minutes 16 DepDelay departure delay, in minutes 17 Origin origin IATA airport code 18 Dest destination IATA airport code 19 Distance in miles 20 TaxiIn taxi in time, in minutes ※色替わってるカラムを今回使用しました 21 TaxiOut taxi out time in minutes 22 Cancelled was the flight cancelled? 23 CancellationCode reason for cancellation (A = carrier, B = weather, C = NAS, D = security) 24 Diverted 1 = yes, 0 = no 25 CarrierDelay in minutes 26 WeatherDelay in minutes 27 28 NASDelay SecurityDelay in minutes in minutes ☆フライトがキャンセルされた要因を説明する 29 LateAircraftDelay in minutes2012/9/8 20
  22. 22. サイバー系 データについて蛇足  ちなみに、全データをDLして結合させてRに普通に取り込 むとこんな感じ  1.2億行  オブジェクトのサイズは16.5G(もはやメモリに載る時代)  しかし、glmはできない  今回利用したのは計算時間 の関係で2000年代のみ  2000年代のみのデータの場合 で列選択後だとこんな感じ→  しかし、これでもglmできない  glmの計算するときに、データ がmatrixに変換されちゃう! そう、2^31の呪い発動です2012/9/8 21
  23. 23. サイバー系 データの読み込み #データは年ごとにバラバラのファイルになってるので一応、年ごとに読み込む #ここでのポイントは、factor型にしたい列は読み込みの段階でfactor化しちゃうこと library(ff); library(ffbase) a2008.ffdf <- read.table.ffdf(file="data/2008.csv", sep=",", header=TRUE, colClasses=c(Year="factor", Month="factor", DayOfWeek="factor", Cancelled="factor")) a2007.ffdf <- read.table.ffdf(file="data/2007.csv", sep=",", header=TRUE, colClasses=c(Year="factor", Month="factor", DayOfWeek="factor", Cancelled="factor")) : (略) a2000.ffdf <- read.table.ffdf(file="data/2000.csv", sep=",", header=TRUE, colClasses=c(Year="factor", Month="factor", DayOfWeek="factor", Cancelled="factor")) #データの行結合(自作のrbind.ffdf関数を使ってます) tt1.ffdf <- rbind.ffdf(a2000.ffdf, a2001.ffdf) : (略) air.ffdf <- rbind.ffdf(tt1.ffdf, a2008.ffdf)2012/9/8 22
  24. 24. サイバー系 データの整形とか #不要なオブジェクトを消す del.obj <- ls()[grep("^a¥¥d+¥¥.ffdf", ls())] for(i in 1:length(del.obj)){ delete(del.obj[i])#disk上の実体を消す #memory上のポインタを消す(rmしてるだけ) eval(parse(text=paste("rm(", del.obj[i], ")", sep=""))) } rm(del.obj) #必要な列だけ抽出する if(FALSE){ #↓こうするとデータがオンメモリになって爆死するから注意 air.ffdf2 <- air.ffdf[,c(1,2,4,9,13,17,18,19,22)] } air.ffdf2 <- ffdf(Year=air.ffdf$Year, Month=air.ffdf$Month, DayOfWeek=air.ffdf$DayOfWeek, UniqueCarrier=air.ffdf$UniqueCarrier, CRSElapsedTime=air.ffdf$CRSElapsedTime, Origin=air.ffdf$Origin, Dest=air.ffdf$Dest, Distance=air.ffdf$Distance, Cancelled=air.ffdf$Cancelled) #必要な行だけ抽出(NAが含まれる列があったので、その列にNAが含まれる行を削除) air.ffdf2 <- subset.ff(air.ffdf2, !is.na.ff(air.ffdf2$CRSElapsedTime))2012/9/8 23
  25. 25. サイバー系 GLM #必要な行だけ抽出(NAが含まれる列があったので、その列にNAが含まれる行を削除) #デフォルトのbigglm関数だといろいろ動かなかったので、前述のとおりいろんなとこに 手いれてます air.mdl <- bigglm.data.frame(Cancelled~., data=air.ffdf2, family=binomial(link="logit"), maxit=1, tolerance=1e-5) この例だとチョーべたなロジスティック回帰ですが、GLMなんで もちろんいろんな分布・リンク関数使えます。 ここら辺はもちろん使える2012/9/8 24
  26. 26. サイバー系 ffでGLM(ロジスティック回帰)の結果 #で、フライトがキャンセルになる要因は何なんだい!? #(全部は載せられないので抜粋) print(summary(air.mdl), digits=4) #bigglmの結果をcar::Anovaに入れることはできない! #SASのtypeⅢ平方和バンザイな人、残念!! Coef (95% CI) SE p Year2001 -0.2066 -0.2157 -0.1975 0.0045 0.0000 Year2002 -0.2753 -0.2855 -0.2651 0.0051 0.0000 Year2003 0.1128 0.1012 0.1244 0.0058 0.0000 Year2004 -0.2277 -0.2367 -0.2187 0.0045 0.0000 Year2005 -0.1930 -0.2021 -0.1839 0.0046 0.0000 Year2006 0.0109 -0.0006 0.0223 0.0057 0.0577 Year2007 0.6616 0.6517 0.6715 0.0049 0.0000 やけにp=0.0000が多い。 Year2008 -0.1394 -0.1510 -0.1278 0.0058 0.0000 Month2 -0.0154 -0.0232 -0.0076 0.0039 0.0001 Month3 -0.0651 -0.0727 -0.0575 0.0038 0.0000 あと、実はやたらNAも多い Month4 -0.0469 -0.0546 -0.0393 0.0038 0.0000 Month5 -0.0141 -0.0217 -0.0065 0.0038 0.0002 Month6 0.0164 0.0097 0.0231 0.0033 0.0000 Month7 0.0940 0.0873 0.1007 0.0033 0.0000 Month8 -0.0299 -0.0374 -0.0223 0.0038 0.0000 Month9 -0.0605 -0.0682 -0.0528 0.0038 0.0000 Month10 -0.0677 -0.0752 -0.0601 0.0038 0.0000 Month11 -0.0578 -0.0654 -0.0501 0.0038 0.0000 Month12 0.0233 0.0167 0.0298 0.0033 0.0000 DayOfWeek2 -0.0140 -0.0195 -0.0086 0.0027 0.0000 DayOfWeek3 -0.0246 -0.0290 -0.0202 0.0022 0.0000 DayOfWeek4 -0.0194 -0.0241 -0.0146 0.0024 0.0000 DayOfWeek5 -0.0417 -0.0462 -0.0372 0.0023 0.0000 DayOfWeek6 -0.0916 -0.0965 -0.0867 0.0024 0.0000 DayOfWeek7 -0.0278 -0.0310 -0.0246 0.0016 0.0000 CRSElapsedTime 0.0003 0.0002 0.0003 0.0000 0.0000 Distance 0.0000 0.0000 0.0000 0.0000 0.00002012/9/8 25
  27. 27. サイバー系 GLM(ロジスティック回帰)の結果  試しにランダムサンプリングしてサンプル数(行数)減らしたデータで 通常のGLMをしてみる #(適当に)7万行をランダムに選択 air70k <- as.data.frame(air2.ffdf[sample(1:nrow(air2.ffdf), 70000),]) #GLM air70k.mdl <- stats::glm(Cancelled ~ ., data=air70k, family=binomial(link=“logit”)) #めっちゃメモリ必要です summary(air70k.mdl) 結果略 (後述) 結果違うって 本当かい!? bigglmは同じ計算を何度もして、計算結果が収束したら while文をbreakする仕組み。今回は時間の都合でループ 1度しか回さないようにしたのでもちろん収束してません。 あとあれだ、計算途中でInfとか出てる可能性もあるかも2012/9/8 26
  28. 28. サイバー系 結果違いましたが、stats::glmの結果見てみる #で、フライトがキャンセルになる要因は今度こそ何なんだい!? #(全部は載せられないので抜粋①) *summary()で結果を見た場合はfactor型は因子の 年による影響 最初のLevelを基準にした結果になる Estimate Std. Error z value Pr(>|z|) (Intercept) -2.546e+00 4.014e-01 -6.342 2.26e-10 *** Year2001 -1.455e+00 5.014e-02 -29.015 < 2e-16 *** 2000年はフライトキャンセルが多い。 Year2002 -1.293e+00 4.616e-02 -28.016 < 2e-16 *** (2000年問題?) Year2003 -9.747e-01 3.796e-02 -25.677 < 2e-16 *** Year2004 -8.687e-01 3.592e-02 -24.181 < 2e-16 *** Year2005 -7.939e-01 3.552e-02 -22.352 < 2e-16 *** Year2006 -9.203e-01 3.726e-02 -24.702 < 2e-16 *** Year2007 -6.421e-01 3.501e-02 -18.343 < 2e-16 *** Year2008 -7.493e-01 3.644e-02 -20.563 < 2e-16 *** 月による影響 Month2 3.280e-02 3.805e-02 0.862 0.388631 Month3 -3.806e-01 4.109e-02 -9.261 < 2e-16 *** Month4 -6.921e-01 4.574e-02 -15.131 < 2e-16 *** 12,1,2月はフライトキャンセルが多い。 Month5 -6.975e-01 4.535e-02 -15.381 < 2e-16 *** (冬だからな) Month6 -3.159e-01 4.078e-02 -7.748 9.34e-15 *** Month7 -4.121e-01 4.163e-02 -9.900 < 2e-16 *** Month8 -3.481e-01 4.068e-02 -8.557 < 2e-16 *** Month9 -2.957e-01 4.101e-02 -7.211 5.57e-13 *** Month10 -7.244e-01 4.591e-02 -15.777 < 2e-16 *** Month11 -7.748e-01 4.747e-02 -16.323 < 2e-16 *** Month12 1.188e-01 3.695e-02 3.216 0.001300 ** 曜日による影響 DayOfWeek2 4.218e-02 3.279e-02 1.286 0.198435 土・日はフライトキャンセルが少ない DayOfWeek3 7.648e-02 3.254e-02 2.350 0.018752 * DayOfWeek4 3.133e-02 3.284e-02 0.954 0.339991 (お客さん多いから頑張っちゃう?) DayOfWeek5 2.210e-02 3.288e-02 0.672 0.501444 DayOfWeek6 -1.571e-01 3.611e-02 -4.349 1.36e-05 *** DayOfWeek7 -1.645e-01 3.503e-02 -4.697 2.64e-06 ***2012/9/8 27
  29. 29. サイバー系 結果違いましたが、stats::glmの結果見てみる・続き #(全部は載せられないので抜粋②) 航空会社による影響 Estimate Std. Error z value Pr(>|z|) UniqueCarrierB6 -5.189e-01 1.437e-01 -3.611 0.000305 *** JetBlue Airways、Continental Air Lines Inc.、Frontier Airlines Inc.、 UniqueCarrierCO -1.433e+00 1.270e-01 -11.282 < 2e-16 *** AirTran Airways Corporation、Trans World Airways LLC、 UniqueCarrierF9 -1.005e+00 2.341e-01 -4.294 1.75e-05 *** US Airways Inc.、 Southwest Airlines Co. はキャンセルになりにくい。 UniqueCarrierFL -6.708e-01 1.309e-01 -5.124 2.99e-07 *** Mesa Airlines Inc.はキャンセルになりやすい。 UniqueCarrierTW -8.223e-01 1.721e-01 -4.777 1.78e-06 *** UniqueCarrierUS -4.794e-01 1.105e-01 -4.339 1.43e-05 *** UniqueCarrierWN -7.638e-01 1.114e-01 -6.856 7.08e-12 *** UniqueCarrierYV 4.000e-01 1.163e-01 3.439 0.000584 *** 出発空港による影響 OriginASE 1.350e+00 3.528e-01 3.828 0.000129 *** Aspen-Pitkin Co/Sardy、Unalaska発のフライトはキャンセルになりやすい。 OriginDUT 2.517e+00 5.925e-01 4.249 2.15e-05 *** Tucson International発はキャンセルになりにくい。 OriginTUS -1.107e+00 3.685e-01 -3.005 0.002653 ** 到着空港による影響 DestEWR 1.030e+00 3.002e-01 3.431 0.000601 *** Newark Intl行のフライトはキャンセルになりやすい 距離・時間による影響 CRSElapsedTime 5.603e-03 1.175e-03 4.767 1.87e-06 *** 予定フライト時間・距離がキャンセルに与える影響 Distance -1.126e-03 1.443e-04 -7.806 5.90e-15 *** は(有意差は出てるけど)、あんまり無いな 例えばこの場合だと、予定フライト時間が1分増えると、 フライトキャンセルのオッズ比がe^0.0056倍(≒1.0056倍)になる2012/9/8 28
  30. 30. サイバー系 最後に感想 1. ffでGLMが出来るなんて(まともな結果が得られるなら)素 敵な武器が増えるね! 2. しかも、ffはRevoScaleRと違っていつも使ってるおなじ みの関数群っぽいのが使えるから便利 3. とはいえ、data加工の段階でうっかりオンメモリにならな いように細心の注意を払う必要あり 4. character型が扱えないのが激しく不便 (RevoScaleRはcharacterも扱える)2012/9/8 29

×