Databricks Community Editionを使ってDatabricksの機械学習を体験してみる

本書では、無償で利用できる[Databricks Community Edition](https://community.cloud.databricks.com/)を使ってDatabricksの基本的な機能をウォークスルーします。GUIなどが更新されているので、2022/8/3時点のGUIで説明をしていきます。

後半で使用しているノートブックはこちらです。

https://github.com/taka-yayoi/public_repo/tree/main/mlflow_ce

# Databricksとは

[データブリックス](https://databricks.com/jp)は、学術界とオープンソースコミュニティをルーツとするデータ＋AIの企業です。Apache Spark™、Delta Lake、MLflowの開発者グループによる2013年の創業以来、最新の[レイクハウス](https://qiita.com/taka_yayoi/items/438f762126f57868aa35)アーキテクチャを基盤に、データウェアハウスとデータレイクの優れた機能を取り入れた、データとAIのためのクラウドベースのオープンな統合プラットフォームを提供しています。

このレイクハウスプラットフォームをご利用いただくことで、機械学習モデルのトレーニングはもちろん、機械学習モデルの運用管理、ETLパイプラインの開発・運用、データの蓄積、BIなど様々なワークロードを一つのプラットフォーム上で効率的に実施いただけるようになります。

:::note
**参考資料**
- [レイクハウスとは何？](https://qiita.com/taka_yayoi/items/438f762126f57868aa35)
- [Databricksの良いところ\(Jupyter notebookとの比較\)](https://qiita.com/taka_yayoi/items/d5ea3dede05a180091b2)
- [データレイクハウスに関するFAQ](https://qiita.com/taka_yayoi/items/04888e5fd08a621511e4)
- [Databricksのアーキテクチャ](https://qiita.com/taka_yayoi/items/7d209bc8d32bc5f2dba4)
:::

# Databricks Community Editionとは

Databricksではその機能を無償でお試しいただけるよう、2通りの方法を用意しております。

- 2週間の無償トライアル: Databricksのすべての機能を2週間無償でお試しいただけます。
- **Community Edition**: 利用できる機能が限定されますが、期限なし・無償でご利用いただけます。

本記事では、**Community Edition**を通じて、Databricksの基本的な機能を体験いただきます。

:::note
**参考資料**
- [IBJP: Community Editionで始めるDatabricks – Databricks](https://databricks.com/jp/international-blogs/get-started-with-databricks-community-edition-jp)
- [Databricksフリートライアルへのサインアップ](https://qiita.com/taka_yayoi/items/fb4f57c069e1f272e88a)
:::

# Databricks Community Editionへのサインアップ

以下のステップを実行することで、Databrikcs Community Editionのワークスペースを無料で利用できるようになります。

1. https://databricks.com/jp/try-databricks にアクセスします。
![Screen Shot 2022-08-03 at 7.34.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e48862e7-94db-9ba7-2226-fadbc8ef1ca8.png)
1. フォームに必要情報を入力し、**無料トライアルを開始**をクリックします。
1. **コミュニティ版を使ってみる**のリンクをクリックします。
![Screen Shot 2022-08-03 at 7.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/13a880c5-f640-5098-1f27-c51ec244dc1f.png)
1. **検証**ダイアログが表示される場合には指示に従って検証を受けます。
![Screen Shot 2022-08-03 at 7.34.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1d74101a-7a2f-1568-2445-132ca971e330.png)
1. 確認メールが送信された旨の画面が表示されます。
![Screen Shot 2022-08-03 at 7.35.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f6f72452-9061-f412-ae74-f139c34e3a08.png)
1. 最初に指定したメールアドレスに確認メールが届いていない確認します。場合によっては迷惑メールと判別されることがあるため、メーワクメールのフォルダも確認します。メールに記載されている**Get started by visiting**のリンクをクリックします。
![Screen Shot 2022-08-03 at 7.36.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f27b6b8a-f470-825e-5ad0-e6b64722ffbb.png)
1. パスワードを設定する画面が表示されるので、パスワードを指定して**パスワードをリセット**をクリックします。以降、Databricks Community Editionにログインする際には、Community EditionのURL https://community.cloud.databricks.com/ とメールアドレス、パスワードが必要となります。
![Screen Shot 2022-08-03 at 7.36.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f481da07-a13e-2054-b526-95d0f1733826.png)
1. これでDatabricks Community Editionへのログインが完了しました。
![Screen Shot 2022-08-03 at 7.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/abe78d6a-68ed-9ffb-e3a0-d9d6b4ce1e65.png)

# Databricksのウォークスルー

## Databricks Community Editionの画面構成

Databricksでは、ノートブック上にロジックを記述してそれを実行することで様々な処理を行います。この観点ではJuypter notebookと非常に近いUIを持っていると言えます。しかし、[様々な点で強化・拡張](https://qiita.com/taka_yayoi/items/d5ea3dede05a180091b2)がなされているのがDatabricksです。

画面の左側のサイドメニューにマウスカーソルを移動するとメニューが展開されます。基本的な機能にはこちらからアクセスすることになります。
![Screen Shot 2022-08-03 at 8.03.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9c100657-915c-c120-9bd0-1236e9c6fa0e.png)

各項目については、以下の参考資料をご覧ください。ここでは、クラスターを作成するためにメニューから**クラスター**をクリックします。

:::note
**参考資料**
- [Databricksワークスペースをナビゲートする](https://qiita.com/taka_yayoi/items/dd41cd715aca272ff5ce)
:::

## クラスターの作成

[クラスター](https://qiita.com/taka_yayoi/items/c5d99cd77fe4bfcf69f0)とは、機械学習モデルのトレーニングやデータの加工を行う際に必要となる計算資源です。Databricksでは大量のデータを高速に処理できるように複数の仮想マシンをまとめて**クラスター**として構成します。Databricksクラスターを用いることで、従来であれば手間のかかる環境構築(仮想マシンの設定、ソフトウェアのインストールなど)をGUIからの操作で手軽に行えるようになります。

1. クラスターの一覧が表示されます。この時点ではクラスターは存在していないため一覧は空の状態です。左上にある**クラスターの作成**ボタンをクリックします。
![Screen Shot 2022-08-03 at 7.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f5e40268-a40b-7f25-b9b5-575ed987a38d.png)
1. この画面で作成するクラスターの設定を行います。ここでは、**クラスター名**と**Databricks Runtimeのバージョン**を指定します。

    - **クラスター名**: taka clusterなど人が見てわかりやすい名前を指定してください。
    - **Databricks Runtimeのバージョン**: Databricks Runtimeとはクラスターに自動でインストールされるソフトウェアのパッケージです。Pythonの実行環境やPythonライブラリなどが含まれています。ここでは、`Runtime 10.5 ML`を選択します。

    ![Screen Shot 2022-08-03 at 7.38.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e2eecb5b-e403-2fdc-9bc0-e6cd84bc2f02.png)

1. **クラスターを作成**をクリックするとクラスターが作成されます。クラスターが作成され、起動するまでに数分要しますのでお待ちください。作成が完了するとクラスター名の右側に緑のチェックマーク入りのアイコンが表示されます。
![Screen Shot 2022-08-03 at 8.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/df3d013e-4179-c628-f2ae-be32926a1a64.png)

## ノートブックの作成

次に、ロジックを記述する[ノートブック](https://qiita.com/taka_yayoi/items/24a897cf40bba6d9e305)を作成します。

1. サイドメニューの**ワークスペース**をクリックします。ワークスペースは名前の通り、皆様の作業場でありノートブックを格納する場所となります。
![Screen Shot 2022-08-03 at 8.13.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/bb65b30f-84d8-64e6-69f4-0343519e5e67.png)
1. ワークスペース配下には**Shared**と**Users**というフォルダが存在しています。**Shared**はワークスペース内で他のユーザーとノートブックを共有するための置き場所として使用します。**Users**はそれぞれのユーザーごとのホームフォルダが格納されています。
1. ホームフォルダにノートブックを作成するので**ホーム**ボタンをクリックして、自分のホームフォルダに移動します。
![Screen Shot 2022-08-03 at 8.13.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/4308a05e-029d-8460-5594-70e5f1d58849.png)
1. ホームフォルダは自分のメールアドレスの名称となっています。ここにフォルダを作成したり、ノートブックを格納することになります。
![Screen Shot 2022-08-03 at 8.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1353593d-0798-7eaa-d5a2-e614a6a32749.png)
1. ホームフォルダ名(自分のメールアドレス)の右にある下向きの矢印をクリックします。
![Screen Shot 2022-08-03 at 8.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7fdb70e2-953e-5790-4d9f-1f485961b26f.png)
1. メニューが表示されるので**作成 > ノートブック**を選択します。
![Screen Shot 2022-08-03 at 8.28.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f56b4a27-fc1d-ede9-93f2-41a3ce2c507f.png)
1. ダイアログが表示されます。以下の内容を指定して、**作成**をクリックします。
    - **名前**: わかりやすいノートブックの名前をつけます。
    - **デフォルト言語**: Pythonのままとします。なお、SQL、Rなど他の言語を指定することもできます。
    - **クラスター**: [上のステップ](#クラスターの作成)で作成、起動したクラスターを選択します。
![Screen Shot 2022-08-03 at 8.29.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/cebac980-6121-4586-69ae-fd106ebaa700.png)
1. これでノートブックが作成されるのと同時に、ノートブックがクラスターに関連づけ(アタッチ)されます。アタッチされているクラスターは画面左上のリストで確認することができます。ノートブックの処理を実行するには稼働中のクラスターにアタッチする必要があります。編集のみを行う際にはクラスターは不要です。
![Screen Shot 2022-08-03 at 8.31.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/cd5c9a69-77d6-2d9b-9c8a-1483dc781f11.png)

:::note info
**ティップス**
フルバージョンのDatabricksではフォルダやノートブックなどにアクセス権を設定できるので、ユーザー間でセキュアに資産のやり取りを行うことができます。
:::

## ノートブックの実行

すでにノートブックが表示されていますので、Juypter notebookを使うのと同様にPythonの処理を記述、実行することができます。

1. 一つ目のセルにカーソルを移動し、以下の内容を記述します。

    ```py:Python
    print("test")
    ```

1. セルを実行するにはいくつかの方法がありますが、ここではセルの右端に表示されているメニューから実行します。再生ボタンをクリックするとメニューが展開されます。
![Screen Shot 2022-08-03 at 8.35.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b688c9b0-665e-23d1-f294-4bcb7f0b8ac5.png)
1. **▶︎セルを実行**をクリックすると当該セルが実行されます。
![Screen Shot 2022-08-03 at 8.36.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c877e66a-816e-98c1-ddcc-772569289b86.png)
1. 以下のように結果が表示されます。
![Screen Shot 2022-08-03 at 8.37.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b514812e-1b1c-ab24-de76-2bf843aa99bc.png)

:::note info
**ティップス**
上に表示されているように、Shift+Enterキーを押してもセルを実行することができます。
:::

新たにセルを追加するには、追加したい場所にカーソルを移動すると`+`マークが表示されるのでこれをクリックすることでセルの上下に追加することができます。

![Screen Shot 2022-08-03 at 8.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5b5bfc38-5cc0-bf5a-0fbe-b5a443e6cf5f.png)

![Screen Shot 2022-08-03 at 8.40.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/83345d71-1393-851d-d7d3-cf2e5ccfd3a2.png)

:::note
**参考資料**
- [Databricksノートブックを使う](https://qiita.com/taka_yayoi/items/dfb53f63aed2fbd344fc)
- [Databricksノートブックを管理する](https://qiita.com/taka_yayoi/items/c306161906d6d34e8bd5)
:::

# Databricksで機械学習を体験してみる

最後にDatabricksでの機械学習を体験してみます。

## ノートブックのインポート

上ではノートブックを作成しましたが、インターネットで公開されているノートブックなどを簡単に取り込むこともできます。

1. サイドメニューの**ワークスペース**をクリックします。
1. **ホーム**ボタンをクリックして、自分のホームフォルダに移動します。
1. ホームフォルダ名(自分のメールアドレス)の右にある下向きの矢印をクリックします。
1. メニューが表示されるので**インポート**を選択します。
![Screen Shot 2022-08-03 at 9.12.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1d65e113-a03a-518e-85b0-b36d7133a961.png)
1. ダイアログが表示されます。以下を指定して**インポート**をクリックします。

    インポート元: `URL`を選択します。
    テキストボックス: 以下のURLを貼り付けます。

    ```
    https://raw.githubusercontent.com/taka-yayoi/public_repo/main/mlflow_ce/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%3A%20%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%83%88%E3%83%AC%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0(CE).py
    ```

    ![Screen Shot 2022-08-03 at 9.12.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1d5c6084-814e-e930-0dbe-f97448f3b859.png)

1. 以下のようにノートブックがインポートされます。
![Screen Shot 2022-08-03 at 9.15.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b15b9114-ac33-c147-884c-115a3bf1cbc2.png)

1. 画面左上で[上のステップ](#クラスターの作成)で作成したクラスターを選択します。

## ノートブックを実行

インポートしたノートブックに記載の指示に従ってノートブックを実行してください。

このノートブックでは、Databricksにおける機械学習モデルトレーニングの概要を説明します。モデルをトレーニングするには、Databricks機械学習ランタイムにプレインストールされているscikit-learnのようなライブラリを利用することできます。加えて、トレーニングしたモデルをトラッキングするためにMLflowを利用したり、ハイパーパラメーターチューニングをスケールさせるために、HyperoptとSparkTrialsを活用することができます。

このチュートリアルでは以下を行います:
- Part 1: MLflowトラッキングを用いたシンプルな分類モデルのトレーニング
- Part 2: より良いモデルを得るためのHyperoptを用いたハイパーパラメーターチューニング

モデルのライフサイクル管理やモデルの推論などDatabricksにおける機械学習の本格運用に関しては、[エンドツーエンドのサンプル](https://qiita.com/taka_yayoi/items/f48ccd35e0452611d81b)をご覧ください。

### ライブラリのインポート

必要なライブラリをインポートします。これらのライブラリは[Databricks機械学習ランタイム](https://qiita.com/taka_yayoi/items/824b507019d3ade7eedc)にプレインストールされており、互換性とパフォーマンスに関してチューニングされています。

```py:Python
import mlflow
import numpy as np
import pandas as pd
import sklearn.datasets
import sklearn.metrics
import sklearn.model_selection
import sklearn.ensemble

from hyperopt import fmin, tpe, hp, SparkTrials, Trials, STATUS_OK
from hyperopt.pyll import scope
```

### データのロード

このチュートリアルでは、異なるワインのサンプルからなるデータセットを使用します。この[データセット](https://archive.ics.uci.edu/ml/datasets/Wine)は、UCI Machine Learning Repositoryからのもので、[DBFS](https://qiita.com/taka_yayoi/items/897264c486e179d72247)に格納されています。ここでのゴールは、品質に基づいて赤ワイン・白ワインを分類するというものです。

他のデータソースからデータをアップロード、ロードする方法の詳細に関しては、データの取り扱いに関するドキュメント([AWS](https://docs.databricks.com/data/index.html)|[Azure](https://docs.microsoft.com/azure/databricks/data/index))をご覧ください。

以下のコマンドはCommunity Editionの制限に対応するためのものです。詳細は[こちら](https://databricks.com/jp/international-blogs/get-started-with-databricks-community-edition-jp)の**よくある質問**を参照ください。

```py:Python
dbutils.fs.cp('dbfs:/databricks-datasets/wine-quality/winequality-white.csv', 'file:/tmp/winequality-white.csv')
dbutils.fs.cp('dbfs:/databricks-datasets/wine-quality/winequality-red.csv', 'file:/tmp/winequality-red.csv')
```

```py:Python
# データのロード、前処理
white_wine = pd.read_csv("/tmp/winequality-white.csv", sep=';')
red_wine = pd.read_csv("/tmp/winequality-red.csv", sep=';')
white_wine['is_red'] = 0.0
red_wine['is_red'] = 1.0
data_df = pd.concat([white_wine, red_wine], axis=0)

# ワイン品質に基づく分類ラベルの定義
data_labels = data_df['quality'] >= 7
data_df = data_df.drop(['quality'], axis=1)

# 80/20でトレーニング、テストデータセットに分割
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
  data_df,
  data_labels,
  test_size=0.2,
  random_state=1
)
```

### Part 1. 分類モデルのトレーニング

#### MLflowトラッキング

機械学習のライフサイクルを管理するソフトウェアである[MLflow](https://mlflow.org/)の[MLflowトラッキング](https://www.mlflow.org/docs/latest/tracking.html)を用いることで、お使いの機械学習トレーニングのコード、パラメーター、モデルを整理することができます。 

[*autologging*](https://www.mlflow.org/docs/latest/tracking.html#automatic-logging)を用いることで、自動MLflowトラッキングを有効化することができます。

```py:Python
# このノートブックにおけるMLflowオートロギングを有効化
mlflow.autolog()
```

次に、MLflowランのコンテキストで分類器をトレーニングし、トレーニングしたモデル、関連するメトリクス、パラメーターを自動で記録します。

モデルのAUCスコアやテストデータセットのような追加メトリクスを記録することもできます。

```py:Python
with mlflow.start_run(run_name='gradient_boost') as run:
  model = sklearn.ensemble.GradientBoostingClassifier(random_state=0)
  
  # モデル、パラメーター、トレーニングメトリクスが自動で記録されます
  model.fit(X_train, y_train)

  predicted_probs = model.predict_proba(X_test)
  roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
  
  # テストデータにおけるAUCスコアは自動で記録されないので、手動で記録します
  mlflow.log_metric("test_auc", roc_auc)
  print("Test AUC of: {}".format(roc_auc))
```

上のセルを実行すると、モデルのトレーニングが行われるのと同時に機械学習モデルがMLflowによって記録されます。
![Screen Shot 2022-08-03 at 19.05.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/04b26df7-914d-1559-b51d-e073aff35148.png)

画面右上の**エクスペリメント**に**1**というバッジが表示されているかと思います。こちらをクリックすることで記録されたモデルを確認することができます。
![Screen Shot 2022-08-03 at 19.13.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b725c908-be9c-c003-ceb9-7146aa784c02.png)

このモデルのパフォーマンスに満足できないのであれば、異なるハイパーパラメータを指定して別のモデルをトレーニングします。

```py:Python
# 後で参照できるようにrun_nameを指定して新たなランを実行します
with mlflow.start_run(run_name='gradient_boost') as run:
  model_2 = sklearn.ensemble.GradientBoostingClassifier(
    random_state=0, 
    
    # n_estimatorsに対して新たなパラメーターを指定してみます
    n_estimators=200,
  )
  model_2.fit(X_train, y_train)

  predicted_probs = model_2.predict_proba(X_test)
  roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
  mlflow.log_metric("test_auc", roc_auc)
  print("Test AUC of: {}".format(roc_auc))
```

記録されたモデルの数でバッジが更新されます。
![Screen Shot 2022-08-03 at 19.14.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0bc9be64-9164-52a2-0cd7-37b233a5670d.png)

#### MLflowランの参照

記録されたトレーニングランを参照するには、エクスペリメントサイドバーを表示するために、ノートブックの右上の**エクスペリメント**アイコンをクリックします。必要であれば、最新の状態を表示するためにリフレッシュアイコンをクリックします。

<img width="350" src="https://docs.databricks.com/_static/images/mlflow/quickstart/experiment-sidebar-icons.png"/>

より詳細なMLflowエクスペリメントページ([AWS](https://docs.databricks.com/applications/mlflow/tracking.html#notebook-experiments)|[Azure](https://docs.microsoft.com/azure/databricks/applications/mlflow/tracking#notebook-experiments))を表示するために、エクスペリメントページアイコン(右上矢印のアイコン)をクリックすることができます。このページでは、ランを比較したり、特定のランの詳細を参照できます。

<img width="800" src="https://docs.databricks.com/_static/images/mlflow/quickstart/compare-runs.png"/>

#### モデルのロード

MLflow APIを用いて特定のランの結果にアクセスすることもできます。以下のセルのコードでは、特定のMLflowランにおいてトレーニングされたモデルをロードして予測を行う方法を示しています。[MLflowランページ](https://qiita.com/taka_yayoi/items/ba0c7f46ff7c3dbf87bb#%E3%83%8E%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E5%8F%82%E7%85%A7)で特定のモデルをロードするためのコードスニペットを参照することもできます。

```py:Python
# モデルが記録された後は、別のノートブックやジョブからロードすることができます
# mlflow.pyfunc.load_modelを用いることで一般的なAPIを用いたモデルの予測が可能になります
model_loaded = mlflow.pyfunc.load_model(
  'runs:/{run_id}/model'.format(
    run_id=run.info.run_id
  )
)

predictions_loaded = model_loaded.predict(X_test)
predictions_original = model_2.predict(X_test)

# ロードしたモデルはオリジナルと一致しなくてはなりません
assert(np.array_equal(predictions_loaded, predictions_original))
```

### Part 2. ハイパーパラメーターチューニング

ここまでで、あなたはシンプルなモデルをトレーニングし、あなたの作業を整理するためにMLflowサービスを使用しました。このセクションでは、Hyperoptを用いてどのように洗練されたチューニングを行うのかをカバーします。

#### Hyperopt、SparkTrialsによる並列トレーニング

[Hyperopt](http://hyperopt.github.io/hyperopt/)はハイパーパラメーターチューニングのためのPythonライブラリです。DatabricksにおけるHyperoptの詳細に関しては[ドキュメント](https://qiita.com/taka_yayoi/items/238ecf8b038151b84bc1)を参照ください。

並列でハイパーパラメーターの探索、複数のモデルのトレーニングを実行するために、HyperoptとSparkTrialsを活用することができます。これにより、モデルのパフォーマンス最適化に必要な時間を短縮することができます。MLflowトラッキングはHyperoptとインテグレーションされているので、モデルとパラメーターを自動で記録します。

:::note warn
**注意**
Community Editionのクラスターで以下を実行すると約7分かかります。速度を上げるにはクラスター構成のノード数を増やし(フルバージョンのDatabricksでは可能です)、並列度を上げるといった対策が可能です。
:::

```py:Python
# 探索する検索空間を定義
search_space = {
  'n_estimators': scope.int(hp.quniform('n_estimators', 20, 1000, 1)),
  'learning_rate': hp.loguniform('learning_rate', -3, 0),
  'max_depth': scope.int(hp.quniform('max_depth', 2, 5, 1)),
}

def train_model(params):
  # ワーカーごとにautologgingを有効化
  mlflow.autolog()
  with mlflow.start_run(nested=True):
    model_hp = sklearn.ensemble.GradientBoostingClassifier(
      random_state=0,
      **params
    )
    model_hp.fit(X_train, y_train)
    predicted_probs = model_hp.predict_proba(X_test)
    # テストデータセットのAUCに基づくチューニング
    # 実運用の環境においては、別に検証用データセットを用いることになるかもしれません
    roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
    mlflow.log_metric('test_auc', roc_auc)
    
    # 損失関数を-1*auc_scoreに設定し、fminがauc_scoreを最大化するようにします
    return {'status': STATUS_OK, 'loss': -1*roc_auc}

# SparkTrialsは、Sparkのワーカーを用いてチューニングを分散します
# 並列度を上げれば処理速度を向上しますが、それぞれのハイパーパラメーターのトライアルは他のトライアルから得られる情報が減ります
# 小規模クラスターやDatabricksコミュニティエディションではparallelism=2を設定するようにしてください
spark_trials = SparkTrials(
  parallelism=8
)

with mlflow.start_run(run_name='gb_hyperopt') as run:
  # 最大のAUCを達成するパラメーターを見つけるためにhyperoptを使用します
  best_params = fmin(
    fn=train_model, 
    space=search_space, 
    algo=tpe.suggest, 
    max_evals=32,
    trials=spark_trials)
```

上を実行している時点で画面右上の**エクスペリメント**をクリックすると、大量のモデルが記録されていることがわかります。大量のモデルをトレーニングしたとしても、MLflowが自動で管理してくれるので、データサイエンティストの方はモデルのトレーニングに集中することができます。
![Screen Shot 2022-08-03 at 19.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f41ddd40-013d-e802-e598-e6bb6f4c78cc.png)

#### ベストモデルを取得するためにランを検索

すべてのラン(MLflowにおいて1回の機械学習モデルトレーニングを指します)はMLflowによってトラッキングされているので、MLflowのsearch runs APIを用いて、最も高いAUCを出したベストのモデルのメトリクスとパラメーターを取得することができます。

チューニングされたモデルは、Part 1でトレーニングしたシンプルなモデルよりも高いパフォーマンスを示すべきです。

```py:Python
# テストデータセットにおけるAUCでランをソートします。同じ順位の場合には最新のランを採用します
best_run = mlflow.search_runs(
  order_by=['metrics.test_auc DESC', 'start_time DESC'],
  max_results=10,
).iloc[0]
print('Best Run')
print('AUC: {}'.format(best_run["metrics.test_auc"]))
print('Num Estimators: {}'.format(best_run["params.n_estimators"]))
print('Max Depth: {}'.format(best_run["params.max_depth"]))
print('Learning Rate: {}'.format(best_run["params.learning_rate"]))

best_model_pyfunc = mlflow.pyfunc.load_model(
  'runs:/{run_id}/model'.format(
    run_id=best_run.run_id
  )
)
best_model_predictions = best_model_pyfunc.predict(X_test[:5])
print("Test Predictions: {}".format(best_model_predictions))
```
![Screen Shot 2022-08-03 at 19.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f22ee069-b5bf-b6ba-4779-cd1446d01a7a.png)

#### 複数のランをUIで比較

Part 1と同じように、**エクスペリメント**サイドバーの上にある外部リンクアイコンからアクセスできるMLflowエクスペリメント詳細ページでランを参照、比較することができます。
![Screen Shot 2022-08-03 at 19.25.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9f29fa77-6789-8528-d9e2-ded184e4c8dc.png)

エクスペリメント詳細ページで、親のランを展開するために"+"アイコンをクリックし、親以外の全てのランを選択、**比較**をクリックします。
![Screen Shot 2022-08-03 at 19.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9d20fc4e-e2f3-bef3-15b0-b4a425182711.png)

下2行のランはハイパーパラメーターチューニングでトレーニングしたものではないので、チェックは外すようにしてください。
![Screen Shot 2022-08-03 at 19.27.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1c3ae73e-897e-7823-7ee3-65eac6b32bbb.png)

それぞれのパラメーターのメトリックに対するインパクトを表示するparallel coordinates plotを用いて、異なるランを可視化することができます。
![Screen Shot 2022-08-03 at 19.28.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/45a1cf9c-d769-bcf6-9354-227c1eda5e50.png)

グラフの一番右の`loss`の軸で範囲を選択するとその部分のlossを導き出したハイパーパラメーターの組み合わせがハイライトされます。これによって、今後精度を高めていくためにはどのようなハイパーパラメーターを探索していったらいいのかの方向性を見極めることが可能となります。
![Screen Shot 2022-08-03 at 19.29.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/79ca464c-bcdc-2ac1-8c21-3a71c350e703.png)

# まとめ

今回は、Databricks Community Edition上でscikit-learnを用いた機械学習モデルのトレーニングおよびトラッキング、ハイパーパラメータチューニングを体験いただきました。

もちろん、Databricksではこれ以外にも様々な機能を提供しています。興味のある方は以下の記事を参照してみてください。

**参考資料**
- [Databricksチュートリアル](https://qiita.com/taka_yayoi/items/4603091dd325c77d577f)
- [Databricks Community Editionで画像データを分析してみる](https://qiita.com/taka_yayoi/items/1c02542125bc327282d5)
- [無料のDatabricks Community EditionでSpark NLPを使って自然言語処理をやってみる](https://qiita.com/taka_yayoi/items/ebec25578a7cfe2f50b0)
- [Databricks Community EditionはDatabricksと何が違うのか？](https://qiita.com/taka_yayoi/items/800fd2714f460a9a1c40)
- [Databricksクイックスタートガイド](https://qiita.com/taka_yayoi/items/125231c126a602693610)
- [Databricks記事のまとめページ](https://qiita.com/taka_yayoi/items/c6907e2b861cb1070f4d)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)