2017年5月31日水曜日

第12回 AzureMachineによるWebサービスのインターネット公開

~機械学習(Azure Machine Learning)の入門からビジネス活用へ~

~目次~ 
1.インターネットへの公開
 1.1.展開(デプロイ)する
 1.2.プログラム等からの呼出し
  1.2.1.APIキーの確認
  1.2.2.サンプルコードの取得
  1.2.3.Web上での確認①
  1.2.4.Web上での確認②
  1.2.5.Excel
  1.2.6.C#
  1.2.7.Python
   1.2.7.1.Python実行環境の構築
   1.2.7.2.Pythonスクリプトの実行
  1.2.8.R  

ブログアーカイブ 


1.     インターネットへの公開


作成した学習モデルを実際の業務で活用するためには、Azure Machine Learning内だけでなく、外部からアクセスする必要があります。Azure Machine Learningは、ユーザーが作成した実験をWebサービスとしてインターネットに展開(デプロイ)する機能を持ちます。展開された実験は、REST APIとして、C#PythonR言語などで作成されたプログラムからアクセスして、値を入力し、予測結果を取得することができます。

 

展開までのおおまかな手順を以下に示します。今回は、4回の記事で作成したクラス分類の実験をトレーニング実験として使用するため、「予測実験に変換する」の手順から説明します。

     トレーニング実験を用意する
     Webサービスとして展開する


1.1.     展開(デプロイ)する


はじめに、4回の記事で作成したクラス分類の実験を以下に示します。この実験は、「SEPAL-LENGTH」、「SEPAL-WIDTH」、「PETAL-LENGTH」、「PETAL-WIDTH」の4つの特徴量を入力して、予測された品種(CLASS)を出力するというものでした。この実験をもとに、4つの特徴量をパラメーターとして受け付けて品種を返すWebサービスを作成していきます。


 

まず、「SET UP WEB SERVICE」>「Predictive Web Service」をクリックします。


 
Webサービスとして使用する上で必要になるモジュール類が自動的に追加され、再配置されます。また、実験の名称も変更されます。




ユーザー(プログラム)が入力したデータをWeb service inputから取り出して予測を行い、結果をWeb service outputへ渡すことでユーザーへ返します。




下部のトグルスイッチを切り替えて、web service viewからexperiment viewへと変更し、RUNをクリックします。




Score Modelの下部の丸印をクリックすると現れるメニューのうち、Visualizeをクリックして、分類結果を確認します。




変換前の実験と同様の結果が出力されているかを確認します。




 
通信量を削減するために、Score ModelWeb service outputの間に、Select Columns in Datasetを挟み、Scored Labelsのみをユーザーへ出力するように変更します。除去した列のデータは、当然Webサービスを呼び出したクライアントも所有しているため、問題ないと考えられますが、並列的に大量のデータを送受信する場合等、クライアント側で状態管理を行うコストが掛かる場合は、列を除去せずに予測結果とともに返したほうが良いかもしれません。

その後、Runをクリックします。


 
Select Columns in Datasetの下部の丸印をクリックすると現れるメニューのうち、Visualizeをクリックして、Scored Labelsのみ出力されるかを確認します。




 

1.2.     プログラム等からの呼出し


1.2.1.    APIキーの確認


プログラム等から実験を呼び出すために必要な情報を確認します。

 
まず、左端のツールバーにあるWEB SERVICESをクリックします。右側の一覧の中からアクセスしたいWebサービスの名称をから選択し、クリックします。




開いたダッシュボードページにAPI keyが記載されているので、任意のテキストファイル等に控えておきます。


 

1.2.2.    サンプルコードの取得


プログラムに組み込むためのサンプルコードを取得するための手順を示します
ダッシュボードページにある、「New Web Services Experience」リンクをクリックします。


Quickstartページが表示されるので、「Use endpoint」をクリックします。


表示されたページの下部にC#PythonR言語で書かれたサンプルコードが記載されているので、それぞれテキストエディタ等にコピーアンドペーストして、ローカルPC上の任意の場所に保存しておきます。



C#

library("RCurl")

library("rjson")

 

# Accept SSL certificates issued by public Certificate Authorities

