🚀

BigQueryML の TimesFM で学習不要な「ゼロショット」の時系列予測を試してみた

に公開

はじめに

こんにちは、クラウドエースの木村です。

Google Cloud の BigQuery ML にモデルの学習やチューニングを一切行わずに、時系列データの予測ができる TimesFM が登場しました。

この記事では、TimesFM の仕組みから、実際の SQL を使ったハンズオン、そして BigQuery ML のもう一つの予測モデル「ARIMA_PLUS」との比較まで、ざっくりと解説します。

対象読者

  • SQL は書けるけど、機械学習は専門外というデータアナリストの方
  • BigQuery で手軽に時系列予測を試してみたいエンジニアの方
  • TimesFM と ARIMA_PLUS の使い分けに悩んでいるデータサイエンティストの方

第1章:TimesFM とは

TimesFM について、まずはその仕組みと特徴について簡単に紹介します。

1.1. TimesFM の概要

TimesFM は、Google Research が開発した、時系列予測に特化した事前学習済みモデルです。アーキテクチャは、Gemini のような LLM(大規模言語モデル)と同じくデコーダオンリーの Transformer モデルをベースにしています。

このモデルの特徴は、学習に使われたデータの量にあります。TimesFM は、ウェブ検索トレンドなど、様々なドメインから集めた 実世界の大量のデータを事前学習したモデルです。この膨大なデータから、TimesFM は時系列データに共通する複雑なパターン(季節性、トレンドなど)をあらかじめ学習済みというわけです。

LLM がネット上の膨大な文章を学習して言語を操るように、 TimesFM は世界中のあらゆる「時間のパターン」を学習して未来を予測する、と考えると分かりやすいかもしれません。

TimesFM の詳細については、以下のリンクをご参照ください。
https://research.google/blog/a-decoder-only-foundation-model-for-time-series-forecasting/
https://github.com/google-research/timesfm

1.2. コア技術 「パッチ化」と「ゼロショット学習」

TimesFM の能力は、主に2つの技術で支えられています。

1つ目は 「パッチ化(Patching)」 です。これは、時系列データを「パッチ」という塊に分割する手法です。文章を単語に区切るのに似ていますね。データひとつひとつではなく、意味のある塊(パッチ)で処理することで、効率的にパターンを捉えることができます。

2つ目は、最大の特徴である 「ゼロショット学習(Zero-Shot Learning)」 です。前述の通り、TimesFM はすでに時系列の多様なパターンを知っています。そのため、未知のデータに対しても、追加学習なしで、いきなり高精度な予測を生成できます。

1.3. BigQuery ML の TimesFM

TimesFM が BigQuery ML に搭載されたことで、時系列予測がもっと身近になりました。

  • AIの民主化 : AI.FORECAST というシンプルな SQL 関数を実行するだけで、機械学習の専門家でなくても最先端の予測分析ができます。
  • 圧倒的なスピード : モデル学習が不要なので、思い立ったらすぐに結果を得られます。店舗ごと・商品ごとの売上データのような、数百万もの時系列データも単一クエリで並列に予測できるスケーラビリティも備えています。

第2章:ハンズオン:SQL で時系列予測

この章では TimesFM を実際に動かしてみます。
BigQuery の公開データセットを使って、SQL クエリで未来の時系列データを予測します。

2.1. チュートリアルの準備

このハンズオンは、Google Cloud の公式チュートリアルで紹介されている内容をベースにしています。
https://cloud.google.com/bigquery/docs/timesfm-time-series-forecasting-tutorial?hl=ja

今回は、サンフランシスコのバイクシェア利用状況の公開データセット bigquery-public-data.san_francisco_bikeshare.bikeshare_trips を使います。

目的 : 過去のデータから、 未来30日分 のバイクシェア利用回数を 1 時間単位で予測する。

まずは、予測モデルに入力するデータを準備します。
元のデータはトリップごとの記録なので、これを1時間単位の利用回数に集計します。

SELECT
  TIMESTAMP_TRUNC(start_date, HOUR) AS trip_hour,
  COUNT(*) AS num_trips
FROM
  `bigquery-public-data.san_francisco_bikeshare.bikeshare_trips`
