SlideShare a Scribd company logo
1 of 49
による高速処理
DATE: 2016/11/18 AUTHOR: Atsushi Yoshida
~ まだfor使ってるの? ~
自己紹介
吉田 敦(よしだ あつし)
• 鎌倉研究室M2
• 趣味:R
–Rでデータサイエンス以外のことをするのが
好き
– 前処理が一番楽しい
2
テーマ
3
遅い遅いと謳われるRだけど、
頑張って高速に処理しようぜって話
高速化のためのよくあるTips
• forループよりもapplyファミリー
• ループ演算よりもベクトル演算
• オブジェクトは何度も変形しない
• 内部関数や著名なパッケージを使う
• 行列計算用ライブラリを使う
• 並列化する
• そもそもRで書かない
4
高速化のためのよくあるTips
1. ループ演算よりもベクトル・行列演算
2. 著名なパッケージや内部関数を使う
3. ループ演算は並列化する
5
高速化のためのよくあるTips
1. ループ演算よりもベクトル・行列演算
 『forを使うな 第一弾』(初級者向け)
2. 著名なパッケージや内部関数を使う
 『覚えゲー』(中級者向け)
3. ループ演算は並列化する
 『ハイスペマシンにあやかる』
『forを使うな 第二弾』(初・上級者向け)
6
7
『forを使うな』 第一弾
ループ演算よりもベクトル・行列演算
Rは,ベクトル演算が得意
『ループ演算よりもベクトル・行列演算』とは
8
vec <- seq1 + seq2
例えば、こういうこと
N <- 1000000
vec <- integer(N)
seq1 <- seq2 <- 1:N
for(i in 1:N) {
vec[i] <- seq1[i] + seq2[i]
}
関数を各要素に対して、実行してくれる
『forを使うな』 第一弾
9
system.time({
vec <- seq1 + seq2
})
## user system elapsed
## 0.006 0.000 0.006
N <- 1000000
vec <- integer(N)
seq1 <- seq2 <- 1:N
system.time({
for(i in 1:N) vec[i] <- seq1[i] + seq2[i]
})
## user system elapsed
## 1.749 0.037 1.831
ベクトル化前
ベクトル化後
高速化の例
なぜ出来るか?
⇒ 関数がベクトル演算に対応しているから
10
sqrt(1:3)
## [1] 1.000000 1.414214 1.732051
iconv(c("あ", "い", "う"), to = "shift-jis")
## [1] "x82xa0" "x82xa2" "x82xa4"
できる例
できない例
Nippon::zen2han(c("1", "4", "16"))
## [1] "1416"
Warning message:
In if (Encoding(s) != "UTF-8") s <- iconv(s, from = "", to = "UTF-8") : the
condition has length > 1 and only the first element will be used
余談
• Vectorize関数を使うと、関数を無理やり
ベクトル演算できるように変形できる
11
Vectorize(function)
Vectorize(Nippon::zen2han)(c("1", "4", "16"))
## 1 4 16
## "1" "4" "16"
12
『forを使うな』 第二弾
ループ演算は並列化する
Rは,シングルコアで動いている
並列処理のイメージ
13
通常のR
並列処理
※詳しいことは知りません
処理を渡す 結果を返す
処理を渡す
計算
結果を返す
計算
foreach パッケージ
• Revolution Analytics社が開発
• forと同じような使い方でわかりやすい
• applyファミリのように使い分ける必要なし
• 返り値を返す
• イテレータを使った省メモリループ
• 並列化をサポート
14
forと同じような使い方
15
for文
foreach文
『in』ではなく『 =』
%do% が必要
for(i in 1:10) {
sqrt(i)
}
foreach(i = 1:10) %do% {
sqrt(i)
}
返り値を返す
16
for文
foreach文
各ループの返り値を
まとめて返す
vec <- numeric(150)
for(i in 1:150) {
vec[i] <- sum(iris[i, 1:4])
}
vec <- foreach(i = 1:150) %do% {
sum(iris[i, 1:4])
}
17
18
19
20
並列化の基本
21
22
23
24
バックエンドの管理
• クラスタの作成・登録・停止がめんどい
25
パッケージの使用
• ループ内でパッケージを使用する場合、
全て指定しなければならない
26
27
28
これを超簡単に書くパッケージがある
29
pforeach
30
31
32
33
34
35
引数
36
この2つを覚えるだけで大丈夫
その他引数については下記を参照
URL - R で超簡単に並列処理を書けるpforeach パッケージ
書籍 - 『Rによるハイパフォーマンスコンピューティング』
• .combine
--> 結合関数を与える
• .parallel
--> 並列のオン・オフを指定する
結合の引数 --> .c (.combine)
37
pforeach(i = 1:3, .c = c) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
pforeach(i = 1:3, .c = list) (sqrt(i))
## [[1]]
## [1] 1
##
## [[2]]
## [1] 1.414214
##
## [[3]]
## [1] 1.732051
##
pforeach(i = 1:3, .c = rbind) (sqrt(i))
## [,1]
## result.1 1.000000
## result.2 1.414214
## result.3 1.732051
デフォルトは c 関数
時々使う?
list 関数
割と使いそう
rbind 関数
並列のオン・オフ
38
pforeach(i = 1:3, .parallel = FALSE) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
npforeach(i = 1:3) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
方法① .parallel = FALSEを付ける
方法② pforeachではなくnpforeachを使う
非並列
非並列
pforeachはデフォルトで並列化
デバック時など,非並列化したいときがある
pforeach(i = 1:3) (sqrt(i))
## [1] 1.000000 1.414214 1.732051
39
40
41
例: ランダムフォレストの並列化
42
library(foreach)
library(kernlab)
library(randomForest)
library(doParallel)
data(spam)
cores <- detectCores()
cl <- makePSOCKcluster(cores)
registerDoParallel(cl)
fit.rf <- foreach(ntree = rep(250, cores),
.combine = combine,
.export = "spam",
.packages = "randomForest") %dopar% {
randomForest(type ~ ., data = spam, ntree = ntree)
}
stopCluster(cl)
foreach
例: ランダムフォレストの並列化
43
library(pforeach)
library(kernlab)
library(randomForest)
data(spam)
fit.rf <- pforeach(ntree = rep(250, .cores),
.c = combine) ({
randomForest(type ~ ., data = spam, ntree = ntree)
})
pforeach
すっきりしました!!
参考
• URL
– for を捨てよ、foreach を書こう
– R で超簡単に並列処理を書けるpforeach パッケージ
– R で超簡単に並列処理を書けるパッケージ pforeach
を作った - ほくそ笑む
– foreachについてまとめたい - J's blog
– foreachでprogressbarを表示する - J's blog
• 書籍
– 『Rによるハイパフォーマンスコンピューティング』
44
progress barを出す(1)
45
まずはこの関数を
読み込みます
参考: foreachでprogressbarを表示する - J's blog
progress barを出す(2)
46
そして、ここに
繰り返し数(N)と
結合関数(デフォルトはc)を
入れると・・・?
progress barが表示できました!!
参考: foreachでprogressbarを表示する - J's blog
今日のまとめ
47
一歩上のR使いになるために
⇒『forを捨てよ、pforeachを書こう』
Enjoy!!
余談
• 並列対応のR
– pqR(ただし2系のRのみ)
– Microsoft R
• 高速化ライブラリ
– OpenBLAS(BLASという数値計算ライブラリ)
– Intel MKL(並列化可能な数値計算ライブラリ)
• Rcpp
– 参考
(https://www.gitbook.com/book/teuder/introducti
on-to-rcpp/details/ja)
49