options(RCurlOptions = list(cainfo = system.file("CurlSSL", "cacert.pem", package = "RCurl")))

 

h = basicTextGatherer()

hdr = basicHeaderGatherer()

 

req = list(

    Inputs = list(

        "input1" = list(

            "ColumnNames" = list("Class", "sepal-length", "sepal-width", "petal-length", "petal-width"),

            "Values" = list( list( "0", "0", "0", "0", "0" ),  list( "0", "0", "0", "0", "0" )  )

            )

        ),

    GlobalParameters = setNames(fromJSON('{}'), character(0))

)

 

body = enc2utf8(toJSON(req))

api_key = "abc123" # Replace this with the API key for the web service

authz_hdr = paste('Bearer', api_key, sep=' ')

 

h$reset()

curlPerform(

    url = "https://ussouthcentral.services.azureml.net/workspaces/***/services/***/execute?api-version=2.0&details=true",

    httpheader=c('Content-Type' = "application/json", 'Authorization' = authz_hdr),

    postfields=body,

    writefunction = h$update,

    headerfunction = hdr$update,

    verbose = TRUE

    )

 

headers = hdr$value()

httpStatus = headers["status"]

if (httpStatus >= 400)

{

    print(paste("The request failed with status code:", httpStatus, sep=" "))

 

    # Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure

    print(headers)

}

 

print("Result:")

result = h$value()

print(fromJSON(result))

Python

import urllib2 # If you are using Python 3+, import urllib instead of urllib2

import json

 

data =  {

    "Inputs": {

        "input1": {

            "ColumnNames": ["Class", "sepal-length", "sepal-width", "petal-length", "petal-width"],

            "Values": [ [ "0", "0", "0", "0", "0" ], [ "0", "0", "0", "0", "0" ], ]

            },

        },

    "GlobalParameters": {}

    }

body = str.encode(json.dumps(data))

url = 'https://ussouthcentral.services.azureml.net/workspaces/***/services/***/execute?api-version=2.0&details=true'

api_key = 'abc123' # Replace this with the API key for the web service

headers = {'Content-Type':'application/json', 'Authorization':('Bearer '+ api_key)}

req = urllib2.Request(url, body, headers)

 

try:

    response = urllib2.urlopen(req)

 

    # If you are using Python 3+, replace urllib2 with urllib.request in the above code:

    # req = urllib.request.Request(url, body, headers)

    # response = urllib.request.urlopen(req)

 

    result = response.read()

    print(result)

except urllib2.HTTPError, error:

    print("The request failed with status code: " + str(error.code))

 

    # Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure

    print(error.info())

 

    print(json.loads(error.read()))                

R

library("RCurl")

library("rjson")

 

# Accept SSL certificates issued by public Certificate Authorities

options(RCurlOptions = list(cainfo = system.file("CurlSSL", "cacert.pem", package = "RCurl")))

 

h = basicTextGatherer()

hdr = basicHeaderGatherer()

 

req = list(

    Inputs = list(

        "input1" = list(

            "ColumnNames" = list("Class", "sepal-length", "sepal-width", "petal-length", "petal-width"),

            "Values" = list( list( "0", "0", "0", "0", "0" ),  list( "0", "0", "0", "0", "0" )  )

            )

        ),

    GlobalParameters = setNames(fromJSON('{}'), character(0))

)

 

body = enc2utf8(toJSON(req))

api_key = "abc123" # Replace this with the API key for the web service

authz_hdr = paste('Bearer', api_key, sep=' ')

 

h$reset()

curlPerform(

    url = "https://ussouthcentral.services.azureml.net/workspaces/***/services/***/execute?api-version=2.0&details=true",

    httpheader=c('Content-Type' = "application/json", 'Authorization' = authz_hdr),

    postfields=body,

    writefunction = h$update,

    headerfunction = hdr$update,

    verbose = TRUE

    )

 

headers = hdr$value()

httpStatus = headers["status"]

if (httpStatus >= 400)

{

    print(paste("The request failed with status code:", httpStatus, sep=" "))

 

    # Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure

    print(headers)

}

 

print("Result:")

result = h$value()

print(fromJSON(result))

 