WHERE
  subscriber_type = 'Subscriber'
  AND start_date >= TIMESTAMP('2018-01-01')
GROUP BY
  1
ORDER BY
  1 DESC
LIMIT
  512

TimesFM のデータ履歴(コンテキスト長)は最大 512 点であるため、これに合わせてデータポイントを 512 点に制限しています。

グラフに可視化したものを以下に示します。時系列の波形から特定のパターンがありそうですね。

バイクシェア利用回数(入力データ)
バイクシェア利用回数(入力データ)

2.2. AI.FORECAST 関数を実行

データの準備ができたら、 AI.FORECAST 関数で TimesFM モデルを呼び出して予測を実行します。

WITH historical AS (
  SELECT
    TIMESTAMP_TRUNC(start_date, HOUR) AS trip_hour,
    COUNT(*) AS num_trips
  FROM
    `bigquery-public-data.san_francisco_bikeshare.bikeshare_trips`
  WHERE
    subscriber_type = 'Subscriber'
    AND start_date >= TIMESTAMP('2018-01-01')
  GROUP BY
    1
  ORDER BY
    1 DESC
  LIMIT 512
)
SELECT *
FROM
  AI.FORECAST(
    TABLE historical,
    horizon => 720,
    confidence_level => 0.95,
    timestamp_col => 'trip_hour',
    data_col => 'num_trips'
  )

各パラメータの意味は次の通りです。

  • TABLE historical: 予測の元になるデータ。
  • horizon => 720: 720時間(30日)先まで予測。
  • confidence_level => 0.95: 95%の予測区間を設定。予測の不確実性を評価できます。
  • timestamp_col => 'trip_hour': 時間軸のカラム。
  • data_col => 'num_trips': 予測したい数値のカラム。

これまではデータをエクスポートして Python でモデリング…といった手間が必要でしたが、AI.FORECAST ならデータ準備から予測まで SQL だけで完結します。このシンプルさこそ、TimesFM の最も強力な機能です。

予測結果をグラフに可視化したものを以下に示します。

バイクシェア利用回数(予測データ)
バイクシェア利用回数(予測データ)

2.3. 実データと予測データを合わせてグラフで可視化

実測データと予測データを合わせて可視化します。

-- 共通テーブル式 (CTE) で実績データと TimesFM 予測を準備
WITH
  -- 1. チュートリアルで使用する実績データを準備
  historical_data AS (
    SELECT
      TIMESTAMP_TRUNC(start_date, HOUR) AS trip_hour,
      COUNT(*) AS num_trips
    FROM
      `bigquery-public-data.san_francisco_bikeshare.bikeshare_trips`
    WHERE
      subscriber_type = 'Subscriber'
      AND start_date >= TIMESTAMP('2018-01-01')
    GROUP BY
      1
    ORDER BY
      1 DESC
    LIMIT 512
  ),
  -- 2. TimesFM による予測を生成
  timesfm_forecast AS (
    SELECT
      forecast_timestamp,
      forecast_value,
      prediction_interval_lower_bound,
      prediction_interval_upper_bound
    FROM
      AI.FORECAST(
        TABLE historical_data,
        horizon => 720,
        confidence_level => 0.95,
        timestamp_col => 'trip_hour',
        data_col => 'num_trips'
      )
  )
-- 3. 実績データと予測データを結合
-- 実績データ
SELECT
  trip_hour AS timestamp,
  num_trips AS historical_value,
  NULL as forecast_value,
  'historical' as type,
  NULL as prediction_interval_lower_bound,
  NULL as prediction_interval_upper_bound

FROM
  historical_data
UNION ALL
-- TimesFMの予測データ
SELECT
  forecast_timestamp AS timestamp,
  NULL AS historical_value,
  forecast_value AS forecast_value,
  'timesfm_forecast' AS type,
  prediction_interval_lower_bound,
  prediction_interval_upper_bound
FROM
  timesfm_forecast
ORDER BY
  timestamp ASC

バイクシェア利用回数(入力データと予測データ)
バイクシェア利用回数(入力データと予測データ)

