タグ別アーカイブ: R

H2OとRでグリッドサーチする

H2Oはグリッドサーチを使うことでハイパーパラメータの探索をある程度、効率的にできます。Rを使った場合のグリッドサーチの書き方を説明します。

grid <- h2o.grid(
  algorithm = "<アルゴリズム名>",
  x = <説明変数リスト>,
  y = <目的変数>,
  training_frame = <訓練集合>,
  validation_frame = <評価集合>,

  hyper_params = list(
     <ハイパーパラメータのリスト>
  )
)

GBMなどはそうハイパーパラメータの数が多くないので学習をただ繰り返してもいいのですが、Deep Learningなどはハイパーパラメータも多いのでグリッドサーチがないとチューニングが現実的ではなくなります。

Azure ML上のRにおける状態空間法でのアクセス解析

3月の.NETラボ勉強会で『Azure ML上のRにおける状態空間法でのアクセス解析』のタイトルでLTに登壇しました。

 

AzureMLでfitdistrplusを使った確率分布の推定

ここでは確率分布の種類は既知のものとして、データから確率分布のパラメータの推定を行う過程を紹介する。Azure MLでは当該機能は機能セットとしては提供していないため、Rで実装されているfitdistrplusを用いて行う。
サンプルデータとしてパラメータが既知の分布を基づいて乱数を生成し、その乱数をデータとしてパラメータの推定を行う。この場合のML StudioでのExperimentを下記図に示す。

Experiment for Estimation Parameters

Experiment for Estimation Parameters

Figure 1は2つのRスクリプトで構成されている。このスクリプトを下記Source 1およびSource 2に示す。Source 1はサンプルデータの生成を行うスクリプトで、Source 2がデータに基づき分布の推定を行うスクリプトである。

maml.mapOutputPortおよび、maml.mapInputPortはAzure MLのRにおける固有の関数でデータの受け渡しを行う関数である。アウトプットされたグラフィックスは既定で特定の割り当てがなされるので特に実装を行わなくてもPNGフォーマットで取得することができる。出力結果を以下のEstimate Resultに示す。

# Create Data Set
data.set
Source 1: Data Generate
# Load required packages
library(fitdistrplus)

# load data frame
data.set
Source 2: Parameter Estimation
Estimate Result

Estimate Result


データサイエンティスト養成読本 R活用編

いささか、旧聞にはなるが上記、書籍を書いておきます。基本的には前に刊行されたムックの続きでRなどにフォーカスしたムックです。R活用編となってはいますが、商業書籍では珍しいJuliaの入門記事やRを.NET環境から利用するR.NETの記事など割と面白いものになっています。特にR.NETを含めた.NETのライブラリ群の配布は現在はNuGetであることは.NETの開発者の諸兄には自明なのですが、意外と気づかない向きもありますので書いておきます。

さて、私の目的はJuliaの入門記事であったわけですが、文法の解説に関しては割りとしっかり書かれているように思われます。とはいえ、ムックの一セクションなので食い足りないのも確かです。書籍ベースだと後は洋書の”Seven More Languages in Seven Weeks: Languages That Are Shaping the Future”と先に書評を書いた、同人誌の実例で学ぶJulia言語入門 v0.3.3/v0.4.0-dev 対応版あたり。

Rで指数表記 (Scientific Notification)を抑止する

Rで指数表記されるのを抑止するには、変数に対してformat(variable, scientific = FALSE)を実行します。例えば、データフレーム中の特定の変数X1について指数表記を抑止するには以下のようなコードとなります。

df$X1 <- format(df$X1, scirntific = FALSE)

Rと他のプログラム間でデータを移動させるとき、プログラムによっては指数表記を解釈できない場合があります。特にCSVでデータをエクスポートする場合にありえるかと思います。

Azure Machine Learning #00

はじめに