More Related Content

What's hot

MCMCサンプルの使い方 ~見る・決める・探す・発生させる~
MCMCサンプルの使い方 ~見る・決める・探す・発生させる~MCMCサンプルの使い方 ~見る・決める・探す・発生させる~
MCMCサンプルの使い方 ~見る・決める・探す・発生させる~
. .
 
パターン認識 04 混合正規分布
パターン認識 04 混合正規分布パターン認識 04 混合正規分布
パターン認識 04 混合正規分布
sleipnir002
 

What's hot (20)

マルコフ連鎖モンテカルロ法 (2/3はベイズ推定の話)
マルコフ連鎖モンテカルロ法 (2/3はベイズ推定の話)マルコフ連鎖モンテカルロ法 (2/3はベイズ推定の話)
マルコフ連鎖モンテカルロ法 (2/3はベイズ推定の話)
 
PRML第6章「カーネル法」
PRML第6章「カーネル法」PRML第6章「カーネル法」
PRML第6章「カーネル法」
 
Granger因果による 時系列データの因果推定(因果フェス2015)
Granger因果による時系列データの因果推定(因果フェス2015)Granger因果による時系列データの因果推定(因果フェス2015)
Granger因果による 時系列データの因果推定(因果フェス2015)
 
関数データ解析の概要とその方法
関数データ解析の概要とその方法関数データ解析の概要とその方法
関数データ解析の概要とその方法
 
