【AzureML】デザイナーで作ったパイプラインをpythonから実行してみる【Python】

お久しぶりですね。
今回はサンプルの`Cross Validation for Binary Classification - Adult Income Prediction`を使ってpythonから実行してみたいと思います。
また、汎用的に利用したいので、一部項目をパラメータにして試してみたいと思います。
ワークスペースやクラスターの作成、実行方法等は[最初の記事](https://qiita.com/K-Nomu3/items/6b9c89b958380ea67b64)を参考にしてください。

# サンプルを開く
それではいつものようにサンプルを見ていきましょう。
データの内容は依然やったものと同じだったので割愛します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/30516cb7-a0e9-c1e2-7241-88ceba7c1028.png)
シンプルですね。
今までと違う点はCrossValidateModelでしょうか。
どのようなブロックなのか確認していきましょう。


# サンプルの内容
`CrossValidateModel`は交差検証を行うブロックです。
交差検証とは、
> データセットの変動性と、そのデータを通じてトレーニングされたモデルの信頼性の両方を評価するために、機械学習でよく使用される手法

らしいです。
学習データとテストデータの分割を数回行い、一つのデータで何回かの学習を行い、その結果を比較することでモデルを評価するという者みたいですね。

ブロックには前処理後のデータとアルゴリズムを繋いでるようですね。
結果としてはどのようなものが得られるのでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/795e2ecf-a7d7-e7a0-49f9-0c6da3e3b345.png)
一つ目は予測結果ですね。
予測結果は`ScoredProbabilities`の値が一番良かった施行のデータが入っているようです。
`FoldNumber`には何回目の施行のデータなのかが入っているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/6b3124fc-0df1-162d-5f78-2d906cb72436.png)
二つ目は評価指標のリストですね。
各施行ごとの評価を比較できるので、作成したモデルがだいたいどれくらいの精度を持つのかを確認することができますね。

# サンプルをいじってみる
今回はここからが本番です。
今まではAzureMLStudio上で作業していましたが、このブロック作成後の実行をpythonコード上から実行してみたいと思います。
また、パラメータを利用して、学習させるデータや結果の出力先を自由に決められるようにしたいと思います。

## AzureCLIでAzureにログインする
pythonでAzureMLを操作するためにAzureCLIでログインする必要があります。
AzureCLIのインストールは[こちら](https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli)を参考に行います。
といっても[こちら](https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-windows?tabs=azure-cli)にあるインストーラーを実行するだけですので簡単ですね。

その後PCを再起動してazコマンドが実行できることを確認します。
```powershell
az --version
```
こちらが実行できたらインストールは成功ですね。
あとはログインして、利用しているサブスクリプションを選択します。

```powershell
az login
az account set --subscription "サブスクリプションID"
```
az loginを実行するとwebページが開くのでloginします。
自分の場合は既定のサブスクリプションが利用中のものと異なっていたので下のコマンドを利用して変更する必要がありました。

これで準備完了です。

## ブロックの修正
まずは先ほどのブロックに修正をしていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/7cd61cb3-c659-de76-8dee-895d69383f5b.png)

ブロックの変更は
- データの入力をImportDataに変更
- ScoreModelの後ろにExportDataを追加
- CrossValidateModelの後ろにExportDataを追加

になります。
また、TrainModelやCrossValidateModelでは学習対象のカラムを指定する部分があります。
もともとはカラム名を指定しているのですが、いろんなデータを使いたいとなると名前指定はよくありません。
そこで、必ず最初のデータを学習対象にするように変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/beca46f4-703c-cf35-3d07-51df857e9a89.png)

このようにすることで、学習時にデータを成型することで任意のデータを学習させることができるはずです。
この変更をTrainModelとCrossValidateModelに行います。

