# ML実験トラッキングとモデル管理

ML実験トラッキングは、機械学習実験の結果を整理、記録、分析するプロセスです。このドキュメントでは、ML実験トラッキングを可能にするワークフローの作成方法について説明します。

完全なML実験トラッキングワークフローのコードは、[Treasure Boxes](https://github.com/treasure-data/treasure-boxes/blob/automl/machine-learning-box/automl/ml_experiment.dig)で確認できます。

**目次**

* [ML実験のトラッキング](#track-ml-experiments)
* [各モデルの評価結果の記録](#record-evaluation-results-for-each-model)
* [時系列でのモデルパフォーマンスのドリフト検出](#detect-drift-in-model-performance-over-time)


# ML実験のトラッキング

ベストプラクティスとして、エンドツーエンドのデータ処理ワークフローの一部として、トレーニングタスクに続いて「*track_experiment*」タスクを使用して、各ML実験をトラッキングする必要があります。_track_experiment_タスクは、ML実験情報とモデル名を「automl_experiments」という名前のTDテーブルに記録するSQLクエリを発行します。サンプルワークフローコードは以下の通りです：


```yaml
+create_db_tbl_if_not_exists:
  td_ddl>: null
  create_databases:
    - '${ output_database}'
  create_tables:
    - automl_experiments
    - automl_eval_results
+train:
  ml_train>:
    docker:
      task_mem: 128g
    notebook: gluon_train
    model_name: 'gluon_model_${session_id}'
    input_table: '${input_database}.${train_data_table}'
    target_column: '${target_column}'
    time_limit: '${fit_time_limit}'
    share_model: true
    export_leaderboard: '${output_database}.leaderboard_${train_data_table}'
    export_feature_importance: '${output_database}.feature_importance_${train_data_table}'
+track_experiment:
  td>: queries/track_experiment.sql
  insert_into: '${output_database}.automl_experiments'
  last_executed_notebook: '${automl.last_executed_notebook}'
  user_id: '${automl.last_executed_user_id}'
  user_email: '${automl.last_executed_user_email}'
  model_name: 'gluon_model_${session_id}'
  shared_model: '${automl.shared_model}'
  task_attempt_id: '${attempt_id}'
  session_time: '${session_local_time}'
  engine: presto
```

上記のワークフローコードは、_automl_experiments_テーブルに以下のようなコンテンツを生成します：

| task_attempt_id | session_time | user_id | user_email | model_name | shared_model | notebook_url |
|  --- | --- | --- | --- | --- | --- | --- |
| 849779333 | 2023-05-18 7:19:18 | 7776 | xxx@treasure-data.com | gluon_model_161722236 | b4a568da-e6f3-4057-b694-e2e19bf0e924 | https://console.treasuredata.com/app/workflows/automl/notebook/4a3c431b3aea4705b32a47d85ca46368 |
| 849772621 | 2023-05-18 7:08:30 | 7776 | xxx@treasure-data.com | gluon_model_161721046 | 94ad5d0e-89ac-4836-99c4-2bc8f975ccbe | https://console.treasuredata.com/app/workflows/automl/notebook/b390b932d4a64fd3a2dc3b75503430fb |
| 849768123 | 2023-05-18 7:01:13 | 7777 | yyy@treasure-data.com | gluon_model_161720337 | 4f2351a3-dd8c-418e-8057-4c8ec9a90cbe | https://console.treasuredata.com/app/workflows/automl/notebook/e8b3319c982345a48ff74db0003d7c9c |
| 849760942 | 2023-05-18 6:49:50 | 7776 | xxx@treasure-data.com | gluon_model_161718676 | 93e68b09-1a2f-4049-bb89-2bfe596ca9b3 | https://console.treasuredata.com/app/workflows/automl/notebook/b02959b1469e4b9c86ec6c6809acc5ff |
| 849753199 | 2023-05-18 6:36:36 | 7776 | xxx@treasure-data.com | gluon_model_161717236 | a7e456d3-8fcf-4173-afb7-f2d58bb985cd | https://console.treasuredata.com/app/workflows/automl/notebook/d3dcbbab99774bd594106a496ec2b2ab |


テーブルの各レコードには、モデル名、モデルを作成したユーザーの詳細、モデルが作成されたセッション時刻、および生成されたノートブックへのリンクが含まれます。

# 各モデルの評価結果の記録

オプションで、評価データセットを使用して各モデルの品質を記録できます。次のワークフローは、分類問題の標準的な評価指標である[AUROC](https://en.wikipedia.org/wiki/Receiver_operating_characteristic)を使用してモデル品質を記録する例です。`record_evaluation`タスクは、automl_eval_resultsテーブルに評価結果を記録します。


```yaml
+predict:
  ml_predict>:
    docker:
      task_mem: 64g
    notebook: gluon_predict
    model_name: 'gluon_model_${session_id}'
    input_table: '${input_database}.${test_data_table}'
    output_table: '${output_database}.predicted_${test_data_table}_${session_id}'
+evaluation:
  td>: queries/auc.sql
  table: '${output_database}.predicted_${test_data_table}_${session_id}'
  target_column: '${target_column}'
  positive_class: ' >50K'
  store_last_results: true
  engine: hive
+record_evaluation:
  td>: queries/record_evaluation.sql
  insert_into: '${output_database}.automl_eval_results'
  engine: presto
  model_name: 'gluon_model_${session_id}'
  test_table: '${input_database}.${test_data_table}'
  session_time: '${session_local_time}'
  auc: '${td.last_results.auc}'
```

Treasure DataのHive実行エンジンは、多数の評価指標をサポートするHivemallをサポートしています。詳細については、[Hivemallドキュメント](https://hivemall.github.io/eval/binary_classification_measures.html)を参照してください。

「automl_eval_results」テーブルのコンテンツ例：

| session_time | model_name | ml_datasets.gluon_test | auroc |
|  --- | --- | --- | --- |
| 2023-06-06 6:21:40 | gluon_model_164947310 | ml_datasets.gluon_test | 0.9226243033 |
| 2023-06-14 6:49:22 | gluon_model_166350110 | ml_datasets.gluon_test | 0.9299335758 |
| 2023-06-15 7:35:30 | gluon_model_166532223 | ml_datasets.gluon_test | 0.9300292252 |
| 2023-05-18 7:19:18 | gluon_model_161722236 | ml_datasets.gluon_test | 0.9238149699 |


# 時系列でのモデルパフォーマンスのドリフト検出

「ドリフト」は、機械学習において、機械学習モデルのパフォーマンスが時間の経過とともにゆっくりと悪化または陳腐化することを表す用語です。ドリフトには主に2つのタイプがあります：データドリフトと[コンセプトドリフト](https://en.wikipedia.org/wiki/Concept_drift)です。データドリフトとコンセプトドリフトの両方が、機械学習モデルのパフォーマンス低下につながる可能性があります。

次のワークフロータスクを使用することで、各モデルの精度と品質を記録し、データとモデルパフォーマンスのドリフトを検出できます。スケジュールされたワークフロージョブを使用して、モデルパフォーマンスを追跡し、モデルパフォーマンスがドリフトした場合に警告を発することができます。

ドリフト検出にはいくつかのスキームがあります。次のワークフロー例は、評価指標を使用してMLモデルパフォーマンスの劣化を特定する方法を示しています。ドリフトが検出されると、次のようにアラートメールをトリガーできます：


```yaml
# timezone: PST
# schedule:
#  daily>: 07:00:00
+evaluation:
  td>: queries/auc.sql
  table: '${output_database}.predicted_${test_data_table}_${session_id}'
  target_column: '${target_column}'
  positive_class: ' >50K'
  store_last_results: true
  engine: hive
+alert_if_drift_detected:
  if>: '${td.last_results.auc < 0.93}'
  _do: null
mail>: null
data: 'Detect drift in model performance. AUC was ${td.last_results.auc}.'
subject: Drift detected
to:
  - me@example.com
bcc:
  - foo@example.com
  - bar@example.com
```

ドリフト検出のために[ワークフロー実行をスケジュール](https://docs.digdag.io/scheduling_workflow.html?highlight=schedule)できます。また、ドリフトが検出された場合、[条件演算子](https://docs.digdag.io/operators/if.html)を使用してアラートメールを送信したり、モデルを再構築したりできます。