「内積が見えると統計学も見える」第5回 プログラマのための数学勉強会 発表資料
「内積が見えると統計学も見える」第5回 プログラマのための数学勉強会 発表資料 「内積が見えると統計学も見える」第5回 プログラマのための数学勉強会 発表資料
「内積が見えると統計学も見える」第5回 プログラマのための数学勉強会 発表資料
 
Dimensionality reduction with t-SNE(Rtsne) and UMAP(uwot) using R packages.
Dimensionality reduction with t-SNE(Rtsne) and UMAP(uwot) using R packages. Dimensionality reduction with t-SNE(Rtsne) and UMAP(uwot) using R packages.
Dimensionality reduction with t-SNE(Rtsne) and UMAP(uwot) using R packages.
 
pymcとpystanでベイズ推定してみた話
pymcとpystanでベイズ推定してみた話pymcとpystanでベイズ推定してみた話
pymcとpystanでベイズ推定してみた話
 
15分でわかる(範囲の)ベイズ統計学
15分でわかる(範囲の)ベイズ統計学15分でわかる(範囲の)ベイズ統計学
15分でわかる(範囲の)ベイズ統計学
 
PCAの最終形態GPLVMの解説
PCAの最終形態GPLVMの解説PCAの最終形態GPLVMの解説
PCAの最終形態GPLVMの解説
 
4 データ間の距離と類似度
4 データ間の距離と類似度4 データ間の距離と類似度
4 データ間の距離と類似度
 
ようやく分かった!最尤推定とベイズ推定
ようやく分かった!最尤推定とベイズ推定ようやく分かった!最尤推定とベイズ推定
ようやく分かった!最尤推定とベイズ推定
 
質的変数の相関・因子分析
質的変数の相関・因子分析質的変数の相関・因子分析
質的変数の相関・因子分析
 
「統計的学習理論」第1章
「統計的学習理論」第1章「統計的学習理論」第1章
「統計的学習理論」第1章
 
時系列予測にTransformerを使うのは有効か?
時系列予測にTransformerを使うのは有効か?時系列予測にTransformerを使うのは有効か?
時系列予測にTransformerを使うのは有効か?
 
変分ベイズ法の説明
変分ベイズ法の説明変分ベイズ法の説明
変分ベイズ法の説明
 
MCMCサンプルの使い方 ~見る・決める・探す・発生させる~
MCMCサンプルの使い方 ~見る・決める・探す・発生させる~MCMCサンプルの使い方 ~見る・決める・探す・発生させる~
MCMCサンプルの使い方 ~見る・決める・探す・発生させる~
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)
 
RでGPU使ってみた
RでGPU使ってみたRでGPU使ってみた
RでGPU使ってみた
 
パターン認識 04 混合正規分布
パターン認識 04 混合正規分布パターン認識 04 混合正規分布
パターン認識 04 混合正規分布
 
楽しい研究のために今からできること 〜新しく研究を始める皆さんへ〜
楽しい研究のために今からできること 〜新しく研究を始める皆さんへ〜楽しい研究のために今からできること 〜新しく研究を始める皆さんへ〜
楽しい研究のために今からできること 〜新しく研究を始める皆さんへ〜
 

Similar to Rによる高速処理 まだfor使ってるの?

位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
Yoshiyuki Asaba
 
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
Nagi Teramo
 
Continuous delivery 6
Continuous delivery 6Continuous delivery 6
Continuous delivery 6
ShinyaOzawa
 
pythonでオフィス快適化計画
pythonでオフィス快適化計画pythonでオフィス快適化計画
pythonでオフィス快適化計画
Kazufumi Ohkawa
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編
Miki Shimogai
 
Logをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組みLogをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組み
Ken Morishita
 

Similar to Rによる高速処理 まだfor使ってるの? (20)

位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
 
Tokyo r30 beginner
Tokyo r30 beginnerTokyo r30 beginner
Tokyo r30 beginner
 
Tokyo r38
Tokyo r38Tokyo r38
Tokyo r38
 
第9回ACRiウェビナー_日立/島田様ご講演資料
第9回ACRiウェビナー_日立/島田様ご講演資料第9回ACRiウェビナー_日立/島田様ご講演資料
第9回ACRiウェビナー_日立/島田様ご講演資料
 
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
 
Continuous delivery 6
Continuous delivery 6Continuous delivery 6
Continuous delivery 6
 