入力データと予測データで、シェアサイクルの利用状況の傾向が類似していることがわかります。
また、将来の予測が遠くなるほど、予測区間のブレが増加することもわかります。

第3章:TimesFM vs ARIMA_PLUS

TimesFM を動かしてみたところで、BigQuery ML のもう一つの主要な予測モデル、ARIMA_PLUS (ARIMA_PLUS_XREG)と比較してみます。

両者はどちらか一方が優れているというわけではなく、それぞれ得意なことが異なるモデルです。

特徴・機能 AI.FORECAST (TimesFM) ML.FORECAST (ARIMA_PLUS)
モデルタイプ Transformer ベースの基盤モデル 統計的時系列パイプライン
BQML関数 AI.FORECAST ML.FORECAST
利用手順 1ステップ(関数呼び出しのみ) 2ステップ以上(CREATE MODEL + ML.FORECAST
データ履歴(コンテキスト長) 512 点 トレーニング データ内のすべてのタイム ポイント
多変量予測(外部変数) 非対応(現在の BigQuery 実装) 対応(ARIMA_PLUS_XREG モデル使用時)
解釈可能性(説明性) 低い(ブラックボックス) 高い(ML.EXPLAIN_FORECAST 等で分解可能)
カスタマイズ性 低い(horizon, confidence_level のみ) 高い(季節性、祝日、トレンド等多数のオプション)
祝日効果 自動考慮なし 自動考慮あり(HOLIDAY_REGION 指定)
外れ値処理 モデルの堅牢性に依存 自動検出・調整機能あり
課金モデル 関数呼び出しごとのクエリ処理量 モデル作成時のデータ処理量 + 予測時のクエリ処理量
ユーザー例 データアナリスト、迅速な予測が必要な開発者 データサイエンティスト、解釈可能性が重要な業務担当者

3.1. 考え方の違い

両者の大きな違いは、予測アプローチにあります。

  • TimesFM:「幅」で勝負
    世界中の膨大なデータから学んだ知識を、予測したいデータに適用します。「世界中の時系列パターンを知る賢者が、あなたのデータを見て『これはあのパターンに似ているな』と予測する」イメージです。

  • ARIMA_PLUS:「深さ」で勝負
    データそのものを深く分析します。「熟練の統計家が、あなたのデータだけをじっくり観察し、独自の法則性を見つけ出して予測する」イメージです。

3.2. 外部要因を扱えるか

予測精度を上げる上で、もう一つ大きな違いが、複数の外部要因を考慮できる多変量予測に対応しているか否かです。

  • TimesFM の制約 : BigQuery ML に実装されている AI.FORECAST は、単変量予測のみサポートしており、予測対象の時系列データ(例:売上)しか見ることができません。セール期間や天気といった外部要因は考慮できません。
  • ARIMA_PLUS_XREG の強み : ARIMA_PLUS_XREG モデルは、多変量予測をサポートしており、外部要因をインプットして予測ができます。例えば、アイスクリームの売上を予測する際に、気温データを加えることで、より精度の高い予測が期待できます。

3.3. 予測の「なぜ?」を説明できるか

予測結果の根拠を説明する能力は、ビジネスでは精度と同じくらい重要です。

  • TimesFMの不透明性 : AI.FORECAST は予測値を出しますが、「なぜ」その予測になったのかを直接説明してはくれません。ブラックボックスのモデルです。
  • ARIMA_PLUSの透明性 : ARIMA_PLUSML.EXPLAIN_FORECAST という関数で、予測値をトレンド、季節性、祝日効果などに分解してくれます。「来月の予測が高いのは、季節性と祝日効果が重なるからです」といった具体的な説明が可能になり、ビジネスサイドの信頼を得やすくなります。

3.4. 利用手順の違い

利用方法のステップにも違いがあります。

  • TimesFM : AI.FORECAST は、入力に対して出力を返すだけのシンプルな関数呼び出しです。データセット内にモデルは作られません。一方で、(現在の BigQuery 実装では)Fine-tuning 機能はなく、モデルをカスタマイズすることはできません。
  • ARIMA_PLUS : CREATE MODEL で、データセット内に永続的な「モデルオブジェクト」を作成します。このモデルは再利用やバージョン管理が可能です。

3.5. 予測結果を並べて比較する

一例ではありますが、前述のチュートリアルを題材に、TimesFM と ARIMA_PLUS の予測結果を可視化して比較してみます。

準備:ARIMA_PLUS モデルの作成

まず、比較対象となる ARIMA_PLUS モデルを作成します。

SQL
CREATE OR REPLACE MODEL `PROJECT_ID.DATASET_ID.bikeshare_arima_plus_model`
OPTIONS(
  MODEL_TYPE='ARIMA_PLUS',
  TIME_SERIES_TIMESTAMP_COL='trip_hour',
  TIME_SERIES_DATA_COL='num_trips',
  AUTO_ARIMA=TRUE,
  HOLIDAY_REGION='US'
) AS
SELECT
  trip_hour,
  num_trips
FROM (
  SELECT
    TIMESTAMP_TRUNC(start_date, HOUR) AS trip_hour,
    COUNT(*) AS num_trips
  FROM
    `bigquery-public-data.san_francisco_bikeshare.bikeshare_trips`
  WHERE
    subscriber_type = 'Subscriber'
    AND start_date >= TIMESTAMP('2018-01-01')
  GROUP BY
    1
)
ORDER BY
  trip_hour DESC
LIMIT 512

(補足)PROJECT_IDDATASET_ID はご自身の環境に合わせて設定してください。

比較用クエリ

次に、実績データ、TimesFM による予測、そして、先ほど作成した ARIMA_PLUS モデルによる予測を1つのテーブルに結合します。

SQL
-- 共通テーブル式 (CTE) を使用して、実績データ、TimesFM 予測、ARIMA_PLUS 予測をそれぞれ準備
WITH
  -- 1. チュートリアルで使用する実績データを準備
  historical_data AS (
    SELECT
      TIMESTAMP_TRUNC(start_date, HOUR) AS trip_hour,
      COUNT(*) AS num_trips
    FROM
      `bigquery-public-data.san_francisco_bikeshare.bikeshare_trips`
    WHERE
      subscriber_type = 'Subscriber'
      AND start_date >= TIMESTAMP('2018-01-01')
    GROUP BY
      1
    ORDER BY
      1 DESC
    LIMIT 512
  ),
  -- 2. TimesFM による予測を生成
  timesfm_forecast AS (
    SELECT
      forecast_timestamp,
      forecast_value,
      prediction_interval_lower_bound,
      prediction_interval_upper_bound
    FROM
      AI.FORECAST(
        TABLE historical_data,
        horizon => 720,
        confidence_level => 0.95,
        timestamp_col => 'trip_hour',
        data_col => 'num_trips'
      )
  ),
  -- 3. ARIMA_PLUS による予測を生成
  arima_plus_forecast AS (
    SELECT
      forecast_timestamp,
      forecast_value,
      prediction_interval_lower_bound,
      prediction_interval_upper_bound
    FROM
      ML.FORECAST(
        MODEL `PROJECT_ID.DATASET_ID.bikeshare_arima_plus_model`, -- ご自身のモデル名に置き換えてください
        STRUCT(720 AS horizon, 0.95 AS confidence_level)
      )
  )
-- 4. 実績データと2つのモデルの予測結果を結合して可視化用のデータを作成
-- 実績データ
SELECT
  trip_hour AS timestamp,
  num_trips AS value,
  'historical_actuals' AS model_type, -- データソースを識別するラベル
  NULL AS lower_bound,
  NULL AS upper_bound
FROM
  historical_data
UNION ALL
-- TimesFM の予測データ
SELECT
  forecast_timestamp AS timestamp,
  forecast_value AS value,
  'timesfm_forecast' AS model_type, -- データソースを識別するラベル
  prediction_interval_lower_bound AS lower_bound,
  prediction_interval_upper_bound AS upper_bound
FROM
  timesfm_forecast
UNION ALL
-- ARIMA_PLUS の予測データ
SELECT
  forecast_timestamp AS timestamp,
  forecast_value AS value,
  'arima_plus_forecast' AS model_type, -- データソースを識別するラベル
  prediction_interval_lower_bound AS lower_bound,
  prediction_interval_upper_bound AS upper_bound
FROM
  arima_plus_forecast
ORDER BY
  timestamp ASC

(補足)PROJECT_IDDATASET_ID はご自身の環境に合わせて設定してください。

可視化

以下の図は、TimesFM と ARIMA_PLUS の予測結果を合わせてグラフに可視化したものです。
両者とも似た予測となっていることがわかります。今回の入力データに関しては、予測に大きな違いはなさそうです。

バイクシェア利用回数(TimesFM & ARIMA)
バイクシェア利用回数(TimesFM & ARIMA)

第4章:使い分けガイド:どっちのモデルをいつ使う?

これまでの比較も踏まえ、どちらのモデルをいつ使えばいいのかについて考えてみます。

4.1. 意思決定フレームワーク

以下の表に、シナリオ別に選ぶべきモデルの指針をまとめてみました。参考程度にご覧ください。

シナリオ/要件 推奨モデル 根拠
とにかく早く試したい、探索的分析 TimesFM 圧倒的な速さと手軽さ。SQL 一行で結果が出て、アイデア検証が捗る。
セール効果を考慮した売上予測 ARIMA_PLUS_XREG 広告費などの外部要因が重要なので、多変量予測が可能な XREG が必須。
監査や報告で「なぜ?」の説明が必要 ARIMA_PLUS ML.EXPLAIN_FORECAST で予測の根拠を分解・説明でき、透明性を確保できる。
大量(数万 SKU〜)の商品需要予測 TimesFM 学習不要で大規模データを並列処理できるスケーラビリティが強み。
ML 専門家がいない分析チーム TimesFM MLOps の手間がなく、SQL スキルだけで高度な予測が可能。
特定指標の精度を極限まで高めたい ARIMA_PLUS / ARIMA_PLUS_XREG 多数のパラメータを微調整し、データに特化した高精度モデルを構築できる。

4.2. 「精度」の話

  • 「どっちが正確?」は状況による : ベンチマークでは TimesFM が良い性能を示すことが多いですが、それは「追加情報なし」の場合です。もし予測に強く影響する外部要因(例:気温とアイスクリームの売上)があり、その将来値がわかるなら、それを組み込んだ ARIMA_PLUS_XREG が TimesFM を上回る精度を出す可能性は十分にあります。

  • ハイブリッド戦略 : まず、TimesFM の AI.FORECAST で全商品のベースライン予測を素早く行い、特に重要な商品だけ ARIMA_PLUS_XREG で深掘り分析する、といった両者の強みを組み合わせるのも有効な戦略かもしれません。

第5章:運用上の考慮事項 - コストとスケーラビリティ

モデルを選ぶ際は、コストや大規模データへの対応能力も重要です。

5.1. パフォーマンスとスケーラビリティ

  • TimesFM : モデル学習がないので非常に高速。特に、数千、数万といった多数の時系列データを一度に予測するのに強いです。
  • ARIMA_PLUS : モデル作成時間はデータ量に比例して増えるため、大規模データで個別に学習が必要な場合は、時間がかかる可能性があります。

5.2. コストモデルの違い

TimesFM と ARIMA_PLUS は、どちらも BigQuery ML の料金体系が適用されますが、課金の仕組みとコストが発生するタイミングに少し違いがあります。

  • TimesFM : モデル作成コストはゼロ。AI.FORECAST 関数を呼び出すたびに、クエリの処理量に応じた料金がかかります。
  • ARIMA_PLUS : モデル作成時、 CREATE MODEL のデータ処理量で発生します。加えて予測時にもクエリの処理量に応じた料金がかかります。

毎日予測を行うがモデル更新は月 1 回という場合は ARIMA_PLUS が、不定期に色々なデータを分析する場合は TimesFM が、コスト的に有利になりそうです。

おわりに

今回は、Bigquery ML の時系列予測モデル TimesFM について、ARIMA_PLUS との比較も交えて紹介しました。

TimesFM と ARIMA_PLUS は、どちらが優れているかという話ではありません。機械学習全般に言えることですが、要件に応じて最適なモデルを選択することが重要となります。

参考リンク

Discussion