入力データと出力ファイル名は実行ごとに自由に決めたいです。
そこで`パイプラインパラメータ`を利用したいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/380864f5-a75e-fcca-445b-0c9dca73cf73.png)
パイプラインパラメータを利用することで、実行時に変数として値を渡すことができるようになります。
この変更をImportDataとExportDataに行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/da2a79fd-1d6a-2527-04df-ca2f3fd8c631.png)
変更はこのようにパラメータ名と値の組み合わせで設定するので、それぞれパラメータ名は一意のものを、値には初期値としてふさわしいものを入れておきます。
例えばImportDataの初期値に存在しないファイル名を入れてしまうと、値を設定しなかった場合にエラーが出てしまうので注意しましょう。




## パイプラインの公開
それではPythonから実行できるようにパイプラインを公開したいと思います。
まずはこれを実行し、動作することを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/1c6a6682-3909-8206-bd69-f6cd7a02d1bb.png)

その後パイプラインエンドポイントを作成するのですが、自分の環境だとAzureMLStuido上からだとうまく動作しなかったのでPythonコードから作成していきたいと思います。

```python
from azureml.core import Workspace
from azureml.core.experiment import Experiment
from azureml.pipeline.core import PipelineRun

ws = Workspace.from_config()
experiment = Experiment(workspace=ws, name='<実験の名前>')

pipeline_endpoint = PipelineRun(experiment, "<実行のID>").publish_pipeline(
    name="<表示名>",
    description="<説明>",
    version="<バージョン>",
    continue_on_step_failure=None #失敗ステップを続行するかどうか
)

```

こちらを実行しましょう。
実験の名前は送信時に選択した実験名を入れます。
実行IDはジョブの概要から確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/3772b4c4-64ef-ded8-80d1-35baa7794003.png)

上記コードを実行すると、パイプラインタブのパイプラインエンドポイントに項目が作成されていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/8c6f6254-df7b-bd80-64b6-5a75a7cf51ed.png)

こちらを開いてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/f829cef4-709e-3ed8-edd1-bc8ee2bc2477.png)
このように表示されると思います。
この右にあるパイプラインIDを利用してこちらを実行させていきます。
それでは実行するためのコードを見ていきましょう。


```python
from azureml.core import Workspace
from azureml.core.experiment import Experiment
from azureml.pipeline.core import PublishedPipeline

ws = Workspace.from_config()
experiment = Experiment(workspace=ws, name='<実験の名前>')
published_pipeline = PublishedPipeline.get(workspace=ws, id="<パイプラインID>")
pipeline_run = experiment.submit(
    published_pipeline,
    pipeline_parameters={
        "Import_data_path": "csvdata/titanic.csv",
        "Export_score_path": "exportdata/scorepub2.csv",
        "Export_eval_path": "exportdata/evalpub2.csv"
        }
    )
```

ワークスペースを取得して、先ほど作成したパイプラインエンドポイントを取得します。
その後、設定したパラメータに任意の値を入れて実行するといった流れになります。

こちらを実行して動作を確認してみます。
今回は入力データをタイタニックの生存予測のデータに変更してみました。
ちゃんと結果は出るでしょうか…

## 実行結果の確認

実行を行うと

```terminal
Submitted PipelineRun -----
Link to Azure Machine Learning Portal: https://ml.azure.com/----
```
というような結果が返ってきます。
一つ目のほうは実行IDになります。
二つ目のほうは実験へのURLになります。こちらを開くことで実行の確認ができますね。
今回は正しく出力されているかが気になるのでBLOBを直接見てみたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/18c2f098-d756-ec99-a913-4fb73aba3acd.png)
どうやらファイルの生成はできているようです。
スコアデータがちゃんとできているかを見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/1e5e8265-460d-dc75-94e7-e0181b31aa9b.png)
ちゃんとタイタニックのデータが出力できています！
評価のほうも見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395106/5b61d756-ba04-e751-fc30-ae83008db26a.png)
評価もちゃんと出力できてますね。

# まとめ
今回はデザイナーで作成したパイプラインをpythonから実行させてみました。
これによって、学習の流れをブロックで作成して、利用はコード上からできることがわかりました。
デザイナーで作成したパイプラインをサービスに組み込んだりして利用できそうですね。