最近のRの
ランダムフォレストパッケージ
- ranger / Rborist -
2015年10月10日
第51回Tokyo.R
@sfchaos
1
自己紹介
■ twitterID: @sfchaos
■ 仕事: クルマのデータマイニング
■ 興味: ノンパラメトリックベイズ/混合メンバシップ
モデル/Julia/Spark
2
宣伝1
■ データサイエンティスト養成読本

機械学習入門編
■ 豪華な執筆陣!!
■ 祝・刊行1ヶ月!!
■ 機械学習の入門に最適な一冊.
■ 「機械学習って何で注目されているの? 意味ある
の?」or「機械学習ってなんでもできるんでしょ!?」
という人には第I部特集1がオススメ.
3
宣伝1
■第1部 しくみと概要を学ぼう!
■特集1 機械学習を使いたい人のための入門講座
■特集2 機械学習の基礎知識
■特集3 ビジネスに導入する機械学習
■特集4 深層学習最前線
■第2部 手を動かして学ぼう!
■特集1 機械学習ソフトウェアの概観
■特集2 Pythonによる機械学習入門
■特集3 推薦システム入門
■特集4 Pythonで画像認識にチャレンジ
■特集5 Jubatusによる異常検知 4
宣伝2
■ 「岩波データサイエンス Vol.1」
■ 豪華な執筆陣!!
■ 特集は,ベイズ推論とMCMCのソフトウェア
■ 芥川賞受賞作家・円城塔さんの掌編小説も!!
■ 雑誌のように気軽に手にとって,本のように骨のあ
る本
■ 書評

http://d.hatena.ne.jp/sfchaos/20151010
5
アジェンダ
■ 最近のRの機械学習パッケージ
■ rangerとRborist(ランダムフォレスト)
■ rangerでの疎行列の扱い
■ まとめ
6
1. 最近のRの機械学習パッケージ
7
最近のトピック
■ 新しいランダムフォレスト実装の台頭 

(ranger/Rborist)

■ 勾配ブースティングの隆盛 (xgboost)

■ mlrパッケージの台頭? (caretと肩を並べつつある?)
■・・・
8
最近のトピック
■ 新しいランダムフォレスト実装の台頭

(ranger/Rborist)

■ 勾配ブースティングの隆盛 (xgboost)

■・・・
9
今回はランダムフォレストの
新しいパッケージについて
ランダムフォレストとは
■ クラス分類・回帰を実行する機械学習の代表的な手法。
■ 訓練データに対してサンプルのブートストラップと説明変
数のサンプリングを行って複数の決定木を構築。
■ テストデータに対して、各決定木の予測結果の多数決によ
り予測を実行。
10
randomForestパッケージ
■ 従来の定番.
■ partyパッケージとかも(条件付き推測木).
11
ranger/Rborist
■ ranger: A Fast Implementation of Random Forests
for High Dimensional Data in C++ and R



http://arxiv.org/abs/1508.04409
■ ranger(RANdom forest GEneRator)
■ rangerもRboristも中身はC++.
■ rangerはスレッド並列化が可能.
12
ranger/Rborist
■ 新たなランダムフォレストのパッケージ
■ @dichikaさんのブログを参照.

RでランダムフォレストやるならRboristかrangerか

http://d.hatena.ne.jp/dichika/20150828/p1
13
ranger/Rborist
■ これまでにも,いくつかのブログで取り上げられている
■ "ranger: A Fast Implementation of Random Forests”のメモ書き

http://yamano357.hatenadiary.com/entry/2015/09/17/230536
■ TagTeam :: Predicting Titanic deaths on Kaggle V: Ranger - R-
bloggers - Statistics and Visualization

http://tagteam.harvard.edu/hub_feeds/1981/feed_items/
2126439
■ [R言語]library("ranger")とlibrary("randomForest")の速度を比較
する - gepulog

http://blog.gepuro.net/archives/130
■ 新型のランダムフォレスト(Random Forest)パッケージ比較:
Rborist・ranger・randomForest - My Life as a Mock Quant

