Azure MLでKaggleのTPS AUG 2022をやってみた

# はじめに
今回はKaggleの「[Tabular Playground Series - Aug 2022](https://www.kaggle.com/competitions/tabular-playground-series-aug-2022)」のコンペをAzure MLを使って予測してみようと思います。



## ワークスペースの作成

![スクリーンショット (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/6db90fc6-5602-e1ad-a997-825613fc8bcb.png)

1. 「Create」をクリックします

![スクリーンショット (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/096805e2-0bff-c81b-2020-4c32f215206e.png)

1. サブスクリプションの選択をし、リソースグループで新規作成を行います。
1. ワークスペース名の入力をします。（今回は「t-kawano-test」としました）
1. 「確認および作成」をしたら続けて「作成」を選びます。

これでワークスペースの作成が完了です！

## デザイナーの作成
ワークスペースの作成が完了したら、「スタジオ Web URL」をクリックしたら、次のような画面に移ります。

![azure-ml.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/f2891389-2604-abd4-7421-98378f6654ec.png)

今回は「デザイナー」という機能を使ってモデルを作成していきます。
デザイナーを「今すぐ開始」で起動します。

![スクリーンショット 2022-11-22 14.23.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/f501eca3-c3ce-fcdd-15e6-86cabcc7de78.png)

このようにサンプルがズラリと並んだ画面に移ります。
これらは既にブロックが組み上がっているものです。

TPS AUG 2022は製品の故障を予測するというコンペです。
つまり、failureの結果が0と1どちらなのかを予測するというもの(二項分類)なので、今回はこちらのサンプルの中の「Cross Validation for Binary Classification」を用いてやってみます。


![スクリーンショット 2022-11-22 14.30.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/6edd99d4-c83a-cb42-880b-49000f8e2643.png)

開いてみると、すでにブロックができあがっているのがわかります。
今回はデータセットだけKaggleのものへ入れ替えてやってみましょう！

## データセットの追加
### 事前準備として
Kaggleのデータセットをダウンロードするには、そのコンペに参加する必要があります。
参加したら「Data」タブからSample、Train、Testの3つのファイルをダウンロードします。

### Azure MLにデータセットを追加する

![スクリーンショット 2022-11-22 14.36.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/3e0b5b8a-cee2-993f-ba01-6081f91e8028.png)

まずは「Data」タブを左側で開き、「+」をクリックします。

![スクリーンショット 2022-11-22 14.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/96c54cf1-20ce-8fcd-9711-ef6661918e3d.png)

名前を設定し、ローカルのファイルからアップロードすればOK!

![スクリーンショット 2022-11-22 14.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/da41d132-0e38-0d50-784c-21b0242f8049.png)

これで追加ができました^^

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/6710b6d9-3429-3450-8177-f05491391ab4.png)

追加したTPS-AUG-2022のtrainデータを置いて、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/595b28a1-68a1-4b95-8dbb-e3ac7a5a9c59.png)

Cleaning Missing DataにつなげればOK！
（元々あったデータセットについては、もう使わないので削除をしておきます。）

そして最後にターゲットの列を選択します。
**Train Model**と**Cross validate Model**それぞれのコンポーネントをダブルクリックすると設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/a3f048c6-ce98-5d8c-8961-268db68aad48.png)

列を変更後、保存をして完了です。

### コンポーネントの追加
学習して出た結果を評価するために、**Evaluate Model**コンポーネントを追加します。

データセットを追加したときと同じように、今度はコンポーネントタブを開き、検索欄で探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/527d55c7-0626-e82c-fde2-731f6dd0b532.png)

そして、**Score Model**とつなげます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/76fd939d-8424-9277-d8a9-056ce0addbb5.png)

また、データの中身を見てみると、**product_code**がtrainとtestデータで全く違うものが使われているので今回は削除します。この列を削除するためには**Select Columns in Dataset**コンポーネントを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/e35fd479-34bb-1665-21b9-a8f62a1cc7ee.png)

trainデータの下にコンポーネントを置いたら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/a597a6bd-3561-1be4-83fe-52658617d5d9.png)

使用する列を指定したら、**product_code**列が削除されます。

## 実行

### コンピューティング先を設定

「設定」をクリックし、「Azure MLコンピューティングクラスターを選択する」でクラスターを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/9ce0c381-4ef6-a4e6-6bdd-79d4802a6c58.png)

ここが選択できない場合は、その下にある「Azure MLコンピューティングクラスターを作成する」をクリックし、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/8d182bbe-da87-558e-7b43-60badccdba1a.png)

**場所**や**仮想マシンの種類**、**サイズ**を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/cfbf9327-ae4b-3e2e-7707-fb382a65e1f6.png)

さらに進んで、コンピューティング名を入力したら作成完了！

### ジョブの実行

画面右上の「送信」をクリックしたら、ジョブのセットアップ画面が出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/0fc900f6-ea76-2414-6f93-6f4d6785d2e2.png)

「新規作成」で実験名を入力、「送信」をクリック！
これでジョブの実行ができます。

ワークスペースに戻ってみると、状態が「実行中」になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/4e398684-1569-272d-acfe-dfe9845e6e7d.png)

