[Azure Machine Learning]AutoMLで作成したモデルをデプロイせずに様々な環境で使用する

基本的に運用面の手間を考えると正式にデプロイする場合はACI⇒AKSコンテナにモデルをデプロイしてREST APIとして利用するのが望ましいとは思います。コンテナが立ち上がるので相応の課金はされてしまい、開発段階でコストを抑えたい場合にはモデルのファイルを取得してNotebookから読み込む必要があります。つまり今回は「AutoMLやデザイナーでモデルは作成したが、テスト用のデータを用いてモデルを検証したい」場面を想定しています。

## モデルファイルの取得
AutoMLやデザイナーで実行して得られたモデルは、それに紐づいた[実験]から取得することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/43e2ecbf-4226-db3b-1597-76842f0c5759.png)

[モデル]を開き、任意のモデルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/16e3b132-32ad-6127-e2a9-a7847da75e52.png)

[ダウンロード]からモデルをダウンロードすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/a4a49d8b-8fc9-abf8-9187-393bf02621d8.png)

モデルやそれ以外の出力は[出力とログ]から確認できます。このあたりを確認することでログを見て分析したり、推論用のコード(scoring_xxxxxx.py)を確認できたりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/0a21143c-1b0e-843b-3668-743dabe00e54.png)

これで、モデルのファイルをダウンロードできました。

## モデルファイルのNotebookへのインポート
モデルファイルさえ取得できれば後は先人たちが残している記事を参照ください。

https://qiita.com/Qiitaman/items/ce7519798a3c6b6e0e8d

ちなみに、モデルのファイルは`.pkl`という形式で出力されます。これは単に「Pythonのオブジェクトをファイルとして出力し、Pythonのコードから呼び出せるようにしたもの」です。なので、pickleというライブラリを利用することでNotebook内でご自身が作成したpythonオブジェクトもファイル出力できるわけです。実体はバイナリもしくはテキストファイルですが、別の環境で利用する際にはバイナリモードが推奨されます。

モデルに推論させる部分のコードは推論用のコードからコピペするのが速いです。以下コードのrun関数の内部が推論部分です。

```python:scoring_xxxxxx.py
# ---------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# ---------------------------------------------------------
import json
import logging
import os
import pickle
import numpy as np
import pandas as pd
from sklearn.externals import joblib

import azureml.automl.core
from azureml.automl.core.shared import logging_utilities, log_server
from azureml.telemetry import INSTRUMENTATION_KEY

from inference_schema.schema_decorators import input_schema, output_schema
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType
from inference_schema.parameter_types.pandas_parameter_type import PandasParameterType


input_sample = pd.DataFrame({"PatientID": pd.Series(["1354778.0"], dtype="float64"), "Pregnancies": pd.Series(["0.0"], dtype="float64"), "PlasmaGlucose": pd.Series(["171.0"], dtype="float64"), "DiastolicBloodPressure": pd.Series(["80.0"], dtype="float64"), "TricepsThickness": pd.Series(["34.0"], dtype="float64"), "SerumInsulin": pd.Series(["23.0"], dtype="float64"), "BMI": pd.Series(["43.50972593"], dtype="float64"), "DiabetesPedigree": pd.Series(["1.213191354"], dtype="float64"), "Age": pd.Series(["21.0"], dtype="float64")})
output_sample = np.array([0])
try:
    log_server.enable_telemetry(INSTRUMENTATION_KEY)
    log_server.set_verbosity('INFO')
    logger = logging.getLogger('azureml.automl.core.scoring_script')
except:
    pass


def init():
    global model
    # This name is model.id of model that we want to deploy deserialize the model file back
    # into a sklearn model
    model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'model.pkl')
    try:
        model = joblib.load(model_path)
    except Exception as e:
        path = os.path.normpath(model_path)
        path_split = path.split(os.sep)
        log_server.update_custom_dimensions({'model_name': path_split[1], 'model_version': path_split[2]})
        logging_utilities.log_traceback(e, logger)
        raise


@input_schema('data', PandasParameterType(input_sample))
@output_schema(NumpyParameterType(output_sample))
def run(data):
    try:
        result = model.predict(data)
        return json.dumps({"result": result.tolist()})
    except Exception as e:
        result = str(e)
        return json.dumps({"error": result})
```

このコードでは予測結果の取得に`model.predict()`を使っていますが、確率で取得したい場合には`model.predict_proba()`を使うことで取得可能です。


## まとめ
お客様案件で未知データに対する結果の評価をデプロイせず行いたいという需要があったので備忘録として残しておきます。