Execute RモジュールでPlotしたグラフをPDFファイルで出力する
Microsoft AzureのMachine Learningで、Rプログラムでグラフを作成し、
作成したグラフをPDFファイルとして取得してみます。
azure.microsoft.com
ゴール
イカサマサイコロを2個振って、出た目の合計ヒストグラムを
PDFファイルでダウンロードできるようにします。
mukkujohn.hatenablog.com
流れ
- Rスクリプトを利用してヒストグラムを作成し、PDFファイルとして出力する
- Base64エンコードした文字列を持つファイルをAzure Blob Storageに保存
- ファイル内のBase64文字列から、バイト配列を取得し返す
Azure Machine Learning
Azure Machine Learningで使用するModuleは2つです。
- Execute R Script Module
- Export Data Module
Execute R Script Module
Execute R Script ModuleのPropertiesはこうなっています。
このR Script PropertyにRスクリプトを記述します。
library(ggplot2) roll <- function() { die <- 1:6 dice <- sample(die, 2, replace = 2, prob = c(1 / 8, 1 / 8, 1 / 8, 1 / 8, 1 / 8, 3 / 8)) sum(dice) } pdf() rolls <- replicate(10000, roll()) qplot(rolls, binwidth = 1) dev.off() library(caTools) b64ePDF <- function(filename) { maxFileSizeInBytes <- 5 * 1024 * 1024 # 5 MB return(base64encode(readBin(filename, "raw", n = maxFileSizeInBytes))) } d2 <- data.frame(pdf = b64ePDF("Rplots.pdf")) maml.mapOutputPort("d2");
イカサマサイコロを2個振って、出た目を合計する
過去記事で作成した、roll関数をそのまま利用します。
roll <- function() { die <- 1:6 dice <- sample(die, 2, replace = 2, prob = c(1 / 8, 1 / 8, 1 / 8, 1 / 8, 1 / 8, 3 / 8)) sum(dice) }
ヒストグラムをPDFファイルとして出力
pdf関数で始まり、dev.offで閉じます。
pdf() rolls <- replicate(10000, roll()) qplot(rolls, binwidth = 1) dev.off()
PDFファイルをBase64エンコードして出力
ここは、このページのWrite a Graphics File部分をそのまま頂きます。
Execute R Script
library(caTools) b64ePDF <- function(filename) { maxFileSizeInBytes <- 5 * 1024 * 1024 # 5 MB return(base64encode(readBin(filename, "raw", n = maxFileSizeInBytes))) } d2 <- data.frame(pdf = b64ePDF("Rplots.pdf")) maml.mapOutputPort("d2");
Export Data Module
Export Data ModuleのPropertiesです。
RUN
ここまで設定できたら、RUNして確認してみます。
緑色のチェックが付いたので、Blob Storage側を確認します。
Export Data ModuleのPropertyで指定したファイルができています。
ファイルの取得、デコード、ダウンロード
Azure Blob StorageをC#コードが操作するためには、このサイトを参考に進めていきます。
azure.microsoft.com
サイト内にも記載されていますが、
2つのパッケージが必要なため、GUIを使うか、パッケージマネージャコンソールからインストールします
www.nuget.org
www.nuget.org
(GUIから行いました。)
Controllerの作成
PDFファイルを出力するControllerを作成します。
RPlotControllerとしました。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.Azure; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; namespace WebApplication1.Controllers { public class RPlotController : Controller { // GET: RPlot public ActionResult Index() { var pdfData = GetPlotPDFData(); if(pdfData == null) { return View(); } return File(pdfData, "application/pdf", "RollPlot.pdf"); } private byte[] GetPlotPDFData() { // ストレージアカウントオブジェクトを作る CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); // ストレージアカウントのBlobにアクセスするクライアントを作る CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // コンテナを指すオブジェクトを作る CloudBlobContainer container = blobClient.GetContainerReference("test"); // コンテナ内のオブジェクトを順番に参照していく foreach (IListBlobItem item in container.ListBlobs(null, false)) { // ブロックブロブなら if (item.GetType() == typeof(CloudBlockBlob)) { // オブジェクトを捕まえて CloudBlockBlob blob = (CloudBlockBlob)item; // Machine Learningで出力したファイル名なら if(blob.Name.Equals("Rplots.csv")) { // blobの内容を文字列として取得して、Base64エンコード文字列としてバイト配列に変換 return Convert.FromBase64String(blob.DownloadText()); } } } return null; } } }
Viewの作成
こんな感じです。
@{ ViewBag.Title = "Top Page"; } <h1>Top Page</h1> <p>@Html.ActionLink("ダウンロード","Index","RPlot")</p>
(RPlotContollerのIndexViewは適当に作成しておいてください。)
実行
アプリケーションを実行してみます。
ダウンロードリンクをクリックすると、ファイルがダウンロードされています。
ファイルの確認
ダウンロードフォルダを確認してファイルを開いてみます。
ちゃんと開けて、意図したグラフが配置されています。
まとめ
めんどくさい手順を踏みましたが、この手順を踏めば
ggplotを利用したグラフをAzure Machine Learningで作成して、
PDFファイルとして配信や、ダウンロードさせる事ができそうです。
入力データや保存先など、Web Server Parameterなりにする必要がありますが、、、
Machine Learningのモジュールをクリックして
visualizeして確認できるグラフが出力できたらなぁ。。。