実行完了したら、ワークスペースの状態は「完了」に変化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/f6e8995f-4f20-6fe2-7a5b-e15df65b4454.png)

ジョブを開き、Score Modelの結果を見てみましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/fee02eba-1c71-684d-a8b9-ed1ab67282fe.png)

Scored Probabilitiesはその結果の信頼性を表すもので、1に近いほど信頼度が高いということです。
結果の一部を見てみても、あまり良くはなさそうです笑

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/be4aab94-f060-aca4-8e96-84e5e95e9460.png)

次にEvaluate Modelの結果も見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/5c38e049-57a9-189f-c341-e60797a516c4.png)

今回のKaggleの評価指標はROCが使われていましたが、大体0.5なので、やはりあまり精度は高くなさそうです。


## testデータを使ってやってみる
Azure MLでは一度推論したモデルは登録し、呼び出すことができるのでこれを使ってtestデータでfailureの予測を行います。

![MicrosoftTeams-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/49c82d58-29fd-1beb-32c1-ce0c86cfe349.png)

ジョブに戻り、**Train Model**で「データの登録」をします。

![MicrosoftTeams-image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/105e6f02-eb51-c776-e6b4-4161e84b87d6.png)

これで実行してみます！

### 結果のデータを取り出す
実行完了したら、予測した結果を取り出したいので、**Export Data**コンポーネントを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/a4836d16-a1b4-3e6b-462f-9484472f712f.png)

csv形式で取り出したいので次のように**Export Data**を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/cedbd2e8-2842-158b-304d-5be33ec685e8.png)

これでジョブを実行し、完了したら

1. 左側の「データ」をクリック
1. 「データソース」で先ほど**Export Data**で指定したデータストアを選択
1. 「プレビューを参照」の下にある該当のファイルをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/14d03076-4f13-2f51-21b2-d8fe933a7d6c.png)

最後に「・・・（三点リーダー）」から「ダウンロード」をクリックすれば結果を取り出すことができます。
Excelで開いてみるとこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/eec14a43-2a96-3b73-5cc0-07a1e3e3a356.png)


## コンペ提出
取り出したデータはそのままだと提出できないので、Kaggleで指定された形式に加工します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/82becefa-ca48-7dc9-d5e9-f90ba86f60db.png)

**id**と**failure**だけ残し、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/5ac70b7e-4411-675e-a9c0-4aa2e11557c1.png)


保存したらいよいよKaggleに提出してみます。

### 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/b63a073a-fc51-77e2-1832-d97dfaf86132.png)

無事、ちゃんと提出することができました！


<!--
## testデータを使ってやってみる
それではKaggleに提出するため、今度は作ったモデルtestデータを追加してみましょう！

再びワークスペースに戻り、デザイナーを開いて先ほど作ったパイプラインを編集します。

先ほどと同じように、今度はTPSコンペのtestデータを追加したら、このようにつなげます。
（Cross Validate Modelは使わないので削除）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/8cf30b85-a9ff-4a8c-5e05-7c00b5bc1f1d.png)

そして、データの中身を見てみると、**product-code**がtrainとtestデータで全く違うものが使われているのでこの列を削除するために**Select Columns in Dataset**コンポーネントを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/df801118-081f-ccf9-0e5d-b8d3b2912742.png)

trainとtestデータの下にそれぞれコンポーネントを追加して、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/a597a6bd-3561-1be4-83fe-52658617d5d9.png)

列を選択したらOK！
-->





## リアルタイム推論
左タブの「コンピュータ」から「推論クラスター」で新規作成を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/9cdea70c-89da-700e-35c8-4d46d9db4399.png)
仮想マシンの選択をし、コンピューティング名を入力したら作成できます。
作成には少し時間がかかるので、終わるまで待ちましょう♪

終わったら再びジョブに戻り、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/00051479-36e9-c871-9c48-d0d4c9d6a5bd.png)

「推論パイプラインの作成」から「リアルタイム推論パイプライン」を選択すると自動的にパイプラインが変わるので、**Web Service Input**コンポーネントを追加し、ジョブの実行を行います。

そして実行が終わったら、ジョブで「デプロイ」がクリックできるようになります。

これでデプロイが完了したらエンドポイントの作成ができます！

![MicrosoftTeams-image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/d40bb187-6327-f78a-1546-f12c1f48be6b.png)


## PythonからAPIを叩いてみる！
コードが自動的に生成されるので、これを使ってPythonから叩いてみます。

まず、左の「エンドポイント」に入ります。

![MicrosoftTeams-image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/f36494bc-4455-1cc9-d1ec-20de0a17dd71.png)

![MicrosoftTeams-image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/47f6fb85-eef6-6bbd-6025-244fcd873e68.png)

「テスト」タグに移り、"0__FloatingPointVal__"をFloat型の数値に変更します。
![MicrosoftTeams-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/0147130b-012e-6cee-6e4c-d64be599c3ba.png)

テストを行うと…

![MicrosoftTeams-image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/4227e91e-4a9e-b7bc-23a1-5b951b9e2655.png)