SVM実践ガイド (A Practical Guide to Support Vector Classification)
SVM実践ガイド (A Practical Guide to Support Vector Classification)SVM実践ガイド (A Practical Guide to Support Vector Classification)
SVM実践ガイド (A Practical Guide to Support Vector Classification)
 
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
MySQLメインの人がPostgreSQLのベンチマークをしてみた話MySQLメインの人がPostgreSQLのベンチマークをしてみた話
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
 
Capistrano in practice - WebCareer
Capistrano in practice - WebCareerCapistrano in practice - WebCareer
Capistrano in practice - WebCareer
 
Fundamentals of Relational Database Management Systems chapter19
Fundamentals of Relational Database Management Systems chapter19Fundamentals of Relational Database Management Systems chapter19
Fundamentals of Relational Database Management Systems chapter19
 
MySQLチューニング
MySQLチューニングMySQLチューニング
MySQLチューニング
 
とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)
 
Using Deep Learning for Recommendation
Using Deep Learning for RecommendationUsing Deep Learning for Recommendation
Using Deep Learning for Recommendation
 
pythonでオフィス快適化計画
pythonでオフィス快適化計画pythonでオフィス快適化計画
pythonでオフィス快適化計画
 
2019年度 若手技術者向け講座 DBMSの機能
2019年度 若手技術者向け講座 DBMSの機能2019年度 若手技術者向け講座 DBMSの機能
2019年度 若手技術者向け講座 DBMSの機能
 
Hiroshimar4_Rintro
Hiroshimar4_RintroHiroshimar4_Rintro
Hiroshimar4_Rintro
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編
 
Logをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組みLogをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組み
 
Deep Learningハンズオン勉強会「Caffeで画像分類を試してみようの会」
Deep Learningハンズオン勉強会「Caffeで画像分類を試してみようの会」Deep Learningハンズオン勉強会「Caffeで画像分類を試してみようの会」
Deep Learningハンズオン勉強会「Caffeで画像分類を試してみようの会」
 
Oracle Cloud Developers Meetup@東京
Oracle Cloud Developers Meetup@東京Oracle Cloud Developers Meetup@東京
Oracle Cloud Developers Meetup@東京
 

Rによる高速処理 まだfor使ってるの?

Editor's Notes

  1. #### library(dplyr) cl <- makeCluster(3) registerDoParallel(cl) foreach(i = 1:150, .packages = "dplyr") %dopar% { iris[i, ] %>% select(-Species) %>% sum } stopCluster(cl) #### square <- function(x) x**2 execute <- function() { cl <- makeCluster(3) registerDoParallel(cl) foreach(i = 1:150, .export = "square") %dopar% { square(i) } stopCluster(cl) } execute() #### library(foreach) library(doParallel) cl <- makeCluster(3) registerDoParallel(cl) foreach(i = 1:3) %dopar% { sqrt(i) } stopCluster(cl) #### library(pforeach) pforeach(i=1:3) ({ sqrt(i) }) #### pforeach(i = 1:3, .c = c) (sqrt(i)) pforeach(i = 1:3, .c = list) (sqrt(i)) pforeach(i = 1:3, .c = rbind) (sqrt(i)) #### pforeach(i = 1:3) (sqrt(i)) pforeach(i = 1:3, .parallel = FALSE) (sqrt(i)) npforeach(i = 1:3) (sqrt(i)) #### pforeach(i=1:3, .cores = 2) ({ i ** 2 }) #### pforeach(i=1:3, .seed = 71) ({ i ** 2 }) #### library(foreach) library(kernlab) library(randomForest) library(doParallel) data(spam) cores <- detectCores() cl <- makePSOCKcluster(cores) registerDoParallel(cl) fit.rf <- foreach(ntree = rep(250, cores), .combine = combine, .export = "spam", .packages = "randomForest") %dopar% { randomForest(type ~ ., data = spam, ntree = ntree) } stopCluster(cl) #### library(pforeach) library(kernlab) library(randomForest) data(spam) fit.rf <- pforeach(ntree = rep(250, .cores), .c = combine) ({ randomForest(type ~ ., data = spam, ntree = ntree) }) #### pb <- function(N, FUN = c) { pbar <- txtProgressBar(min = 2, max = N, style = 3) count <- 0L if(is.character(FUN)) { FUN <- get(FUN) } function(...) { count <<- count + length(list(...)) - 1L setTxtProgressBar(pbar, count) if(count == (N-1)) { cat("\n") } FUN(...) } } #### N <- 10000 pforeach(i = 1:N, .combine = pb(N), .multicombine = TRUE) ({ sqrt(i) })[1:10]