http://d.hatena.ne.jp/teramonagi/20150914/1442226764
14
パッケージ間の比較
■ 小規模データに対する実行時間の比較
15
■ ranger: A Fast Implementation of
Random Forests for High
Dimensional Data in C++ and R
■ Figure 3

http://arxiv.org/abs/1508.04409
パッケージ間の比較
■対象データ:シミュレーションされた100,000サン
プル,100特徴量
16
■ ranger: A Fast Implementation of Random Forests for High
Dimensional Data in C++ and R
■ Table 2

http://arxiv.org/abs/1508.04409
rangerとRboristの比較
17
■ 連続量の特徴量に対してサンプルサイズと特徴量数を変化させて比較
■ ranger: A Fast Implementation of Random Forests for High Dimensional
Data in C++ and R
■ Figure 4

http://arxiv.org/abs/1508.04409
2. rangerとRborist

 (ランダムフォレスト)
18
パッケージのインストール
■ CRANからインストール
19
> install.packages(c(“randomForest”, “ranger”, “Rborist”))
使用方法
20
> randomForest(目的変数 ~., data=データ)
> ranger(目的変数 ~., data=データ))
> Rborist(説明変数, 目的変数)
比較実験
■ spamデータセット
21
> library(kernlab)
> data(spam)
> dim(spam)
[1] 4601 58
比較実験
22
> # randomForest
> system.time(randomForest(type ~., data=spam, ntree=1000))
 ユーザ システム 経過
20.885 0.176 21.265
> # ranger
> system.time(ranger(type ~., data=spam, num.trees=1000,
+ seed=71))
 ユーザ システム 経過
8.688 0.113 2.534
> # ranger(省メモリモード)
> system.time(ranger(type ~., data=spam, seed=71,
+ save.memory=TRUE))
 ユーザ システム   経過
29.017 0.113 8.171
> # Rborist
> system.time(Rborist(spam %>% select(-type), spam$type))
 ユーザ システム   経過
 7.948 0.630 8.616
引数の対応
23
決定木の個数 サンプリングする
特徴量数
クラスウェイト
(不均衡データ)
randomForest ntree mtry classwt
ranger num.trees mtry ?
Rborist ntree predProb
(各特徴量が選択さ
れる確率)
classWeight
3. rangerでの疎行列の扱い
24
rangerの疎行列の扱い
25
http://yamano357.hatenadiary.com/entry/2015/09/17/230536
!!!
rangerパッケージの処理フロー
■ Rのranger関数がユーザとのインタフェース
■ rangerCpp関数からC++のranger_rangerCpp関数を呼び出す.
■ ranger_rangerCpp関数の中でrangerCpp関数を呼び出し,forest
クラスをインスタンス化して,ランダムフォレストを構築する.
26
ranger関数 rangerCpp関数
C++
・forestクラスのインスタンス化
・forestクラスの初期化
・ランダムフォレストの構築
 (forestクラスのrunメンバー関数)