成功できました！

### Pythonから
コードをコピーして、PythonでAPIを叩いてみましょう。

```predict.py
import urllib.request
import json
import os
import ssl
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": {
    "input1": [
      {
        "id": 26570,
        "product_code": False,
        "loading": 119.57,
        "attribute_0": "material_5",
        "attribute_1": "material_6",
        "attribute_2": 6,
        "attribute_3": 4,
        "measurement_0": 6,
        "measurement_1": 9,
        "measurement_2": 6,
        "measurement_3": 19.305,
        "measurement_4": 10.178,
        "measurement_5": 17.534,
        "measurement_6": 18.168,
        "measurement_7": 11.598,
        "measurement_8": 18.654,
        "measurement_9": 10.802,
        "measurement_10": 15.909,
        "measurement_11": 18.07,
        "measurement_12": 13.772,
        "measurement_13": 13.659,
        "measurement_14": 16.825,
        "measurement_15": 13.742,
        "measurement_16": 17.71,
        "measurement_17": 634.612
      },
      {
        "id": 26571,
        "product_code": False,
        "loading": 113.51,
        "attribute_0": "material_5",
        "attribute_1": "material_6",
        "attribute_2": 6,
        "attribute_3": 4,
        "measurement_0": 11,
        "measurement_1": 8,
        "measurement_2": 0,
        "measurement_3": 17.883,
        "measurement_4": 11.927,
        "measurement_5": 17.228,
        "measurement_6": 16.033,
        "measurement_7": 11.179,
        "measurement_8": 19.368,
        "measurement_9": 12.032,
        "measurement_10": 13.998,
        "measurement_11": 13.000,
        "measurement_12": 12.473,
        "measurement_13": 17.468,
        "measurement_14": 16.708,
        "measurement_15": 14.776,
        "measurement_16": 14.102,
        "measurement_17": 537.037
      },
      {
        "id": 26572,
        "product_code": False,
        "loading": 112.16,
        "attribute_0": "material_5",
        "attribute_1": "material_6",
        "attribute_2": 6,
        "attribute_3": 4,
        "measurement_0": 8,
        "measurement_1": 12,
        "measurement_2": 4,
        "measurement_3": 18.475,
        "measurement_4": 10.481,
        "measurement_5": 16.619,
        "measurement_6": 18.189,
        "measurement_7": 12.126,
        "measurement_8": 17.774,
        "measurement_9": 11.743,
        "measurement_10": 17.046,
        "measurement_11": 18.086,
        "measurement_12": 10.907,
        "measurement_13": 13.363,
        "measurement_14": 15.737,
        "measurement_15": 17.065,
        "measurement_16": 16.021,
        "measurement_17": 658.995
      },
      {
        "id": 26573,
        "product_code": False,
        "loading": 112.72,
        "attribute_0": "material_5",
        "attribute_1": "material_6",
        "attribute_2": 6,
        "attribute_3": 4,
        "measurement_0": 8,
        "measurement_1": 11,
        "measurement_2": 10,
        "measurement_3": 16.518,
        "measurement_4": 10.888,
        "measurement_5": 15.293,
        "measurement_6": 18.592,
        "measurement_7": 11.304,
        "measurement_8": 18.948,
        "measurement_9": 11.79,
        "measurement_10": 18.165,
        "measurement_11": 16.163,
        "measurement_12": 10.933,
        "measurement_13": 15.501,
        "measurement_14": 15.667,
        "measurement_15": 12.62,
        "measurement_16": 16.111,
        "measurement_17": 594.301
      },
      {
        "id": 26574,
        "product_code": False,
        "loading": 208.0,
        "attribute_0": "material_5",
        "attribute_1": "material_6",
        "attribute_2": 6,
        "attribute_3": 4,
        "measurement_0": 14,
        "measurement_1": 16,
        "measurement_2": 8,
        "measurement_3": 17.808,
        "measurement_4": 12.693,
        "measurement_5": 17.678,
        "measurement_6": 15.814,
        "measurement_7": 13.431,
        "measurement_8": 19.141,
        "measurement_9": 12.37,
        "measurement_10": 14.578,
        "measurement_11": 17.849,
        "measurement_12": 11.941,
        "measurement_13": 16.07,
        "measurement_14": 16.183,
        "measurement_15": 13.324,
        "measurement_16": 17.15,
        "measurement_17": 801.044
      }
    ]
  },
  "GlobalParameters": {}
}
body = str.encode(json.dumps(data))
url = 'http://XXX'
api_key = 'YYY' # Replace this with the API key for the web service
# 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)}
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'))

```

こちらも"0__FloatingPointVal__"をFloat型の数値に変更と、falseをFalseに変更しました。
これを実行したら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/0446cc3a-b180-3e7a-bd0c-a65d48b7fed7.png)

同じように結果が返ってきました！
推論結果がScored Labelsに、信頼スコアがScored Probabilitiesに入っています。

## まとめ
+ Azure MLのデザイナーを使ってみた
+ KaggleのTPS Aug 2022をAzure MLを使って提出
+ エンドポイントを作成し、Pythonでたたいてみた