Azure Machine LearningもGA (一般提供)を向かえ、注目を集めているようです。ここで、Azure Machine Learningとは何か、そして、どう使って行くかをまとめて行きたいと思います。Azure Machine Learningは洗練されたUIを持ち、ユーザインターフェイスとしてなら使用は容易です。しかし、機械学習の基本的なスキルなしに使うことは容易くはありません。この辺は機械学習の側面をかなり遮蔽しBAプラットフォームとしてレポーティングを含めまとめた、IBM Watson Analyticsとは根本的に異なるところです。

逆に言うと、IBM Watson Analyticsは機械学習の仕組みを遮蔽しているために、学習結果の理由を説明するのはかなり困難です。これは、同様に学習のアプローチを見せない、Google Predictive APIも同様です。その意味では説明可能であり、モデルの中身が見えるという面白い立ち位置にあります。これは、優劣というよりも考え方の違いかと思います。当たれば良い、そしてモデルの開発に時間をかけたくないというニーズもあれば、説明可能性が重要なこともあります。ただ、技術の使い分けを考えるときには重要なファクターです。

Azure Machine Learningとは

Azure Machine LearningはMicrosoft Azureの上に構築された機械学習のPaaSプラットフォームです。基本的にはアドホックに学習モデルを作成するためのML StudioとWeb APIとして学習や予測を動かすためのAPI群からなります。使用可能なモデルはMicrosoftが用意したプロプライエタリなモデルとR及びPythonが使用可能です。

ML Studioでのモデリングは有効グラフでビルディングブロックのデータフローを結線していく、SPSS Modelerや各種ETLツールで見かける形式を採用しています。この方式はデータフローが確認しやすくモデリングの仕組みを把握しやすい優れた方法です。PythonやRはビルディングブロックにスクリプトを記載する方法です。これは、R Analytics Flowと同様でスキルセットを活用しやすいと思います。

データは現時点においてはAzureのBLOB StorageもしくはSQL ServerのDBaaSであるSQL Databaseが利用できます。BLOB Storageにアウトプットすることで同じAzureのData Factoryをデータ加工プラットフォームとして活用できます。また、Machine LearningのアウトプットをBLOB Storageにして、ExcelやPower BIといったBIプラットフォームを活用し世間的な言い方ではBAプラットフォームの一部として活用できます。また、Web APIとして展開することで多くのツールからアクセス可能であると思います。

今回、GAを迎え、料金体系もプレビューのときとは一新しています。特徴は無料とStandardの2つに料金体系が分かれたことです。無料の側はWeb APIの利用に制限があり、また、モデリングの連続実行時間に時間制約があることデータサイズに上限があること、またSLAが保障されず、スケジューリングの優先順位が高くないこと、などの制約がありますがデータサイズは10GBとゆるく無料でもかなりのことができます。また、使用可能なモデルにも制約はありません。(2015/02/20 現在)

Cox Proportional Hazards Model on Azure Machine Learning with R

このアーティクルはTokyo-Rでのプレゼンをベースに書き起こしたものになります。

本アーティクルではCox回帰を例題に説明を行いますが、一般化線形回帰のときのケースは.NET ラボの7月のLTでやっておりますので、Azure Machine Learningのアーティクルをご活用ください。

Microsoft Azure プラットフォーム上に構築された機械学習のためのPaaSであるAzure Machine Learningを使って、Cox回帰をやってみます。Azure Machine Learningの環境はML Studioというもので完全にWebベースでモダンブラウザなら大方のブラウザで操作できます。環境のスクリーンショットを示します。

ML Studio Screen shot

Azure Machine LearningはMicrosoftのプロプライエタリなビルディングブロックとRベースの分析環境の複合で実現されています。プロプライエタリなビルディングブロックにはSVMなど多くの分析手法が実装されていますが、生存時間など実装されていないモデルもたくさんあります。

まず、生存時間分析を実施する場合、データ量が大きくなると問題になるのはデータセットの準備です。生存時間分析ではイベント発生までの時間が必要になりますから、データを走査してイベント発生までの時間を抽出するのはわりと大変です。

さらに、その部分ができたとして、実際に適正なモデルを得るにはクロスバリデーションなどを含め考える必要があります。

