本記事は R Advent Calendar 2016 に参加しています。
Azure Machine Learning(Azure ML)を使うと、分析処理を容易に WebAPI 化することができて便利です。分析モジュールは細分化することができ、 R や Python で処理を記述することができます。 R Advent Calendar なのでもちろん R の話です。
R で処理を行う際に、自作他作問わず様々なパッケージを導入する必要がありますが、 Azure ML だとパッケージの導入は少し手間がかかります。というのは Azure ML の分析モジュールではインターネットアクセスを行うことができず、 `install.packages` 関数や `devtools` パッケージの install 系関数では単純にパッケージをインストールすることができないからです。
ではどうするかというと、パッケージを CRAN と同じディレクトリー構造で Windows バイナリーパッケージを配置し(後述)、それを zip ファイルにまとめて DATASETS にアップロードします。アップロードした zip ファイルは、下図のようにして expreriment のモジュールとして R モジュールに渡します。
zip ファイルは C ドライブの src フォルダーに展開されますので、 R スクリプトから参照することができ、以下のようなコードでパッケージをインストールできます。
repos_uri <- "file:///C:/src/myrepos" install.packages("mypackage", repos = repos_uri)
さて、 CRAN と同じディレクトリー構造でパッケージを配置するにはどうするか、というところで登場するのが、題名にもある miniCRAN パッケージです。名前の通り、小さな CRAN みたいなもの(ローカルリポジトリー)を作ることができ、今回の目的である CRAN と同じディレクトリー構造でパッケージを配置することを容易にします。
使い方は簡単で、以下のようにパッケージ名のベクトルを `makeRepo` 関数に与えるだけです。
library(miniCRAN) pkg_list <- c("dplyr", "tidyr") makeRepo( pkg_list, path = "myrepos", download = TRUE, type = "win.binary", Rversion = "3.1.0" )
ここで重要なのは、 `type = "win.binary"` と `Rversion = "3.1.0"` です。 Azure ML は Windows 上の R 3.1.0 で動作するため、 OS と R のバージョンを明示的に指定する必要があります。ちなみに R のバージョンは CRAN の R 3.1.0 の他に、 Microsoft R Open 3.2.2 も選ぶことができ、どちらを選ぶかによって `makeRepo` 関数に指定する `Rversion` のバージョンも変更します。ローカルリポジトリー内はディレクトリー構造でバージョンを分けているので、両バージョンが混在したローカルリポジトリーを作成することもできます。
miniCRAN パッケージには、パッケージの依存関係を解決するための関数も用意されており、自作関数を使った分析モジュールを作る場合には、必要最低限のパッケージを選択してローカルリポジトリーを作ることも簡単にできます。
私は Azure ML にアップロードする独自パッケージを作成する際に、以下のような感じのスクリプトを利用して、 Windows 上で Azure ML にアップロードするローカルリポジトリーの zip ファイルを作成しています。 zip コマンドは Rtools に付属しているものにパスを通して利用しています。
library(magrittr) # 3.1.0: CRAN R # 3.2.2: Microsoft R Open AZUREML_R_VERSION <- "3.1.0" PACKAGE_NAME <- "mypackage" # 最初からインストールされているパッケージ DEFAULT_PACKAGES <- c("base", "methods", "utils", "grDevices", "graphics", "stats", "datasets") ## 依存関係とバージョンを取得するためにインストール binary_package <- devtools::build(binary = TRUE) install.packages(binary_package, repos = NULL, type = "binary") PACKAGE_VERSION <- installed.packages()[PACKAGE_NAME, "Version"] REPO_PATH <- "myrepos" PACKAGE_ZIP <- sprintf("%s.zip", REPO_PATH) ## 依存パッケージ pkgs <- miniCRAN::pkgDep(PACKAGE_NAME, installed.packages(), recursive = TRUE) %>% unlist() %>% unique() %>% setdiff(DEFAULT_PACKAGES) pdb <- miniCRAN::pkgAvail(Rversion = AZUREML_R_VERSION) deps <- miniCRAN::pkgDep(pkgs, availPkgs = pdb) ## CRAN リポジトリ作成 if (dir.exists(REPO_PATH)) { unlink(REPO_PATH, recursive = TRUE, force = TRUE) } dir.create(REPO_PATH, recursive = TRUE) miniCRAN::makeRepo(deps, path = REPO_PATH, download = TRUE, type = "win.binary", Rversion = AZUREML_R_VERSION) ## 独自パッケージを追加 minor_version <- sub("^(\\d+\\.\\d+)\\D*.*$", "\\1", AZUREML_R_VERSION) dest <- file.path(REPO_PATH, "bin", "windows", "contrib", minor_version, basename(binary_package)) file.rename(binary_package, dest) ## CRAN のアップデート miniCRAN::updateRepoIndex(REPO_PATH, type = "win.binary", Rversion = AZUREML_R_VERSION) ## zip 作成 zip(PACKAGE_ZIP, REPO_PATH)
まとめ
Azure ML でパッケージを利用するには、ローカルリポジトリーを作成する必要があります。ローカルリポジトリーの作成には miniCRAN パッケージが便利です。