Databricksのai_forecastによる時系列予測

こちらの`ai_forecast`関数を実際に動かして見ます。

https://qiita.com/taka_yayoi/items/7ab597d7a49c47d8b990

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

# 基本的な使い方

```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', -- 予測のhorizon
  time_col => 'ds', -- 時間列
  value_col => 'revenue' -- 値列
)
```

これだけで予測を行うことができます。
![Screenshot 2024-09-15 at 12.10.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e7ed71e1-24ab-e8f2-db96-d6cc5a3ea764.png)

可視化します。
![Screenshot 2024-09-15 at 12.11.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/84e02619-da15-0201-33bc-338545ca4482.png)

より挙動をわかりやすくするために、過去のデータ(トレーニングデータ)を追加します。

```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' -- 値列
  )
UNION
SELECT
  DATE(tpep_pickup_datetime) AS ds,
  -- 日付に変換
  SUM(fare_amount) AS revenue_forecast,
  -- 収益の合計
  NULL as revenue_lower,
  NULL as revenue_upper
FROM
  samples.nyctaxi.trips
GROUP BY
  1
```
![Screenshot 2024-09-15 at 12.37.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/10a6932c-9e20-e2c2-2b89-820745d13e79.png)


# より複雑な例

降車地点の郵便番号`dropoff_zip`でグルーピングし、`revenue`と`n_trips`を予測しています。

```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, -- 収益がnullの場合は0を使用
      COALESCE(aggregated.n_trips, 0) AS n_trips -- トリップ数がnullの場合は0を使用
    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}' -- パラメータ
)
```
![Screenshot 2024-09-15 at 12.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d572ec55-28ec-81ef-1eb7-6c9644c92808.png)
![Screenshot 2024-09-15 at 12.19.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e64da666-a59b-592d-6d51-9c0ae85e4b20.png)

# グループごとに異なるパラメーターを適用

```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}' -- 日付の順序を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 1, 2, 3
)
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`というカラムを作成してその中にパラメーターを埋め込んでいます。

![Screenshot 2024-09-15 at 12.32.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d51e74f7-d9b0-5260-d479-112b20b80b1a.png)
![Screenshot 2024-09-15 at 12.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1cedbdda-4c06-03b2-7d38-9df2d31f78e1.png)

# ダッシュボードへの組み込み

ロジックをSQLで完結できるので、簡単にダッシュボードに組み込むことができます。プレビュー申請の上、ご活用ください！
![Screenshot 2024-09-15 at 15.15.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ac685aff-cdf2-f2c3-c644-ee07211cb32a.png)


### はじめてのDatabricks

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

### Databricks無料トライアル

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