今回はRの標準的な配布の中に含まれるsurvivalを使うので問題はありませんが、パッケージをインストールしなければならない場合には、ちっと対応が要ります。基本的にはパッケージ及び依存先を上げておいて、明示的にローカルからinstall.packageします。

Rに組み込まれているデータセット kidneyをエクスポートして、Azure Machine Learningでモデリングする例を示します。

この場合のExecute R Script ブロックに書くコードを示します。

library(survival)

kidney <- maml.mapInputPort(1) # class: data.frame

kidney.cox <- coxph( Surv(time, status) ~ sex+disease, data=kidney) 
kidney.fit <- survfit(kidney.cox)

plot(kidney.fit)

mamlというのはAzure Machine Learningで組み込まれているパッケージで自動的に読み込まれます。mapInputPortはデータの読み込みに使う関数でブロックへの入力データをデータフレームとして吐き出します。plotなどの作図は何も書かなくてもブロックからの出力に含まれるのでこのような単純な例ではRのコード側での対応は要りません。また、先の線形回帰の例で示していますが、データフレームを出力するとデータとして拾えます。

Chart of survival

今回の例ではデータセットが小さいため、全データをそのままモデリングしていることもあり、特に考慮していませんが。大きなデータで複数のセットを作って、学習を進める場合には複数のExecute R Scriptブロックを用いて、Azure ML側のデータの分割などの機能セットを使ったほうがよいと思われます。

また、データを走査してのイベント発生日の検出にはHDInsightに含まれる、Hadoop環境で行うのもありえるでしょう。

また、モデルそのものの適用については Azure Machine Learningでは実行環境をAPI化する機能をサポートしているのでRServeとかを考えなくても展開ができます。とはいえ、これでポンだけでは結局、predictを叩いているのと差がないのでもうちっとあがいてみます。車輪の再発明とも言いまが。

生存時間そのものは以下のようなモデルです。

h(t)=\lim_{\Delta t \to 0} \frac{S(t)-S(t - \Delta t)}{\Delta t} \cdot \frac{1}{S(t)}
H(t)=\int_0^{t} h(t)du=-\log S(t)
h(t)=h_0(t) \cdot \mathrm{e}^{(\alpha + \beta_{1} X_{1} + \beta_{2} X_{2} + \ldots + \beta_{p} X_{p})} = h_0(t) \cdot RISK

従って、時間を無視してパラメトリックに表されたリスクの効き具合だけを単純に議論するならば、係数を説明変数かけて合計してエクスポネンシャルするのと同じです。ただし、Rのcoxphでは説明変数は内部で平均を引き算して用いているので適用する場合にはそこも実装しないと同じ値にはなりません。適用をC#で実装した事例はC#によるCox回帰の適用の実装で書いたのでご確認ください。

Rのwrite.csvではcol.namesが使えない

write.tableではcol.namesオプションがあり、変数名を出力せずにアウトプットができます。しかし、write.csvでは明示的にcol.namesオプションが殺されており、col.namesは指定できません。
これは、write.csvのソースコードを確認するとはっきりとします。

function (...) 
{
    Call <- match.call(expand.dots = TRUE)
    for (argname in c("append", "col.names", "sep", "dec", "qmethod")) if (!is.null(Call[[argname]])) 
        warning(gettextf("attempt to set '%s' ignored", argname), 
            domain = NA)
    rn <- eval.parent(Call$row.names)
    Call$append <- NULL
    Call$col.names <- if (is.logical(rn) && !rn) 
        TRUE
    else NA
    Call$sep <- ","
    Call$dec <- "."
    Call$qmethod <- "double"
    Call[[1L]] <- as.name("write.table")
    eval.parent(Call)
}

中を見れば判るとおり、col.namesを使えないようにしています。元々、write.csvはwrite.tableのサブセットであり、いくつかのパラメータを既定値としてセットしたものとしてデザインされています。よって、その範囲外の使い方をするには大本のwrite.tableを使うようになっています。