- 決定木の構築(treeクラス)
ranger_rangerCpp
関数
rangerCpp関数
C++
rangerCpp関数の引数
27
## Call Ranger
result <- rangerCpp(treetype, dependent.variable.name, data.final, variable.names, mtry,
num.trees, verbose, seed, num.threads, write.forest, importance.mode,
min.node.size, split.select.weights, use.split.select.weights,
always.split.variables, use.always.split.variables,
status.variable.name, prediction.mode, loaded.forest, sparse.data,
replace, probability, unordered.factor.variables, use.unordered.factor.variables,
save.memory, splitrule)
ranger_rangerCpp関数の引数
28
cppExport SEXP ranger_rangerCpp(SEXP treetypeSEXP, … , SEXP splitrule_rSEXP) {
…
Rcpp::traits::input_parameter< Rcpp::RawMatrix >::type sparse_data(sparse_dataSEXP);
…
}
rangerでの疎行列対応
■ 疎行列に対応しているのはgwaa.dataクラスのオブ
ジェクトのみ(GenABELパッケージ).
29
## GenABEL GWA data
if (class(data) == "gwaa.data") {
snp.names <- data@gtdata@snpnames
sparse.data <- data@gtdata@gtps@.Data
data <- data@phdata
if ("id" %in% names(data)) {
data$"id" <- NULL
}
gwa.mode <- TRUE
save.memory <- FALSE
} else {
sparse.data <- as.matrix(0)
gwa.mode <- FALSE
}
R/ranger.R 166-179
gwaa.dataクラスの使用
■ 試しに,GenABEL.dataパッケージのge03d2データ
セットを指定してみる.
■ 遺伝子のデータ?
30
gwaa.dataクラスの使用
■ こんなデータ
31
> library(GenABEL.data)
> data(ge03d2)
> str(ge03d2)
Formal class 'gwaa.data' [package "GenABEL"] with 2 slots
..@ phdata:'data.frame': 950 obs. of 8 variables:
.. ..$ id : chr [1:950] "id4" "id10" "id25"
"id33" ...
.. ..$ sex : int [1:950] 0 1 0 0 0 0 1 1 0 1 ...
.. ..$ age : num [1:950] 51.6 53.7 66 44.7 49.9 ...
.. ..$ dm2 : int [1:950] 1 1 1 1 1 1 1 1 1 1 ...
.. ..$ height: num [1:950] 152 170 165 174 157 ...
.. ..$ weight: num [1:950] 83 65.6 69.6 69.7 84.3 ...
.. ..$ diet : int [1:950] 0 0 0 0 0 0 0 0 0 0 ...
.. ..$ bmi : num [1:950] 36 22.6 25.6 22.9 34.1 ...
..@ gtdata:Formal class 'snp.data' [package "GenABEL"]
with 11 slots
.. .. ..@ nbytes : num 238
.. .. ..@ nids : int 950
•••
gwaa.dataクラスの使用
■ phdataで回帰を実行してみる
32
> # 欠損値の除去
> ge03d2@phdata <- na.omit(ge03d2@phdata)
> head(ge03d2@phdata)
id sex age dm2 height weight diet bmi
id4 id4 0 51.63771 1 151.7863 83.03480 0 36.04086
id10 id10 1 53.73938 1 170.3180 65.59815 0 22.61363
id25 id25 0 66.01148 1 164.7949 69.55278 0 25.61103
id33 id33 0 44.66715 1 174.4638 69.73042 0 22.90929
id35 id35 0 49.87941 1 157.1834 84.27884 0 34.11185
id58 id58 0 36.99524 1 165.0929 89.53816 0 32.85122
> # BMIを目的変数とする回帰モデルの構築
> model.rg <- ranger(bmi ~., data=ge03d2)
スパースデータのデータ構造
■ このとき,sparse.dataは次のようになっている.
33
## GenABEL GWA data
if (class(data) == "gwaa.data") {
snp.names <- data@gtdata@snpnames
sparse.data <- data@gtdata@gtps@.Data
data <- data@phdata
if ("id" %in% names(data)) {
data$"id" <- NULL
}
gwa.mode <- TRUE
save.memory <- FALSE
} else {
sparse.data <- as.matrix(0)
gwa.mode <- FALSE
}
R/ranger.R 166-179
> dim(sparse.data)
[1] 238 7589
> class(sparse.data)
[1] “matrix”
> sparse.data[1:3, 1:3]
[,1] [,2] [,3]
[1,] 99 95 ae
[2,] 57 55 db
[3,] 9a 55 2f
> mode(sparse.data)
[1] "raw"
モードがraw
4. まとめ
34
まとめ
■ Rでランダムフォレスト実行のパッケージとして,
ranger, Rborist等が開発されている.
■ rangerで疎行列を扱えるのは,現状,gwaa.dataク
ラスのオブジェクトのみ.
35

最近のRのランダムフォレストパッケージ -ranger/Rborist-