Databricks AutoMLの動作原理

[How Databricks AutoML works \| Databricks on AWS](https://docs.databricks.com/machine-learning/automl/how-automl-works.html) [2023/2/21時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本書ではDatabricks AutoMLの動作原理や、欠損値の補完や[大規模データサンプリング](#大規模データセットのサンプリング)の様な実装の詳細を説明します。

Databricks　AutoMLは以下を実行します:

1. モデルトレーニングに使用するデータセットの準備。例えば、分類問題においてはAutoMLはモデルトレーニングの前に[不均衡データの検知](#分類問題における不均衡データセットのサポート)を実行します。
1. 複数のモルのトレーニングと[チューニング](https://docs.databricks.com/machine-learning/automl-hyperparam-tuning/index.html)の繰り返しを行い、それぞれのモデルはオープンソースのコンポーネントから構成されるので、編集が容易でご自身の機械学習パイプラインに組み込むことができます。
    - AutoMLは自動でハイパーパラメーターチューニングのトライアルをクラスターのワーカーノードに分散します。
    - Databricks Runtime 9.1 LTS ML以降では、シングルワーカーノードのメモリーにデータセットが収まらない場合、AutoMLは自動でデータセットのサンプリングを行います。[大規模データセットのサンプリング](#大規模データセットのサンプリング)をご覧ください。
1. [scikit\-learn](https://scikit-learn.org/stable/)、[xgboost](https://xgboost.readthedocs.io/en/latest/)、[LightGBM](https://lightgbm.readthedocs.io/en/latest/index.html)、[Prophet](https://facebook.github.io/prophet/docs/)、[ARIMA](https://pypi.org/project/pmdarima/)パッケージのアルゴリズムに基づいてモデルを評価します。
1. 結果とそれぞれのトライアルランのソースコードを含むPythonノートブックを表示するので、コードのレビュー、再現、修正を行うことができます。また、ご自身のデータセットのサマリー統計情報を計算し、あとでレビューできるようにこれらの情報をノートブックに保存します。

# AutoMLのアルゴリズム

Databricks AutoMLは、以下の表のアルゴリズムに基づいてモデルをトレーニングし、評価します。

:::note
**注意**
分類モデル、回帰モデルにおいては、決定木、ランダムフォレスト、確率的勾配降下法を用いたロジスティック回帰、線形回帰はscikit-learnをベースとしています。
:::

| 分類モデル | 回帰モデル | 予測モデル |
|:--|:--|:--|
| [Decision trees](https://scikit-learn.org/stable/modules/tree.html#classification)  | [Decision trees](https://scikit-learn.org/stable/modules/tree.html#regression)  | [Prophet](https://facebook.github.io/prophet/docs/quick_start.html#python-api)  |
| [Random forests](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html#sklearn.ensemble.RandomForestClassifier)  |  [Random forests](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html#sklearn.ensemble.RandomForestRegressor) | [Auto\-ARIMA](https://pypi.org/project/pmdarima/)(Databricks Runtime 10.3 ML以降で利用可能)  |
| [Logistic regression](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression)  |   [Linear regression with stochastic gradient descent](https://scikit-learn.org/stable/modules/sgd.html#regression)|   |
|  [XGBoost](https://xgboost.readthedocs.io/en/latest/python/python_api.html#xgboost.XGBClassifier) |  [XGBoost](https://xgboost.readthedocs.io/en/latest/python/python_api.html#xgboost.XGBRegressor) |   |
| [LightGBM](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMClassifier.html)  | [LightGBM](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMRegressor.html)  |   |

# サポートされるデータ特徴量のタイプ

以下でリストされていない特徴量タイプはサポートされていません。例えば、画像はサポートされていません。

以下の特徴量タイプはサポートされています:

- Numeric (`ByteType, ShortType, IntegerType, LongType, FloatType, and DoubleType`)
- Boolean
- String (カテゴリー変数や英語テキスト)
- Timestamps (`TimestampType, DateType`)
- ArrayType[Numeric] (Databricks Runtime 10.4 LTS ML以降)
- DecimalType (Databricks Runtime 11.3 LTS ML以降)

# トレーニング/検証/テストセットへのデータの分割

Databricks Runtime 10.1 ML以降では、分類問題や回帰問題でトレーニング/検証/テストセットへの分割で使用する時間カラムを指定することができます。このカラムを指定すると、データセットは時間に基づいてトレーニング/検証/テストセットに分割されます。もっとも古いデータポイントはトレーニングに使用され、次に古いデータポイントは検証に用いられ、最新のデータポイントはテストセットとして使用されます。

Databricks Runtime 10.1 MLでは、時間カラムはタイムスタンプか整数値である必要があります。Databricks Runtime 10.2 ML以降では文字列のカラムも選択可能です。

# 大規模データセットのサンプリング

:::note
**注意**
サンプリングは予測問題では適用されません。
:::

AutoMLはクラスターのワーカーノードにハイパーパラメーターチューニングのトライアルを分散させますが、それぞれのモデルは単一のワーカーノードでトレーニングされます。

AutoMLは自動でお使いのデータセットのロードとトレーニングに必要なメモリー量を推定し、必要であればデータセットのサンプリングを行います。

Databricks Runtime 9.1 LTS MLからDatabricks Runtime 10.5 MLでは、サンプリングの割合はクラスターのノードタイプやノードごとのメモリー総量に依存しません。

Databricks Runtime 11.x MLでは:

- コアごとのメモリーが多いワーカーノードを使うほどサンプリングの割合が増加します。**memory optimized**インスタンスタイプを選択することでサンプルサイズを増加させることができます。
- クラスターのSpark設定`spark.task.cpus`に大きな値を指定することで、さらにサンプルサイズを増加させることができます。デフォルトの設定は`1`であり、最大はワーカーノードにおけるCPU数となります。この値を増やすとサンプルサイズは大きくなりますが、並列で実行されるトライアルの数は減少します。例えば、4コア64GB RAMを持つマシンにおいて、デフォルトの`spark.task.cpus=1`では、ワーカーごとに4トライアルが実行され、それぞれのトライアルは16GB RAMに限定されます。`spark.task.cpus=4`に設定すると、それぞれのワーカーは1つのみのトライアルを実行しますが、64GB RAMを活用することができます。

Databricks Runtime 12.0 ML以降では、トレーニングタスクごとにより多くのCPUコアを割り当てることで、より大規模なデータセットでのAutoMLトレーニングが可能です。合計メモリー量が大きいインスタンスサイズを選択することで、サンプルサイズを増加させることができます。

Databricks Runtime 11.0 ML以降では、AutoMLがデータセットのサンプリングを行った際、サンプリングの割合がUIの**Overview**タブに表示されます。

分類問題において、AutoMLはターゲットラベルの分布を保持するために、階層化サンプリングを行う際にPySparkの`sampleBy`[メソッド](https://api-docs.databricks.com/python/pyspark/latest/pyspark.sql/api/pyspark.sql.DataFrameStatFunctions.sampleBy.html)を使用します。

回帰問題においては、PySparkの`sample`[メソッド](https://api-docs.databricks.com/python/pyspark/latest/pyspark.sql/api/pyspark.sql.DataFrame.sample.html)を使用します。

# 分類問題における不均衡データセットのサポート

Databricks Runtime 11.2 ML以降において、AutoMLがデータセットの不均衡を検知すると主要なクラスをダウンサンプルし、クラスの重みを追加することで、トレーニングデータセットの不均衡を削減しようとします。AutoMLはトレーニングデータセットのバランスのみを取り、テストデータセットや検証用データセットのバランスは取りません。このようにすることで、補強されておらず真のクラス分布を持つデータセットを用いて常にモデルのパフォーマンスが評価される様になります。

不均衡なトレーニングデータセットのバランスを取るために、AutoMLは特定のクラスがサウンサンプリングされる度合いと逆比例するクラスの重みを使用します。例えば、100サンプルのトレーニングデータセットで95サンプルがクラスAに属しており、5サンプルがクラスBに属している場合、AutoMLはクラスAが70サンプルになる様にダウンサンプリングを行い、70/95あるいは0.736の比率でクラスAをダウンサンプリングしますが、クラスBのサンプル数は5を維持します。最終モデルが適切に調整され、モデル出力の確率分布が入力と同じになる様に、AutoMLはクラスAのクラスの重みを1/0.736あるいは1.358でスケールアップしますが、クラスBの重みは1のままとします。そして、AutoMLはモデルのトレーニング時にそれぞれのクラスのサンプルが適切に重み付けされる様に、モデルトレーニングにおけるパラメーターとしてこれらのクラスの重みを活用します。

# セマンティックタイプ検知

:::note
**注意**
- セマンティックタイプの検知は予測問題では適用されません。
- AutoMLは、[カスタムの注入メソッド](https://docs.databricks.com/machine-learning/automl/train-ml-model-automl-ui.html#impute-missing-values)が指定されているカラムに対してセマンティックタイプの検知を行いません。
:::

Databricksランタイム9.1ML LTS以降では、AutoMLはテーブルスキーマにおいてSparkやpandasのデータ型と異なるセマンティックタイプのカラムを持っているかどうかを検知しようとします。AutoMLはこれらのカラムを検知したセマンティックタイプとして取り扱います。これらの検知はベストエフォートであり、時には既存のセマンティックタイプを見逃す場合があります。あるいは、カラムのセマンティックタイプを手動で指定するか、[アノテーションを用いて](#セマンティックタイプのアノテーション)AutoMLにセマンティックタイプの検知を行わないように指示することができます。

特に、AutoMLは以下の変換を行います。

- 日付やタイムスタンプデータを表現する文字列、整数型のカラムはタイムスタンプ型に変換します。
- 数値データを表現する文字列カラムは数値型に変換します。

Databricksランタイム10.1 ML以降では、AutoMLは以下の調整も行います。

- カテゴリカルなIDを含む数値カラムはカテゴリカルな特徴量として取り扱われます。
- 英語テキストを含む文字列カラムはテキストの特徴量として取り扱われます。

## セマンティックタイプのアノテーション

Databricksランタイム10.1 ML以降では、カラムに対してセマンティックタイプのアノテーションを指定することで、セマンティックタイプを手動でコントロールすることができます。カラム`<column_name>`のセマンティックタイプを`<semantic_type>`として手動でアノテーションするには以下の文法を使用します。

```py:Python
metadata_dict = df.schema["<column_name>"].metadata
metadata_dict["spark.contentAnnotation.semanticType"] = "<semantic_type>"
df = df.withMetadata("<column_name>", metadata_dict)
```

`<semantic_type>`は以下のいずれかとなります。

- `categorical`: カテゴリカルな値を含むカラム(例えば、IDとして取り扱われる数値)です。
- `numeric`: 数値を含むカラム(例えば、数値にパースできる文字列)です。
- `datetime`: タイムスタンプの値を含むカラム(タイムスタンプに変換できる文字列、数値、日付の値)です。
- `text`: 英語テキストを含む文字列カラムです。

カラムに対するセマンティックタイプ検知を無効化するには、特殊なキーワードアノテーションである`native`を指定します。

# モデル説明可能性のためのShapley値(SHAP)

:::note
**注意**
MLR 11.1以前では、データセットに`datetime`カラムが含まれている場合SHAPのプロットは生成されません。
:::

AutoMLの回帰、分類ランによって生成されるノートブックには、[Shapley値](https://shap.readthedocs.io/en/latest/example_notebooks/overviews/An%20introduction%20to%20explainable%20AI%20with%20Shapley%20values.html#)を計算するコードが含まれています。Shapley値はゲーム理論に基づいており、モデルの予測に対するそれぞれの特徴量の重要度を推定します。

Shapley値を計算するためにAutoMLのノートブックでは[SHAP package](https://shap.readthedocs.io/en/latest/overviews.html)を使用します。これらの計算処理は非常にメモリーを消費するので、デフォルトではこの計算は行われません。

Shapley値を計算して、表示するには:

- AutoMLが生成したトライアルノートブックの**Feature importance**セクションに移動します。
- `shap_enabled = True`を設定します。
- ノートブックを再実行します。

# 時系列の集計

予測問題において、時系列データのタイムスタンプに対して複数の値がある場合、AutoMLはこれらの値の平均値を使用します。

合計を使用するには、ソースコードのノートブックを編集します。**Aggregate data by …** セルで、以下のように`.agg(y=(target_col, "avg"))`を`.agg(y=(target_col, "sum"))`に変更します。

```py:Python
group_cols = [time_col] + id_cols
df_aggregation = df_loaded \
  .groupby(group_cols) \
  .agg(y=(target_col, "sum")) \
  .reset_index() \
  .rename(columns={ time_col : "ds" })
```

# Feature Storeのインテグレーション

Databricks Runtime 11.3 LTS ML以降では、分類問題あるいは回帰問題で使用するオリジナルのデータセットを拡張するために、[Feature Store](https://qiita.com/taka_yayoi/items/88ddec323537febf7784)にある既存の特徴量テーブルを活用することができます。

Databricks Runtime 12.2 LTS ML以降では、AutoMLのすべての問題: 分類、回帰、予測において、オリジナルの入力データセットを拡張するために、[Feature Store](https://qiita.com/taka_yayoi/items/88ddec323537febf7784)にある既存の特徴量テーブルを活用することができます。

特徴量テーブルを作成するには、[Databricks Feature Store](https://qiita.com/taka_yayoi/items/88ddec323537febf7784)をご覧ください。

この能力を活用するには、お使いのアカウントとワークスペースはE2バージョンのプラットフォーム上にある必要があります。使用しているプラットフォームのバージョンを確認するには、Databricks担当者にお問い合わせください。

既存の特徴量テーブルを使用するには、[AutoMLのUIで特徴量テーブルを選択する](https://docs.databricks.com/machine-learning/automl/train-ml-model-automl-ui.html#feature-store)か、[AutoMLのラン設定](https://docs.databricks.com/machine-learning/automl/train-ml-model-automl-api.html)で`feature_store_lookups`パラメーターを設定します。

```py:Python
feature_store_lookups = [
  {
     "table_name": "example.trip_pickup_features",
     "lookup_key": ["pickup_zip", "rounded_pickup_datetime"],
  },
  {
      "table_name": "example.trip_dropoff_features",
     "lookup_key": ["dropoff_zip", "rounded_dropoff_datetime"],
  }
]
```

# Feature StoreインテグレーションのAutoMLサンプルノートブック

https://docs.databricks.com/_extras/notebooks/source/machine-learning/automl-feature-store-example.html

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

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