Microsoft R Clientによる大規模データの分析
Revolution Analyticsを買収したMicrosoftが、Revolution R Openに代わりMicrosoft R OpenというRのラッパーのようなものを出している。それに更に大規模データ分析用の独自開発パッケージを追加したMicrosoft R Client(MRC)というツールがあり、MRCの独自パッケージ{MicrosoftML}に実装されているrxGLMを用いて簡単な動作テストを実行したのでその結果を記しておく。MRCのインストールについてはこちらを参照:
まずは大規模データを読み込むために{readr}パッケージをインストール。なお今回はAWSに新しく立てたWindows Serverを使うので、{tidyverse}を使って必要そうなパッケージをまとめてインストールすることにする。
install.packages("tidyverse")
続いてライブラリの読み込みと作業ディレクトリの変更を行う。
library(readr) library(MicrosoftML) library(RevoScaleR) library(lattice) wk_dir <-"C:/Users/Administrator/Desktop/MicrosoftML" setwd(wk_dir)
データを読み込む。{MicrosoftML}がハイパフォーマンスやスケーラブルを謳っているので、そこそこの大規模データ(500万行×18列、2GB程度)を使用してみた。サンプルデータはこちらから取得した。
UCI Machine Learning Repository
### 大規模データの読み込みにreadr::read_csvを使用 ### ヘッダーがないのでcol_namesはFALSEにする datTmp <- read_csv("Data/SUSY.csv", col_names = FALSE) ### X1が目的変数、X2〜X5を説明変数として使用した ### 全カラムを使用した時の結果は後日 ### まずは結果の比較用にglmを実行。まぁ、動かないだろうと予想 start_time <- Sys.time() res_GLM <- glm(X1 ~ X2 + X3 + X4 + X5, family = binomial("logit"), data = datTmp) end_time <- Sys.time() print(end_time - start_time) # 予想通りメモリの割り当てに失敗した旨のエラーメッセージを受け取る。。。 ### MicrosoftMLではどうか。rxGLMが{MicrosoftML}におけるGLMに相当する関数。 start_time <- Sys.time() res_rxGLM <- rxGlm(X1 ~ X2 + X3 + X4 + X5, family = binomial("logit"), data = datTmp) end_time <- Sys.time()
> print(end_time - start_time) Time difference of 9.806952 secs
なんと、500万行のデータのglmが10秒足らずで実行できた。なおWindowsインスタンスはAWSでのt2.medium(64bit、RAM4GB)を使用しており、特別スペックが良いという訳ではない。
このままではglmとの比較ができないので、もう少しデータを減らして再挑戦してみる。
### gcを使ってメモリを解放しておく gc() gc() ### 使用データを100万行にする datTmp_1MM <- datTmp[1:1000000, ] ### 再実行 start_time <- Sys.time() res_rxGLM_02 <- rxGlm(X1 ~ X2 + X3 + X4 + X5, family = binomial("logit"), data = datTmp_1MM) end_time <- Sys.time() print(end_time - start_time) # Time difference of 1.839989 secs gc() gc() start_time <- Sys.time() res_GLM_02 <- glm(X1 ~ X2 + X3 + X4 + X5, family = binomial("logit"), data = datTmp_1MM) end_time <- Sys.time() >print(end_time - start_time) # Time difference of 7.471947 secs
今度はglmでも10秒かからず実行できた。
そこで両者の結果が一致するかを確認する。
coef(res_GLM_02) (Intercept) X2 X3 X4 X5 -1.7128408655 2.6384939818 0.0002822391 -0.0012571389 -0.9573449310 coef(res_rxGLM_02) (Intercept) X2 X3 X4 X5 -1.7128408655 2.6384939818 0.0002822391 -0.0012571389 -0.9573449310
回帰係数は両者で一致しており、問題なさそうだ。
続いてsummaryを実行する。
### まずはrxGLM > summary(res_rxGLM_02) Call: rxGlm(formula = X1 ~ X2 + X3 + X4 + X5, data = datTmp_1MM, family = binomial("logit")) Generalized Linear Model Results for: X1 ~ X2 + X3 + X4 + X5 Data: datTmp_1MM Dependent variable(s): X1 Total independent variables: 5 Number of valid observations: 1e+06 Number of missing observations: 0 Family-link: binomial-logit Residual deviance: 1160233.9234 (on 999995 degrees of freedom) Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) -1.7128409 0.0052066 -328.976 2.22e-16 *** X2 2.6384940 0.0079644 331.285 2.22e-16 *** X3 0.0002822 0.0022039 0.128 0.898 X4 -0.0012571 0.0022356 -0.562 0.574 X5 -0.9573449 0.0062846 -152.332 2.22e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 (Dispersion parameter for binomial family taken to be 1) Condition number of final variance-covariance matrix: 7.0668 Number of iterations: 6 ### 続いてglm > summary(res_GLM_02) Call: glm(formula = X1 ~ X2 + X3 + X4 + X5, family = binomial("logit"), data = datTmp_1MM) Deviance Residuals: Min 1Q Median 3Q Max -8.4904 -0.8894 -0.7140 1.0654 3.0185 Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) -1.7128409 0.0052066 -328.977 <2e-16 *** X2 2.6384940 0.0079644 331.287 <2e-16 *** X3 0.0002822 0.0022039 0.128 0.898 X4 -0.0012571 0.0022356 -0.562 0.574 X5 -0.9573449 0.0062846 -152.333 <2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 (Dispersion parameter for binomial family taken to be 1) Null deviance: 1379205 on 999999 degrees of freedom Residual deviance: 1160234 on 999995 degrees of freedom AIC: 1160244 Number of Fisher Scoring iterations: 5
summaryの結果も両者で大きく異なる様子はない。rxGLMの方でもう少し情報を追加したぐらいか。
一旦動作テストは以上である。{MicrosoftML}は少なくともオリジナルのRのglmと比較して大規模データに強いというのは間違いなさそうで、Rの弱点をカバーできる作りになっているようだ。従来MicrosoftはSQL ServerとRを連携させることで大規模データへの対応を行ってきたイメージがあったが、R単体(と言えないかもしれないが)でこれぐらいの規模のデータを処理できるのであれば、ウェブログを触るような状況とならない限りR一本で大抵の処理はできるように思う。RユーザーとしてはMRCを含めて近年のMicrosoftのRへの貢献はかなり大きいと感じている。
また今回の記事では割愛したが、{MicrosoftML}ではrxGLM以外にも様々な関数が用意されており、特に二項分類のための”Fast Tree"と呼ばれるアルゴリズムを実装した関数はかなり強力な感触を受けた。こちらの検証結果も後日書いてみようと思う。