Databricksのai_forecast関数

[ai\_forecast function \| Databricks on AWS](https://docs.databricks.com/ja/sql/language-manual/functions/ai_forecast.html) [2024/8/8時点]の翻訳です。


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

**適用先:** Databricks SQL

:::note warn
**重要！**
この機能は[パブリックプレビュー](https://docs.databricks.com/ja/release-notes/release-types.html)です。プレビューに参加するにはDatabricksアカウントチームに連絡してください。
:::

`ai_forecast()`は、爺列データを未来に外挿するように設計されているテーブル値関数です。この関数で利用できる引数に関しては[引数](#引数)をご覧ください。

# 要件

- Databricks SQLバージョン2024.35以降が稼働しているPro SQLウェアハウスでのみ利用できます。
- [Databricks SQLの価格ページ](https://www.databricks.com/jp/product/pricing/databricks-sql)をチェックしてください。

# 構文

```sql
ai_forecast(
  observed TABLE,
  horizon DATE | TIMESTAMP | STRING,
  time_col STRING,
  value_col STRING | ARRAY<STRING>,
  group_col STRING | ARRAY<STRING> | NULL DEFAULT NULL,
  prediction_interval_width DOUBLE DEFAULT 0.95,
  frequency STRING DEFAULT 'auto',
  seed INTEGER | NULL DEFAULT NULL,
  parameters STRING DEFAULT '{}'
)
```

# 引数

`ai_forecast()`は、任意の数の**グループ**(`group_col`をご覧ください)を予測することができ、それぞれのグループで最大100の**メトリクス**(`value_col`をご覧ください)を予測することができます。予測の頻度は、あるグループにおけるすべてのメトリクスと同じですが、グループによっては異なる異なります(`frequency`をご覧ください)。

この関数で利用できる引数は以下の通りです:

- `observed`は、予測処理におけるトレーニングデータとして使用されるテーブル値の入力です。
    - この入力のリレーションには、1つの`time`カラムと1つ以上の`value`カラムを必要とします。`Group`と`parameters`カラムはオプションです。入力リレーションにおけるその他のカラムは無視されます。
- `horizon`は、予測結果の終了時間(最後の値は除外)を表現するタイムスタンプにキャスト可能な数値となります。グループ(`group_col`をご覧ください)内では、予測結果は最後の観測値とhorizonの間の期間を持つことになります。horizonが最後の観測時間よりも小さい場合、結果は生成されません。
- `time_col`は`observed`における「時刻のカラム」を参照する文字列です。`time_col`で参照されるカラムは`DATE`か`TIMESTAMP`である必要があります。
- `value_col`は、`observed`の値のカラムを参照する文字列あるいは文字列の配列です。この引数で参照されるカラムは`DOUBLE`にキャストできるものではなくてはなりません。
- `group_col`(オプション)は、`observed`におけるグループのカラムを表現する文字列あるいは文字列の配列です。指定された場合、評価指標のパーティショニングに用いられ、それぞれのグループごとに予測が独立に生成されます。指定されない場合、入力データ全体が単一のグループとして取り扱われます。
- `prediction_interval_width`(オプション)は、予測間隔の幅を表現する0から1の値です。未来の値は`prediction_interval_width`%の確率で、`{v}_upper`と`{v}_lower`の間に含まれることになります。
- `frequency`(オプション)は、予測結果の時間粒度を指定する時間ユニットあるいはpandasのオフセットエイリアスの文字列となります。指定されない場合、それぞれのグループにおける予測粒度は自動で推定されます。frequencyの値が指定されると、すべてのグループに適用されます。
    - グループにおいて推定されたfrequencyは、最近の観測結果のモードとなります。これは、ユーザーによって調整はできない簡便なオペレーションとなります。
    - 例えば、99個の「月曜日」と1個の「火曜日」を持つ時系列においては、「週」がfrequencyとして推定されます。
- `seed`(オプション)は予測処理において使用される擬似的乱数生成器の初期化に使用される数値です。
- `parameters`(オプション)は、予測処理のパラメーター化を表現するカラムIDの名前あるいは文字列にエンコードされたJSONとなります。いかなるパラメータの組み合わせは任意の順序で指定でき、例えば、`{“weekly_order”: 10, “global_cap”: 1000}`のようなものとなります。指定されないパラメーターはすべて、トレーニングデータの属性に基づいて自動で決定されます。以下のパラメーターがサポートされています:
    - `global_cap`や`global_floor`は、メトリックの値で取りうるドメインを定義するために、一緒にあるいは独立に定義するために用いられます。例えば、`{“global_floor”: 0}`は、コストのようなメトリックが常に正になるように制約するために用いることができます。これらは、トレーニングデータと予測データ全体に適用され、予測結果のみに厳密な制約を加えるために使用することはできません。
- `daily_order`と`weekly_order`は、日次、週次の季節性コンポーネントのフーリエ順序を設定します。 

# 戻り値

予測データを含む新規の行セットとなります。出力テーブルのスキーマには、時間とグループカラムが型変換されない状態で格納されます。例えば、入力テーブルの時間カラムが`DATE`の場合、出力テーブルの時間カラムも`DATE`となります。それぞれのvalueカラムには、`{v}_forecast`、`{v}_upper`、`{v}_lower`のパターンに従う3つの出力カラムが存在することになります。入力テーブルの値のタイプに関係なく、予測された値のカラムは常に`DOUBLE`になります。出力テーブルには、最後の観測データからhorizonに至る未来の値のみが含まれます。

AI_FORECASTによって実行されるスキーマ推定の例をいくつか示します:

| 入力テーブル | 引数 | 出力テーブル |
|:--|:--|:--|
|  `ts: TIMESTAMP val: DOUBLE` |  `time_col => 'ts' value_col => 'val'` |  `ts: TIMESTAMP val_forecast: DOUBLE val_upper: DOUBLE val_lower: DOUBLE` |
| `ds: DATE val BIGINT`  |  `time_col => 'ds' value_col => 'val'` | `ds: DATE val_forecast: DOUBLE val_upper: DOUBLE val_lower: DOUBLE`  |
| `ts: TIMESTAMP dim1: STRING dollars: DECIMAL(10, 2)`  | `time_col => 'ts' value_col => 'dollars' group_col => 'dim1'`  |  `ts: TIMESTAMP dim1: STRING dollars_forecast: DOUBLE dollars_upper: DOUBLE dollars_lower: DOUBLE` |
| `ts: TIMESTAMP dim1: STRING dim2: BIGINT dollars: DECIMAL(10, 2) users: BIGINT`  | `time_col => 'ts' value_col => ARRAY('dollars', 'users') group_col => ARRAY('dim1', 'dim2')`  |   `ts: TIMESTAMP dim1: STRING dim2: BIGINT dollars_forecast: DOUBLE dollars_upper: DOUBLE dollars_lower: DOUBLE users_forecast: DOUBLE users_upper: DOUBLE users_lower: DOUBLE`|

# サンプル

以下の例では、特定の日付までの予測を行っています:

```sql
WITH
aggregated AS (
  SELECT
    DATE(tpep_pickup_datetime) AS ds,
    SUM(fare_amount) AS revenue
  FROM
    samples.nyctaxi.trips
  GROUP BY
    1
)
SELECT * FROM AI_FORECAST(
  TABLE(aggregated),
  horizon => '2016-03-31',
  time_col => 'ds',
  value_col => 'revenue'
)
```

以下の例は、より複雑なものとなっています:

```sql
WITH
aggregated AS (
  SELECT
    DATE(tpep_pickup_datetime) AS ds,
    dropoff_zip,
    SUM(fare_amount) AS revenue,
    COUNT(*) AS n_trips
  FROM
    samples.nyctaxi.trips
  GROUP BY
    1, 2
),
spine AS (
  SELECT all_dates.ds, all_zipcodes.dropoff_zip
  FROM (SELECT DISTINCT ds FROM aggregated) all_dates
  CROSS JOIN (SELECT DISTINCT dropoff_zip FROM aggregated) all_zipcodes
)
SELECT * FROM AI_FORECAST(
  TABLE(
    SELECT
      spine.*,
      COALESCE(aggregated.revenue, 0) AS revenue,
      COALESCE(aggregated.n_trips, 0) AS n_trips
    FROM spine LEFT JOIN aggregated USING (ds, dropoff_zip)
  ),
  horizon => '2016-03-31',
  time_col => 'ds',
  value_col => ARRAY('revenue', 'n_trips'),
  group_col => 'dropoff_zip',
  prediction_interval_width => 0.9,
  parameters => '{"global_floor": 0}'
)
```

テーブルで0秒や空のエントリーがマテリアライズされていないことはよくあることに注意してください。欠損しているエントリーの値を例えば`0`に推定できる場合、予測関数を呼び出す前にこれらの値が組み込まれている必要があります。値が本当に欠損しているあるいは未知の場合、`NULL`のままにしておくことも可能です。

非常に疎なデータにおいては、「自動」frequency推定で予期しないアウトプットを回避するために、frequencyの値を明示的に指定するか、欠損値を事前に盛り込むことがベストプラクティスとなります。例えば、「本当の」frequencyが1つの欠損値を持つ週次であったとしても、14日離れた2つのエントリーに対して「自動」frequency推定は、「14D」のfrequencyを推定するでしょう。欠損しているエントリーを含めることで、このような不明確性を排除することができます。

最後に、入力テーブルに存在する異なるグループに、異なるパラメーターが適用される例を示します。

```sql
WITH past AS (
  SELECT
    CASE
      WHEN fare_amount < 30 THEN 'Under $30'
      ELSE '$30 or more'
    END AS revenue_bucket,
    CASE
      WHEN fare_amount < 30 THEN '{"daily_order": 0}'
      ELSE '{"daily_order": "auto"}'
    END AS parameters,
    DATE(tpep_pickup_datetime) AS ds,
    SUM(fare_amount) AS revenue
  FROM samples.nyctaxi.trips
  GROUP BY ALL
)
SELECT * FROM AI_FORECAST(
  TABLE(past),
  horizon => (SELECT MAX(ds) + INTERVAL 30 DAYS FROM past),
  time_col => 'ds',
  value_col => 'revenue',
  group_col => ARRAY('revenue_bucket'),
  parameters => 'parameters'
)
```

どのように`parameters`としてカラムIDを用いているのかに注意してください。これによって、ユーザーは事前に決定したパラメーターのJSONを格納し、新規データに再利用することができます。

# 制限

プレビュー期間においては以下の制限が存在します:

- デフォルトの予測処理は、prophetのような区分的線形かつ季節性のモデルとなります。これは、利用できる唯一の予測モデルとなります。
- エラーメッセージはPython UDTFエンジンを通じて提供され、Pythonのトレースバック情報が含まれます。トレースバックの最後に実際のエラーメッセージが含まれています。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

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