• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
データサイエンスワールドからC++を眺めてみる
 

データサイエンスワールドからC++を眺めてみる

on

  • 1,541 views

 

Statistics

Views

Total Views
1,541
Views on SlideShare
1,425
Embed Views
116

Actions

Likes
7
Downloads
10
Comments
0

1 Embed 116

https://twitter.com 116

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    データサイエンスワールドからC++を眺めてみる データサイエンスワールドからC++を眺めてみる Presentation Transcript

    • データサイエンスワールドから C++を眺めてみる 2014年3⽉1⽇ Boost.勉強会#14 @sfchaos
    • ⾃⼰紹介  TwitterID:@sfchaos  お仕事:データマイニング  普段の使⽤⾔語:R,Python,Perl,シェル 1
    • アジェンダ 1. 2. 3. 4. イントロダクション RからC++を使ってみる C++での統計解析 まとめ 2
    • 1. イントロダクション 3
    • 最近モテモテの データサイエンティスト 出典:http://markezine.jp/article/detail/18435 4
    • データサイエンティストたちは どんなツールを使っている? 5
    • 1位  2位  3位  C/C++は9位 Top Languages for analytics, data mining, data science 6
    •  データ分析では分析仕様が初めから決まっているとは限らず, 探索的に分析してデータの特徴を明らかにすることが重要.  また,分析結果を分かりやすく可視化できる環境が必要.  こうした観点から,RやPython等が分析ツールとして⽤いら れることが多い. 7
    • RからPythonへの流れも?? データ・サイエンスのプログラミング⾔語はRからPythonに置き換わる 8
    •  ⼀⽅で,特にRは処理が遅い. • ループ処理など  そのため,RからC++を呼んで処理を⾼速化することは,  結構よく⾏われる.  また,C++からRの関数を呼び,統計処理を⾏わせる⽅法 もある.  というわけで,今⽇は誰得?な話をします(^^; 9
    • 2. RからC++を使ってみる C++ 10
    • 2.1 Rcppパッケージ  RからC++を実⾏するためのパッケージ.  以下のような多くのライブラリとの連携機能も提供. • • • • Eigen(線形代数演算) GSL(科学技術計算) Numpy(科学技術計算,Python) Octave(科学技術計算) etc. 11
    • 2.2 フィボナッチ数列 fibonatti.cpp #include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] int fibCpp(const int n) { if (n < 2) { return n; } else { return fibonacci(n-1) + fibonacci(n-2); } } 12
    • 2.2 フィボナッチ数列 $ R > install.packages("Rcpp") > library(Rcpp) > sourceCpp("fibCpp.cpp") > fibCpp(20) [1] 6765 13
    • 2.2 フィボナッチ数列  Rで実⾏した場合に⽐べて,約1,000倍のスピードアップ. > sourceCpp("fibCpp.cpp") > benchmark(fibCpp(20), fibR(20), replications=5000)[, 1:4] test replications elapsed relative 2 fibR(20) 5000 200.434 756.355 1 fibCpp(20) 5000 0.265 1.000 参考:@teramonagi Tokyo.R ⽩熱教室「これからのRcppの話をしよう」 14
    • 3. C++での統計解析 C++ 15
    • 3.1 C++での統計処理  取り急ぎ調べたところ,以下のライブラリなどがある模様.  良いライブラリがあったら教えてください(^^; ライブラリ 記述統計量 統計的検定 多変量解析 機械学習 ○ × × × Apophenia ○ ○ △ △ ROOT △ △ △ △ GSL △ ×(?) △ ×(?) ALGLIB ○ ○ ○ △ Boost. Accumulators ○:多くの⼿法を提供 △:少数の⼿法を提供 ×:⾮提供 16
    • 3.2 Boost.Accumulators  統計量の計算などの統計処理を提供.  最⼩値,平均値,中央値,最⼤値  共分散  密度  合計値 等  詳細は,BoostJpの逆引きリファレンスを参照.   https://sites.google.com/site/boostjp/tips 17
    • 3.2 Boost.Accumulators  boost::accumulators::accumulator_setというコンテ ナにデータを⼊⼒.  テンプレートパラメータに実⾏する処理を指定(統計量計算) #include <iostream> #include <boost/accumulators/accumulators.hpp> #include <boost/accumulators/statistics.hpp> using namespace boost::accumulators; int main() { accumulator_set<double, stats<tag::min, tag::mean, tag::sum> > acc; acc(3.0); acc(1.0); acc(4.0); acc(2.0); acc(5.0); } std::cout << extract::min(acc) << std::endl; // 最小値 std::cout << extract::mean(acc) << std::endl; // 平均値 std::cout << extract::sum(acc) << std::endl; // 合計値 18
    • 3.2 Boost.Accumulators  std::vectorや配列などのコンテナに格納されたデータに対し ては,for_eachを使⽤してaccumulator_setに代⼊. #include <iostream> #include <boost/array.hpp> #include <boost/range/algorithm/for_each.hpp> #include #include #include #include <boost/bind.hpp> <boost/ref.hpp> <boost/accumulators/accumulators.hpp> <boost/accumulators/statistics.hpp> using namespace boost::accumulators; int main() { int ar[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; accumulator_set<double, stats<tag::min, tag::mean, tag::max> > acc; boost::for_each(ar, boost::bind(boost::ref(acc), _1)); std::cout << extract::min(acc) << std::endl; // 最小値 std::cout << extract::mean(acc) << std::endl; // 平均値 std::cout << extract::max(acc) << std::endl; // 最大値 } return 0; 19
    • 3.3 ALGLIB  数値計算およびデータ処理のためのソフトウェア.  C++, C#, Python, VBAなど多くのプログラミング⾔語から 呼び出せる.  商⽤版もあり,マルチスレッドIntel Math Kernel Library を⽤いた最適化・⾼速化等に対応 20
    • 3.3 ALGLIB #include <iostream> #include "statistics.h" using namespace std; using namespace alglib; int main() { real_1d_array x = "[0,1,4,9,16,25,36,49,64,81]"; real_1d_array y = "[0,1,2,3,4,5,6,7,8,9]"; double v; ナゾの値の代⼊⽂ cout.precision(8); // 共分散 v = cov2(x, y); cout << "共分散: " << double(v) << endl; // Pearson 相関係数 v = pearsoncorr2(x, y); cout << "Pearson 相関係数: " << double(v) << endl; // Spearman 相関係数 v = spearmancorr2(x, y); cout << "Spearman 相関係数: " << double(v) << endl; return 0; } 21
    • 3.4 C++からRの呼び出し  RInsideというパッケージを⽤いることにより,C++からRを呼 び出せる. 22
    • 3.4.1 式の評価 #include <RInside.h> int main(int argc, char *argv[]) { RInside R(argc, argv); R["x"] = 10 ; R["y"] = 20 ; // C++に埋め込むRのインスタンスの⽣成 // Rのインスタンスにオブジェクトの名前と値を代⼊ R.parseEvalQ("z <- x + y") ; // Rでの評価式 int sum = R["z"]; // []演算⼦でオブジェクトの値を取得 std::cout << "10 + 20 = " << sum << std::endl ; // 以下の⽅法で評価してもO.K. sum = R.parseEval("x + y") ; std::cout << "10 + 20 = " << sum << std::endl ; exit(0); } 以下のRInlineパッケージのソースのinst/examples/standard/rinside_sample8.cpp http://cran.r-project.org/src/contrib/RInside_0.2.11.tar.gz 23
    • Makefile 3.4.1 式の評価 ## -*- mode: make; tab-width: 8; -*R_HOME := $(shell R RHOME) sources := programs := $(wildcard *.cpp) $(sources:.cpp=) ## Rのためのヘッダやライブラリ RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) ## Rcppのヘッダやライブラリ RCPPINCL := $(shell echo 'library(Rcpp, lib.loc="/home/sfchaos/lib/R");Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'library(Rcpp, lib.loc="/home/sfchaos/lib/R");Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'library(RInside, lib.loc="/home/sfchaos/lib/R");RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'library(RInside, lib.loc="/home/sfchaos/lib/R");RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) 24
    • Makefile(続 ) 3.4.1 式の評価 ## makeするための各種のルール CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) all: $(programs) @test -x /usr/bin/strip && strip $^ run: $(programs) @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done clean: rm -vf $(programs) rm -vrf *.dSYM runAll: for p in $(programs); do echo ""; echo ""; echo "Running $$p"; ./$$p; done 25
    • 3.4.1 式の評価 $ make rinside_sample8.cpp $ ./rinside_sample8 10 + 20 = 30 10 + 20 = 30 26
    • lm.cpp 3.4.2 回帰分析 #include <RInside.h> int main(int argc, char *argv[]) { RInside R(argc, argv); // C++ 埋 込 R 生成 std::vector<double> x; x.push_back(1.0); x.push_back(2.0); x.push_back(3.0); R["x"] = x; std::vector<double> y; y.push_back(2.0); y.push_back(4.0); y.push_back(6.0); R["y"] = y; // R 回帰分析 実行(y = 2*x) R.parseEvalQ("fit.lm <- lm(y ~ x); fit.lm.coef <- fit.lm$coef"); std::vector<double> coef; coef = R["fit.lm.coef"]; // 回帰係数 取得 std::cout << "傾 : " << coef[1] << std::endl; std::cout << "切片: " << coef[0] << std::endl; } return 0; 27
    • 3.4.2 回帰分析 $ make lm g++ -I/usr/local/lib/R/include -I/home/sfchaos/lib/R/Rcpp/include I/home/sfchaos/lib/R/RInside/include -g -O2 -Wall I/usr/local/include lm.cpp -L/usr/local/lib/R/lib -lR L/usr/local/lib/R/lib -lRblas -L/usr/local/lib/R/lib -lRlapack L/home/sfchaos/lib/R/RInside/lib -lRInside -Wl,rpath,/home/sfchaos/lib/R/RInside/lib -o lm $ ./lm 傾き: 2 切⽚: -0 28
    • 3.4.3 Qtへの埋め込み  QtにRを埋め込むことも可能.  詳細は以下を参照.   R inside Qt: A simple RInside application パラメータを変えて 計算を実⾏ 29
    • 4. まとめ 30
    •  R ⇔ C++の誰得な発表. • R ⇒ C++: Rcpp • C++ ⇒ R: RInside  C++で統計解析を⾏うための良いツールがあれば,       是⾮教えてください. 31