1.2.3.    Web上での確認①


ダッシュボードページにあるTestボタンをクリックします。


フォームが表示されるので予測に使用するデータを入力し、完了ボタンをクリックします。



実行結果が通知されます。


 

1.2.4.    Web上での確認②


ダッシュボードページにある、ボタンの隣のTestリンクをクリックします。


 
数回ページ遷移が発生した後、Testページが表示されます。a


予測に使用するデータをフォームへ入力し、「Test Request-Response」ボタンをクリックします。


 
右側のパネルに予測結果が表示されます。

CSVアイコンをクリックすると、単一行テキストボックスではなく複数行入力可能なテキストエリアが表示されます。ここに予測に使用するデータをカンマ区切りで入力し、「Test Request-Response」ボタンをクリックします。

右側のパネルに予測結果が表示されます。


1.2.5.    Excel


ダッシュボードページにある、「Excel 2013 or later」リンクをクリックします。Sample Dataと書かれたダイアログボックスが表示された場合は「OK」ボタンをクリックします。



 
Excelブックをダウンロードします。


Excelブックを開き、右端のパネルにある「Experiment1 [Predictive Exp.]」をクリックします。


Use sample data」をクリックして、ワークシートにサンプルデータを配置します。


サンプルデータが配置されたら、Class列の値をすべて-1に置き換えます。これは、学習の際にClass列が学習に使用されていないことを念のため確認するためのものなので、行わなくても問題ありません。
その後、右側パネルにあるOutputテキストボックスに、予測結果を書き出す先となるセルを指定します。


Inputテキストボックスの右隣のボタンをクリックして、入力値のデータ範囲を指定します。その後、Predictボタンをクリックします。

 
指定された出力先に予測結果「Scored Labels」が書き出されます。


 

1.2.6.    C#


Visual Studioを開き、コンソールアプリケーションを作成します。






メインメニューから「ツール」>「NuGetパッケージマネージャー」>「パッケージマネージャーコンソール」をクリックし、パッケージマネージャーコンソールを開きます。
 
パッケージマネージャーコンソールに、以下のコマンドを入力し、「Enter」キーを押します。


Install-Package Microsoft.AspNet.WebApi.Client



「正常にインストールされました」と表示されたことを確認後、パッケージマネージャーコンソールを閉じます。



Program.cs1.2.2項で取得したサンプルコードを貼り付け、変数apiKeyには1.2.1項で取得したAPI keyを記載します。


 

必要に応じて入力値(変数Inputs)を変更し、ツールバーの開始ボタンをクリックします。


 
予測結果が出力されることを確認します。




1.2.7.    Python


1.2.7.1. Python実行環境の構築


前回の記事ではAnacondaを使用してPython本体および関連パッケージをインストールするための手順をご紹介しました。しかしながら、本項で使用するPythonの機能は標準ライブラリに含まれるurllibモジュール程度であり、敢えてAnacondaを使用して関連パッケージを導入する必要は低いといえます。そこで以下では、Python本体およびPython Tools for Visual Studioを使用して開発環境を構築するための手順をご紹介します。もしも、scikit-learnのようなライブラリが必要になった場合は、Python本体に付属したpipを使用して後から追加することができます。

Visual Studioを開き、左側にあるパネルの「テンプレート」>「他の言語」>「Python」を選択後、中央にあるパネルの「Python Tools for Visual Studioをインストール」をクリックし、OKボタンをクリックします。


 
「見つからない機能のインストール」ダイアログボックスで、インストールボタンをクリックします。




更新画面が表示されるので、更新ボタンをクリックします。




「セットアップが完了しました」というメッセージを確認後、インストーラを閉じます。


 
ブラウザ等で、http://go.microsoft.com/fwlink/?LinkId=299430にアクセスして、Pythonのインストーラをダウンロードします。


 
ダウンロードしたインストーラを起動して、Python本体をインストールします。


 
環境変数PATHPython実行ファイルのパスを追加する設定のみ、既定値から変更して、有効にします。同一マシン上に、他にもPython実行環境が存在する場合には、適宜調整してください。


 
Complete the Python」というメッセージが表示されていることを確認し、インストーラを閉じます。


 

