どうもこんにちは。株式会社船井総研デジタルの@fsd_yoshikawaです。
この度、AzureのMachine Learning(以下ML)を使ってみた軌跡をここに書き留めたいと思います。
以下記事においてMachine LearningのことをML、Azure内のMachine LearningサービスのことをAzureMLと呼称します。なおAzureにはお手軽に機械学習をさせる機能があって、それについてはAzureAutoMLと呼称します。
記事の目的
- とりあえずAzureMLがどういうものか知りたい人向け
- ローカルマシン上で実行したMLの結果と、AzureAutoMLの結果とを比較する
- AzureML内のJupyterNotebookを使用する
まずはローカルマシン上に比較用のMLコードを用意
ローカルマシン環境
Windows_version=Windows11
WSL_version=2
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"
ローカルマシン上でMLの準備
MLを行うにあたってPythonを使います。
Pythonのバージョンと利用するパッケージのバージョン
python = "^3.8"
scikit-learn = "^1.2.1"
pandas = "^1.5.3"
バージョン記述内の"^"が意味するものは、左端のメジャーバージョンを表す数値が変わらない最大のバージョンまで想定しているということです。
例: python = "^3.8" ➔ 3.8 <= Python version < 4.0
ローカルマシン上でのMLの概要
- 使用する学習用データはIrisデータセット
- 使用するMLアルゴリズムは3つ(DecisionTreeClassifierとLinearRegressionとKNeighborsClassifier)
- 3つのアルゴリズムをデフォルトで使用して、そのスコアの平均をAzureMLとの比較用データとする。
AzureMLはデータを与えるとお手軽にMLしてくれるということですが、どのくらいお手軽なのか、またどのくらいの精度のモデルができるのかを検証したいと思います。
そのためにはまず、ローカルマシン上でMLを動かしてみて、その結果と比較するのが良いと考えました。
一つのMLアルゴリズムだけでは単純にアルゴリズム同士の性能比較となってしまうので、ここでは3つのアルゴリズムをデフォルトで使い、それらのスコアの平均を比較用データとしたいと思います。単純に3つのスコアの平均を取るという行為は乱暴な措置であるため、それぞれのモデルのスコアも併せて表示します。
作成したコードは下記のとおり。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
import time
start = time.time()
TRAIN_SIZE = 0.7
# Prepare data
dataset = load_iris()
columns_name = dataset.feature_names
x = dataset.data
t = dataset.target
x_train, x_test, t_train, t_test = train_test_split(x, t, train_size=TRAIN_SIZE, random_state=1)
# Prepare models
models = [
DecisionTreeClassifier(),
LogisticRegression(),
KNeighborsClassifier()
]
# Run
train_scores = 0
test_scores = 0
for model in models:
model.fit(x_train, t_train)
# print(f"{str(model)} Train score: {model.score(x_train, t_train):.3f}")
print(f"{str(model)} Test score: {model.score(x_test, t_test):.3f}")
train_scores += model.score(x_train, t_train)
test_scores += model.score(x_test, t_test)
# Print average
print("[ Result ]".center(40, "*"))
# print(f"Train score average: {train_scores / len(models):.3f}")
print(f"Test score average: {test_scores / len(models):.3f}")
print(f"Elapsed time: {time.time() - start:.3f}")
このコードを実行すると、結果は下記の通りになりました。
DecisionTreeClassifier() Test score: 0.956
LogisticRegression() Test score: 0.978
KNeighborsClassifier() Test score: 0.978
***************[ Result ]***************
Test score average: 0.970
Elapsed time: 0.016
3つのアルゴリズムのスコアの平均は約0.97ということになりました。
また、コード中に時間計測のコードを埋めて実行時間を計測してみたところ約16ミリ秒で完了するのを確認しました。
続けてIrisデータセットを抽出
Irisデータセットは下記のサイトよりダウンロードできます。
UCI Machine Learning Repository: Iris Data Set
https://archive.ics.uci.edu/ml/datasets/iris
しかし上記のsample.pyでは dataset = load_iris()
によって学習用データを用意しています。
おそらく上記URLのデータセットと内容は全く同じだと思うのですが、ここでは慎重を期してload_iris()
のデータを抽出して使いたいと思います。
Irisデータセットを抽出するためのコードは下記の通りです。
import os.path
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
src_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = os.path.dirname(src_dir)
data_dir = os.path.join(root_dir, 'data')
df_d = pd.DataFrame(iris.data, columns=["sepal_length(cm)", "sepal_width(cm)", "petal_length(cm)", "petal_width(cm)"])
df_t = pd.DataFrame(iris.target, columns=["target"])
df = pd.concat([df_d, df_t], axis=1)
df.to_csv(f"{data_dir}/iris_sample_data.csv", index=False)
上記のコードによってiris_sample_data.csv
という形でIrisデータセットの内容を下記のような形で抽出できました。
これで前準備は整いました。
これからAzureMLを動かしていきます。
AzureMLを触る
基本的には下記の内容を元にAzureMLをセットアップしていきます。
Scikit-learn 機械学習モデルをトレーニングする (v2) - Azure Machine Learning | Microsoft Learn
https://learn.microsoft.com/ja-jp/azure/machine-learning/how-to-train-scikit-learn
ざっと読んだらAzureML Studioというものを使うことがわかります。
URLは下記の通りです。
Microsoft Azure Machine Learning Studio
https://ml.azure.com/home
ここでディレクトリの切り替えを推奨されたのでディレクトリを変更し、正しいサブスクリプションとリソースグループを設定してワークスペース名を決定します。
これでワークスペースの作成ボタンを押してしばらくするとワークスペースが出来ていますので、作ったワークスペースを選択すると次のような画面になります。
早速自動MLを選択してAzureAutoMLを開始していきましょう。
新規の自動機械学習ジョブを選択します。
データアセットの選択では、作成を選択しましょう。
データ資産の名前と型の設定という画面が表示されますので、ここで必須入力事項である名前を入力します。種類は表形式で固定になっています。
データ資産のソースを選択する画面ではローカルファイルからを選択します。
ストレージの種類、データストアの選択はデフォルトのままでいきます。
ファイルまたはフォルダーの選択の画面で、先程抽出したIrisデータセットのiris_sample_data.csvを選択します。
読み込むと下図が表示されました。
いい感じです。
上図において データセットに複数行のデータが含まれています というチェックボックスがあります。
そのままの意味で受け取れば、このデータは複数行で構成されていますのでチェックが必要と考えるべきだと思うのですが
その点について下記のサイトでは
データのセル内に改行コードが含まれている場合、このオプションをオンにすれば正しく読み取ってくれます。ただしパフォーマンスを著しく下がります
Azure Machine LearningのAutoMLで時系列予測を試してみた~①モデル作成編~ - Qiita
https://qiita.com/tmiyata25/items/a08fd81ef8cc156cdb03
と書かれており、データセル内の改行を意味しているとの注釈があります。
なお言語表示をEnglishにするとこの部分は下図のように表現されます。
なんとも判断の難しい文章なのですが、今回はチェックはしないで進めました。
データに問題がないことを確認して次へいくと学習用データのスキーマが表示されます。
そして最後にレビュー。
これまでの設定事項の総括みたいな表示です。作成を選択します。
データアセットの選択画面に戻ってきますので、ここで最新の情報に更新をクリックすると作成したデータアセットが表示されます。
作成したデータを選択して、次へ。
ジョブの構成画面では下図のような設定値にしました。
ターゲット列は学習用データに対する教師データが含まれる列ということになります。
コンピューティングの種類を選択では「コンピューティングクラスター」と「コンピューティングインスタンス」のどちらかが選べるのですが、クラスターを使えば複数のコンピューターを使ってより早く学習を終わらせられる、くらいの理解でおります。
クラスター、インスタンス、両方を作成することもできるのですがそれぞれの稼働時間に対して料金が発生するので、巨大なデータを扱うのでなければコンピューティングインスタンスのみの設定で問題ないかと思います。
※公式のマニュアルではここで両方のコンピューティングリソースを作成するように解説されているんですけどね。
コンピューティングの種類を選択のボックスにコンピューティングインスタンスを設定した状態で新規を押すと、下図の通りコンピューティングインスタンスの設定が始まります。
大きなデータではないので、一番小さいCPUを選んで作成します。
CPUを作成するとしばらく待ち(大体2~3分)が発生します。
準備が整うと先程作成したコンピューティングインスタンスが設定された状態の画面になります。
次へを押して進みます。
タスクと設定の選択画面では、この学習の目的を設定します。
今回のタスクはIrisの花の分類になりますので分類を選択して次へ。
次の画面では検証とテストの種類を選択します。
検証の種類はいくつかの中から選ぶことができるのですが、せっかくの自動MLですので自動を選びます。
次に、テストデータアセットの欄ではテスト用のデータと学習用のデータを分けることができるようです。
ローカルでのMLのsample.pyに倣い、全データより70%を学習用に、30%をテスト用に使いたいと思いますので下図のように設定しました。
設定が終わったら終了を選択します。
ジョブの画面に戻ると、既にジョブが実行されているのが確認できるはずです。
ここからジョブが終わるのを待つんですが、完了までに47分19秒かかりました。
結果の比較検証
AzureAutoMLの測定値
AutoMLのResultは下図の通りの形式で出力されました。
結果はAccuracy: 0.967、 AUC_macro: 1 というものになりました。
Accuracyに関しては下記の通りに説明されています
Accuracy (正確性) は、分類モデルの利点をケース全体に対する真の結果の割合として測定します。
モデルの評価: コンポーネント リファレンス - Azure Machine Learning | Microsoft Learn
https://learn.microsoft.com/ja-jp/azure/machine-learning/component-reference/evaluate-model
AUC_macroは混同行列による性能評価を分類ごとにとって、その平均を求めたものです。
下記の記事にわかりやすい説明があります。
【評価指標】ROC 曲線と AUC についてわかりやすく解説してみた | キカガクの技術ブログ
https://blog.kikagaku.co.jp/roc-auc
ちなみに、測定指標は出力されるグラフ中のペンのアイコンから複数の中から選べるようになっています。
AzureAutoMLの測定値の出力はこれで分かったのですが、以下ではローカルのML(sample.py)中の各モデルにおけるscore()が何を求めているのかということに目を向けてみます。
Scikit-learnにおける各モデルのscore()の導き方について調べました。
LogisticRegressionの測定値(score())
sklearn.linear_model.LogisticRegression — scikit-learn 1.2.2 documentation
https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html
KNeighborsClassifierの測定値(score())
参照: sklearn.neighbors.KNeighborsClassifier — scikit-learn 1.2.2 documentation
https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html
DecisionTreeClassifierの測定値(score())
参照: sklearn.tree.DecisionTreeClassifier — scikit-learn 1.2.2 documentation
https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
それぞれのアルゴリズムすべて
Return the mean accuracy on the given test data and labels.
In multi-label classification, this is the subset accuracy which is a harsh metric since you require for each sample that each label set be correctly predicted.
という説明です。
ここでmean accuracyつまり平均の精度を取ってきているというのが、AzureAutoMLのAccuracyとは微妙に説明が異なっているようです。
おそらくここで言う平均とは分類ごとの精度の平均を取っているということだと推測します。
ということで値の比較はあくまで参考程度とお考えください。
今回使用した機械学習アルゴリズムについての詳細は以下を参照してください。
キカガク(KIKAGAKU)で機械学習実践(教師あり学習)を学ぶ
https://www.rteak.com/2020/04/kikagaku2.html
まとめ
ローカルでMLを実行した結果とAzureAutoMLを実行した結果を簡単に比較すると以下のようになりました。
AzureAutoML | ローカルML | |
---|---|---|
かかった時間 | 47分19秒 | 約16ミリ秒 |
精度 | 約0.96 | 約0.97 (3アルゴリズムの測定値平均) |
以上の実験のような限定された条件下においては上記のような結果になりましたが、AzureAutoMLがクラウド環境におけるMLということで、より大量かつ複雑なデータを処理するとなった場合、結果は逆転する可能性は十分にあります。
その際には、どんな性能のクラスターを何個、何時間使うのか、という経済的コストも計算に入れて測定する必要があると思いますが。
Irisの花のデータセット程度の解析の場合、ローカルでのMLの方が環境構築の手間を除けば圧倒的にコストが良いという結論です。
以上、ここまでご覧いただきありがとうございました。
追記: 2023年4月19日
Microsoft Azure Machine Learning Studio上で作成したモデルをオンラインで使えるようにするための方法を下記の記事にまとめました。
補足: Azure上のJupyter Notebookについて
Jupyter Notebookとはブラウザ上に用意できて簡単にPythonの実行結果が得られるIDE(統合開発環境)のひとつです。
AzureMLではAzureML Studioの画面の左側のNotebookを選択することで利用可能です。
なお、予めコンピューティング画面において利用するコンピューティングインスタンスを設定しておく必要があります。
ファイルを追加して、sample.pyを入力して実行してみます。
コンピューティングインスタンスの欄でどのリソースで実行するのかを確認したのち、画面左側の再生ボタンを押すと、コードが実行されます。
コードの下部に実行結果が表示されました。
Jupyter Notebookには予め主要なパッケージがインストールされている場合が多く、今回もコードに用いられている全てのパッケージのインポートに成功して、なんの問題もなく実行できました。
2023年3月22日時点におけるAzureML上Notebookで使えるパッケージの一覧を取得したところ、下記の通りになりました。
adal 1.2.7
aiosignal 1.3.1
alembic 1.9.2
argcomplete 2.0.0
asttokens 2.0.5
attrs 22.2.0
azure-ai-ml 1.2.0
azure-common 1.1.28
azure-core 1.26.2
azure-graphrbac 0.61.1
azure-identity 1.12.0
azure-mgmt-authorization 3.0.0
azure-mgmt-containerregistry 10.0.0
azure-mgmt-core 1.3.2
azure-mgmt-keyvault 10.1.0
azure-mgmt-resource 21.2.1
azure-mgmt-storage 20.1.0
azureml-core 1.48.0
azureml-dataprep 4.8.4
azureml-dataprep-native 38.0.0
azureml-dataprep-rslex 2.15.2
azureml-fsspec 0.1.0b3
azureml-mlflow 1.48.0
azure-storage-blob 12.14.1
azure-storage-file-datalake 12.9.1
azure-storage-file-share 12.10.1
backcall 0.2.0
backports.tempfile 1.0
backports.weakref 1.0.post1
bcrypt 4.0.1
cachetools 5.2.1
certifi 2022.6.15
cffi 1.15.1
charset-normalizer 3.0.1
click 8.0.4
cloudpickle 2.2.0
colorama 0.4.6
contextlib2 21.6.0
contourpy 1.0.7
cryptography 39.0.0
cycler 0.11.0
Cython 0.29.33
databricks-cli 0.17.4
debugpy 1.5.1
decorator 5.1.1
distlib 0.3.6
distro 1.8.0
docker 6.0.1
dotnetcore2 3.1.23
entrypoints 0.4
executing 0.8.3
filelock 3.9.0
Flask 2.2.2
fonttools 4.38.0
frozenlist 1.3.3
fsspec 2022.11.0
gitdb 4.0.10
GitPython 3.1.30
google-api-core 2.11.0
googleapis-common-protos 1.58.0
google-auth 2.16.0
greenlet 2.0.1
grpcio 1.43.0
gunicorn 20.1.0
humanfriendly 10.0
idna 3.4
imageio 2.24.0
importlib-metadata 5.2.0
ipykernel 6.9.1
ipython 8.4.0
isodate 0.6.1
itsdangerous 2.1.2
jedi 0.18.1
jeepney 0.8.0
Jinja2 3.1.2
jmespath 1.0.1
joblib 1.2.0
jsonpickle 2.2.0
jsonschema 4.17.3
jupyter-client 7.2.2
jupyter-core 4.10.0
kiwisolver 1.4.4
knack 0.10.1
llvmlite 0.39.1
Mako 1.2.4
Markdown 3.4.1
MarkupSafe 2.1.2
marshmallow 3.19.0
matplotlib 3.6.3
matplotlib-inline 0.1.2
mldesigner 0.1.0b9
mlflow 2.1.1
mlflow-skinny 2.1.1
mltable 1.0.0
msal 1.20.0
msal-extensions 1.0.0
msgpack 1.0.4
msrest 0.7.1
msrestazure 0.6.4
ndg-httpsclient 0.5.1
nest-asyncio 1.5.5
networkx 3.0
numba 0.56.4
numpy 1.24.1
oauthlib 3.2.2
opencensus 0.11.1
opencensus-context 0.1.3
opencensus-ext-azure 1.1.8
packaging 21.3
pandas 1.5.2
paramiko 2.12.0
parso 0.8.3
pathspec 0.10.3
pexpect 4.8.0
pickleshare 0.7.5
Pillow 9.4.0
pip 22.3.1
pkginfo 1.9.6
platformdirs 2.6.2
portalocker 2.7.0
prompt-toolkit 3.0.20
protobuf 3.20.3
psutil 5.9.4
ptyprocess 0.7.0
pure-eval 0.2.2
pyarrow 10.0.1
pyasn1 0.4.8
pyasn1-modules 0.2.8
pycparser 2.21
pydash 5.1.2
Pygments 2.11.2
PyJWT 2.6.0
PyNaCl 1.5.0
pyOpenSSL 22.1.0
pyparsing 3.0.9
pyrsistent 0.19.3
PySocks 1.7.1
python-dateutil 2.8.2
pytz 2022.7.1
PyWavelets 1.4.1
PyYAML 6.0
pyzmq 23.2.0
querystring-parser 1.2.4
ray 2.0.0
requests 2.28.2
requests-oauthlib 1.3.1
rsa 4.9
scikit-image 0.19.3
scikit-learn 1.2.0
scipy 1.10.0
SecretStorage 3.3.3
setuptools 65.6.3
shap 0.41.0
six 1.16.0
slicer 0.0.7
smmap 5.0.0
SQLAlchemy 1.4.46
sqlparse 0.4.3
stack-data 0.2.0
strictyaml 1.6.2
tabulate 0.9.0
threadpoolctl 3.1.0
tifffile 2022.10.10
tornado 6.1
tqdm 4.64.1
traitlets 5.1.1
typing-extensions 4.4.0
urllib3 1.26.14
virtualenv 20.17.1
wcwidth 0.2.5
websocket-client 1.4.2
Werkzeug 2.2.2
wheel 0.37.1
zipp 3.11.0
以上でAzure上のJupyter Notebookについての補足説明を終わります。