続: Azure Machine Learningを触ってみた ～MLエンドポイントのデプロイ～ 


こちら前回の記事の続きになります。

https://qiita.com/fsd_yoshikawa/items/ec1a57302a4ab11b5e4f

# 記事の目的

ここでは、Azure Machine Learning（以下AzureML） で学習済みのモデルをオンラインにデプロイする方法について説明します。この方法でデプロイされたモデルは、REST APIを介してアクセスできます

# デプロイまでの手順

Microsoft Azure Machine Learning Studioにて、自動MLを選択し、既に学習の終わったジョブを選択します。

![スクリーンショット 2023-04-19 154226.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/25f273f7-7767-15cc-8dd3-dc84ad62e5c2.png)

ここでは適当に一番上のジョブを選択することにします。

次に下図の画面に遷移しますので、モデルの項目をクリックします。

![スクリーンショット 2023-04-19 154557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/19caa903-e98a-22d3-ab2c-8f33a73b6299.png)

すると、下図のようにこのジョブにおけるモデルを作成するのに試行されたアルゴリズムの一覧が加重AUC順に表示されます。なので基本的には一番上に提示されたアルゴリズムを選択すれば問題ないかと思われます。

アルゴリズムを選択するとデプロイ項目が選択可能になりますので、ここをクリックし、リアルタイムエンドポイントを選択します。

![スクリーンショット 2023-04-19 154737.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/87588616-5bbb-cd52-c984-eabeebcbdeb4.png)


すると下図の画面が現れますので仮想マシンとインスタンス数を選びます。
この方法でデプロイするエンドポイントはAzureFunctionsなどと違い、時間ごとの課金となります。
インスタンス数は私の場合1を設定しましたが、この値に応じて時間課金の倍率が変わると思われます。

![スクリーンショット 2023-04-19 155935.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/08d1d430-a41c-4597-d62c-f41b805381dd.png)

デプロイを押すとエンドポイントの作成が始まります。
私の場合ですと、だいたい5分くらいでエンドポイントが立ち上がりました。


# デプロイしたエンドポイントへのアクセス

Microsoft Azure Machine Learning Studioにてエンドポイントを選択、そこにさきほどデプロイされたエンドポイントが表示されているのでクリックします。

![スクリーンショット 2023-04-19 162415.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/83e29bea-af1b-8679-24d9-782fd704e60e.png)

すると遷移した画面の中頃より下部分にRESTエンドポイントというURLが表示されます。
ここにアクセスすればAutoMLをオンラインで使えるということになるのですが、話はもうちょっと複雑です。

![スクリーンショット 2023-04-19 162909.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/e1afafe0-a9e2-fe76-dfab-bef89a05bdd8.png)

実際的には画面上側の「テスト」と「使用」を使って詰めていきます。

## テスト

まずはテストですが、これはきちんとエンドポイントが機能しているかを手っ取り早く試すことができます。

sepal-lengthやsepal_widthなどの値を適当に入れてテストボタンを押すと右側にテスト結果が返ってきます。
Resultとして0が返ってきますのでこれはVersicolorであるとモデルは判断したということがわかります。

![スクリーンショット 2023-04-19 163127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/f8631d7f-b1c6-9c07-eed2-4a5102393430.png)

エンドポイントがきちんと動作していることがわかりました。

## 使用
つぎに使用ですが、ここでは実際にこのエンドポイントを外部から使う方法が示されます。

![スクリーンショット 2023-04-19 164426.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/565c80bb-587f-9997-a1fd-f1f29f94d996.png)

具体的にはこのエンドポイントに接続するためのコードがPython, C#, Rの三種類の言語で提供されています。ここではPythonを使用します。

エンドポイント固有のパラメータは**url**, **api_key**, **azureml-model-deployment** の3つです。
つまりエンドポイントを立て直すたびにこの3つのパラメーターは変わっていくということになります。

この点を踏まえて、再利用性の高いAutoMLエンドポイントへ接続するコード例を以下に提示します。

```python:automl_connector.py
import urllib.request
import json
import os
import ssl

URL="url example"
API_KEY="api key example"
AZUREML_MODEL_DEPLOYMENT="model example"

def allowSelfSignedHttps(allowed):
    # bypass the server certificate verification on client side
    if allowed and not os.environ.get('PYTHONHTTPSVERIFY', '') and getattr(ssl, '_create_unverified_context', None):
        ssl._create_default_https_context = ssl._create_unverified_context

allowSelfSignedHttps(True) # this line is needed if you use self-signed certificate in your scoring service.

# Request data goes here
# The example below assumes JSON formatting which may be updated
# depending on the format your endpoint expects.
# More information can be found here:
# https://docs.microsoft.com/azure/machine-learning/how-to-deploy-advanced-entry-script
data =  {
  "Inputs": {
    "data": [
      {
        "sepal_length(cm)": 0.0,
        "sepal_width(cm)": 0.0,
        "petal_length(cm)": 0.0,
        "petal_width(cm)": 0.0
      }
    ]
  },
  "GlobalParameters": {
    "method": "predict"
  }
}

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


# Replace this with the primary/secondary key or AMLToken for the endpoint

if not API_KEY:
    raise Exception("A key should be provided to invoke the endpoint")

# The azureml-model-deployment header will force the request to go to a specific deployment.
# Remove this header to have the request observe the endpoint traffic rules
headers = {'Content-Type':'application/json', 'Authorization':('Bearer '+ API_KEY), 'azureml-model-deployment': AZUREML_MODEL_DEPLOYMENT }

req = urllib.request.Request(URL, body, headers)

try:
    response = urllib.request.urlopen(req)

    result = response.read()
    print(result)
except urllib.error.HTTPError as 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(error.read().decode("utf8", 'ignore'))
```

上記のコードの冒頭

* URL="url example"
* API_KEY="api key example"
* AZUREML_MODEL_DEPLOYMENT="model example"

部分において実際的には以下の通りの値を設定します。

* URL: RESTエンドポイント
* API_KEY: 主キー
* AZUREML_MODEL_DEPLOYMENT: AzurePortal上に表示されるコードの44行目のheader定義上の'azureml-model-deployment'の値

もっともapi keyなどは通常コードの中に記述するべきではありませんので、状況に応じて秘匿する必要があります。

以上を踏まえて上記コードを実行すると

```
b'{"Results": [0]}'
```

という表示が返ってきました。成功です。

AutoMLを使って作成されたモデルのエンドポイントをオンラインにデプロイすることができました。