1.2.7.2. Pythonスクリプトの実行


Visual Studioのメインメニューから、「ファイル」→「新規作成」→「プロジェクト」を開き、「新しいプロジェクト」ダイアログの「インストール済み」→「テンプレート」→「他の言語」→「Python」配下に、いくつかのテンプレートが追加されていることを確認します。


 
Pythonアプリケーションを作成します。


 
Pythonスクリプトに1.2.2項で取得したサンプルコードを貼り付け、変数apiKeyには1.2.1項で取得したAPI keyを記載します。また、必要に応じて入力値(変数Inputs)を変更します。


その後、ツールバーの開始ボタンをクリックし、予測結果が出力されることを確認します。


 

1.2.8.    R


サンプルコードを実行するために必要なパッケージをインストールしておきます。

まず、パッケージをダウンロードする際のミラーサーバーを選択します。一般に、ミラーサーバーとの物理的な距離が近いほうがダウンロードに要する時間が少なくて済むため、日本国内のユーザーであれば東京のミラーサーバーへ接続するように設定しておくのが良いと考えられます。RStudioのメインメニューの「Tools」→「Global Options」をクリックします。
 
Packages」をクリックします。


 
Change」をクリックします。



Japan (Tokyo)」を選択した後、「OK」をクリックします。


 
Apply」、「OK」の順にクリックします。
 
Rstudioの右下にあるパネルの「Packages」をクリックした後、「Install」をクリックします。



Packages欄に「RCurl,rjson」と入力し、「Install」をクリックします。



package ‘RCurl’ successfully unpacked and MD5 sums checked」、「package ‘rjson’ successfully unpacked and MD5 sums checked」の2行が出力されていることを確認します。




Console欄を確認するとわかるように、今回実施した手順では、Rスクリプトの中で「install.packages」関数を実行したのと同じ処理が行われています。

 

パッケージをインストールする際に、R本体をインストールしたときの設定によっては、「Would you like to use a personal library instead?」と表示されることがあります。この場合「はい」ボタンをクリックするとそのままインストール処理を実行することができます。これは、R本体がインストールされたフォルダの中に、ライブラリを作成できないときに表示されるダイアログボックスで、Windows Vista以降のWindows OSで、R本体をProgram Files以下にインストールした場合に表示されることがあります。「はい」ボタンをクリックした場合、全ユーザーで共有するライブラリパスを使用する代わりに、ユーザーごとにドキュメントフォルダ以下にライブラリを作成し、使用することになります。






 


続いて、1.2.2項で取得したサンプルコードをRStudio左上のエディタにペーストします。

その後、「# Replace this with the API key for the web service」と書かれた行で、1.2.1項で取得したAPI key の値を変数api_keyに設定します。また、必要に応じて入力値(変数Inputs)を変更します。
 
Rスクリプトを全選択した状態で「Ctrl」キーと「Enter」キーを同時押しして、Rスクリプトを実行し、結果が得られていることを確認します。結果の値が2つ出力されているのは、Inputsリストの”Values”に「list( list( "0", "0", "0", "0", "0" ),  list( "0", "0", "0", "0", "0" )  )」と2組の入力値を記述しているためです。



今回の記事では、Azure Machine Learning上で作成した実験をWebサービスとしてインターネットに展開(デプロイ)し、RESTクライアントから呼び出して利用する方法についてご紹介しました。せっかく学習モデルを作成しても、活用されないのでは宝の持ち腐れとなってしまいます。REST APIとしてWebサービスを公開することで、クライアント側のOSやプログラミング言語の違いを気にせずに済み、また、最低限ブラウザさえ存在すれば使用できるため、広く利用されるようなWebサービスへと育てられる可能性があります。

ここまで12回にわたってAzure Machine Learningのご紹介を行ってきましたが、次回の記事では、Azure Machine Learningとは少々毛色が異なるサービスであるCognitive Servicesについてご紹介していきたいと考えております。



ブログアーカイブ



前回までのブログと今後の予定
 
機械学習(Azure Machine Learning)の入門からビジネス活用へ
 
 第13回 Cognitive Servicesの活用 6月初旬公開予定
 
 
その他以下ブログを発信中です。