基盤モデルと自動異常検出を用いた TimeCopilot による予測パイプラインの構築方法
本文の状態
日本語全文を表示中
詳細モードで約6分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
MarkTechPost
MarkTechPost は、TimeCopilot を活用して航空会社乗客データや合成データを処理するエンドツーエンドの予測ワークフローを構築する方法を紹介し、統計モデルや基盤モデルの評価手法を解説している。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
本チュートリアルでは、TimeCopilot を用いてエンドツーエンドの予測ワークフローを構築します。実際の航空会社乗客データを含むパネルデータセットと、異常値を注入した合成季節時系列を用意し、多様な統計モデル、ファウンデーションモデル、およびオプションの GPU ベース予測モデルを評価します。ローリング交差検証と複数の誤差指標を用いて最良のモデルを特定し、予測区間付きの確率的予測を生成し、将来のトレンドを可視化し、異常な観測値を検出します。最後に、予測モデルを選択し、その予測結果をアクセスしやすい分析回答に変換する TimeCopilot のオプション LLM エージェント(大規模言語モデルエージェント)について探ります。
TimeCopilot のインストールと互換性のある NumPy および SciPy バージョンの固定
!pip install -q "timecopilot" "utilsforecast" "matplotlib"
!pip install -q --force-reinstall --no-deps "numpy==1.26.4" "scipy==1.13.1"
print("Setup complete. Restarting the runtime to load clean binaries...")
import IPython
IPython.Application.instance().kernel.do_shutdown(True)
予測環境を準備するために、TimeCopilot、UtilsForecast(ユーティリティ予測)、Matplotlib をインストールします。バイナリ競合を防ぐため、互換性のある NumPy および SciPy のバージョンを強制適用します。その後、Colab ランタイムを再起動して更新されたライブラリが正しく読み込まれるようにします。
AirPassengers データの読み込みと合成異常パネルの構築
必要なライブラリをインポートし、環境を確認して GPU の利用可否を検出します。AirPassengers データセットを読み込み、スパイク(急激な変動)を組み込んだ第 2 の合成季節時系列を作成します。これら 2 つの時系列を結合してパネルデータセットとし、予測ホライズンと月次頻度を設定します。
統計モデル、Prophet モデル、Chronos モデルの構成
異なるブラウザを使用する
from timecopilot.forecaster import TimeCopilotForecaster
from timecopilot.models.stats import AutoARIMA, AutoETS, SeasonalNaive, Theta
from timecopilot.models.prophet import Prophet
from timecopilot.models.foundation.chronos import Chronos
chronos_repo = "amazon/chronos-bolt-small" if HAS_GPU else "amazon/chronos-bolt-tiny"
models = [
SeasonalNaive(), AutoETS(), AutoARIMA(), Theta(), Prophet(),
Chronos(repo_id=chronos_repo, alias="Chronos"),
]
if HAS_GPU:
try:
from timecopilot.models.foundation.timesfm import TimesFM
models.append(TimesFM(repo_id="google/timesfm-2.0-500m-pytorch", alias="TimesFM"))
except Exception as e:
print("Skipping TimesFM:", e)
tcf = TimeCopilotForecaster(models=models)
print("\nModels:", [getattr(m, "alias", type(m).__name__) for m in models])
統計モデル、Prophet モデル、および Chronos モデルの多様なコレクションを構成します。利用可能なハードウェアに応じて Chronos モデルのサイズを選択し、GPU が存在する場合はオプションで TimesFM を含めます。その後、TimeCopilotForecaster を初期化して、すべてのモデルを一貫したインターフェースを通じて管理できるようにします。
ロールイング交差検証の実行と RMSE によるモデルランキング
print("\nRunning cross-validation (slow step: foundation weights download)...")
cv_df = tcf.cross_validation(df=panel, h=H, freq=FREQ, n_windows=3)
print(cv_df.head())
from utilsforecast.evaluation import evaluate
from utilsforecast.losses import mae, rmse, mape
eval_df = evaluate(cv_df.drop(columns=["cutoff"]), metrics=[mae, rmse, mape])
print("\n=== Per-series error (lower = better) ===")
print(eval_df.round(3))
model_cols = [c for c in eval_df.columns if c not in ("unique_id", "metric")]
leaderboard = (eval_df.groupby("metric")[model_cols].mean().T.sort_values("rmse"))
print("\n=== Leaderboard (mean across series) ===")
print(leaderboard.round(3))
best_model = leaderboard.index[0]
print(f"\n>>> Best model by mean RMSE: {best_model}")
We perform rolling cross-validation across three windows to measure each model's forecasting performance. We calculate MAE, RMSE, and MAPE for every series and aggregate the results into a leaderboard. We identify the model with the lowest mean RMSE for subsequent forecasting and visualization.
Generating Probabilistic Forecasts with Prediction Intervals
Copy CodeCopiedUse a different Browser
fcst_df = tcf.forecast(df=panel, h=H, freq=FREQ, level=[80, 95])
print("\nForecast columns:", list(fcst_df.columns))
def plot_series(uid, point_model=best_model):
hist = panel[panel["unique_id"] == uid]; fc = fcst_df[fcst_df["unique_id"] == uid]
plt.figure(figsize=(11, 4)); plt.plot(hist["ds"], hist["y"], color="black", label="history")
if point_model in fc.columns:
plt.plot(fc["ds"], fc[point_model], color="C0", label=f"{point_model} forecast")
lo, hi = f"{point_model}-lo-95", f"{point_model}-hi-95"
if lo in fc.columns and hi in fc.columns:
plt.fill_between(fc["ds"], fc[lo], fc[hi], alpha=0.25, color="C0", label="95% interval")
plt.title(f"{uid} — {point_model}"); plt.legend(); plt.tight_layout(); plt.show()
for uid in panel["unique_id"].unique():
plot_series(uid)
80% および 95% の予測区間を含む、12 ヶ月分の確率的予測(probabilistic forecasts)を生成します。ここでは、履歴値、ポイント予測(point forecasts)、不確実性範囲を表示する再利用可能なプロット関数を定義しています。この関数を各時系列に適用し、観測された履歴と予測される将来の軌跡を比較します。
予測パネル全体における異常検出
Copy CodeCopiedUse a different Browser
print("\nRunning anomaly detection...")
anomalies_df = tcf.detect_anomalies(df=panel, h=H, freq=FREQ, level=99)
anom_cols = [c for c in anomalies_df.columns if c.endswith("-anomaly")]
if anom_cols:
flagged = anomalies_df[anomalies_df[anom_cols].any(axis=1)]
print(f"Flagged points (>=1 model): {len(flagged)}")
print(flagged[["unique_id", "ds", "y"] + anom_cols].head(20).to_string(index=False))
col = f"{best_model}-anomaly"
if col not in anomalies_df.columns: col = anom_cols[0]
sub = anomalies_df[anomalies_df["unique_id"] == "Synthetic"]
pts = sub[sub[col] == True]
plt.figure(figsize=(11, 4)); plt.plot(sub["ds"], sub["y"], color="black", label="value")
plt.scatter(pts["ds"], pts["y"], color="red", zorder=5, label=f"anomaly ({col})")
plt.title("Anomaly detection — Synthetic series"); plt.legend(); plt.tight_layout(); plt.show()
else:
print(anomalies_df.head())
Interpreting Forecasts with the TimeCopilot LLM Agent
Copy CodeCopiedUse a different Browser
from timecopilot import TimeCopilot
if os.environ.get("OPENAI_API_KEY") or os.environ.get("ANTHROPIC_API_KEY"):
llm = "openai:gpt-4o" if os.environ.get("OPENAI_API_KEY") else "anthropic:claude-sonnet-4-5"
tc = TimeCopilot(llm=llm, retries=3)
single = panel[panel["unique_id"] == "AirPassengers"]
result = tc.forecast(df=single, freq=FREQ, h=H,
query="Total air passengers expected over the next 12 months, and which months peak?")
out = result.output
print("\n=== AGENT REPORT ===")
print("Selected model:", out.selected_model)
print("Beats SeasonalNaive:", out.is_better_than_seasonal_naive)
print("Why:", out.reason_for_selection)
print("Answer:", out.user_query_response)
print(result.fcst_df.head())
else:
print("\n[Agent section skipped] No LLM key. Everything above ran key-free.")
print("\nDone.
image")
パネル全体で異常を検出し、フラグ付けされた観測値を合成系列上で可視化します。OpenAI または Anthropic の API キーが利用可能な場合に限り、TimeCopilot LLM エージェントを初期化するオプションがあります。このエージェントを用いてモデルを選択し、SeasonalNaive モデルとの比較評価を行い、実用的な質問に対する予測の解説を行います。
結論
結論として、データ準備からモデル評価、確率的予測、可視化、異常検出、そしてエージェントによる解釈までを一貫して行う統合された TimeCopilot パイプラインを構築しました。従来の統計手法と最新のファウンデーションモデルを、一貫した交差検証フレームワーク内で比較し、客観的な誤差指標に基づいて最もパフォーマンスの高いアプローチを選択しました。また、予測区間を通じて予測の不確実性を定量化し、複数の時系列にわたる異常な観測値も特定しました。自動化された予測とオプションの LLM エージェントを組み合わせることで、単一のワークフロー内で正確な数値予測と明確で意思決定指向の洞察の両方を生成することができました。
原文を表示
In this tutorial, we build an end-to-end forecasting workflow with TimeCopilot. We prepare a panel dataset containing real airline passenger data and a synthetic seasonal series with injected anomalies, then evaluate a diverse collection of statistical, foundation, and optional GPU-based forecasting models. We use rolling cross-validation and multiple error metrics to identify the strongest model, generate probabilistic forecasts with prediction intervals, visualize future trends, and detect unusual observations. Finally, we explore TimeCopilot’s optional LLM agent, which selects a forecasting model and translates its predictions into an accessible analytical response.
Installing TimeCopilot and Pinning Compatible NumPy and SciPy Versions
Copy CodeCopiedUse a different Browser
!pip install -q "timecopilot" "utilsforecast" "matplotlib"
!pip install -q --force-reinstall --no-deps "numpy==1.26.4" "scipy==1.13.1"
print("Setup complete. Restarting the runtime to load clean binaries...")
import IPython
IPython.Application.instance().kernel.do_shutdown(True)
We install TimeCopilot, UtilsForecast, and Matplotlib to prepare the forecasting environment. We enforce compatible NumPy and SciPy versions to prevent binary conflicts. We then restart the Colab runtime so the updated libraries load correctly.
Loading AirPassengers Data and Building a Synthetic Anomaly Panel
Copy CodeCopiedUse a different Browser
import os, warnings
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
warnings.filterwarnings("ignore")
pd.set_option("display.width", 160)
pd.set_option("display.max_columns", 30)
print("numpy:", np.__version__)
import scipy; print("scipy:", scipy.__version__)
try:
import torch
HAS_GPU = torch.cuda.is_available()
except Exception:
HAS_GPU = False
print(f"GPU available: {HAS_GPU}")
df = pd.read_csv(
"https://timecopilot.s3.amazonaws.com/public/data/air_passengers.csv",
parse_dates=["ds"],
)
df["unique_id"] = df["unique_id"].astype(str)
rng = np.random.default_rng(7)
dates = df["ds"].unique(); n = len(dates)
synth = pd.DataFrame({
"unique_id": "Synthetic",
"ds": dates,
"y": (np.linspace(50, 250, n)
+ 40 * np.sin(2 * np.pi * np.arange(n) / 12)
+ rng.normal(0, 8, n)).round(2),
})
anomaly_idx = [30, 75, 120]
synth.loc[anomaly_idx, "y"] *= 2.2
panel = pd.concat([df[["unique_id", "ds", "y"]], synth], ignore_index=True)
print("\nPanel shape:", panel.shape)
print(panel.groupby("unique_id")["y"].agg(["count", "mean", "min", "max"]))
H, FREQ = 12, "MS"
We import the required libraries, verify the environment, and detect GPU availability. We load the AirPassengers dataset and create a second synthetic seasonal series with injected spikes. We combine the two series into a panel dataset and set the forecasting horizon and monthly frequency.
Configuring Statistical, Prophet, and Chronos Forecasting Models
Copy CodeCopiedUse a different Browser
from timecopilot.forecaster import TimeCopilotForecaster
from timecopilot.models.stats import AutoARIMA, AutoETS, SeasonalNaive, Theta
from timecopilot.models.prophet import Prophet
from timecopilot.models.foundation.chronos import Chronos
chronos_repo = "amazon/chronos-bolt-small" if HAS_GPU else "amazon/chronos-bolt-tiny"
models = [
SeasonalNaive(), AutoETS(), AutoARIMA(), Theta(), Prophet(),
Chronos(repo_id=chronos_repo, alias="Chronos"),
]
if HAS_GPU:
try:
from timecopilot.models.foundation.timesfm import TimesFM
models.append(TimesFM(repo_id="google/timesfm-2.0-500m-pytorch", alias="TimesFM"))
except Exception as e:
print("Skipping TimesFM:", e)
tcf = TimeCopilotForecaster(models=models)
print("\nModels:", [getattr(m, "alias", type(m).__name__) for m in models])
We configure a diverse collection of statistical, Prophet, and Chronos forecasting models. We select the Chronos model size according to the available hardware and optionally include TimesFM when a GPU is present. We then initialize TimeCopilotForecaster to manage all models through one consistent interface.
Running Rolling Cross-Validation and Ranking Models by RMSE
Copy CodeCopiedUse a different Browser
print("\nRunning cross-validation (slow step: foundation weights download)...")
cv_df = tcf.cross_validation(df=panel, h=H, freq=FREQ, n_windows=3)
print(cv_df.head())
from utilsforecast.evaluation import evaluate
from utilsforecast.losses import mae, rmse, mape
eval_df = evaluate(cv_df.drop(columns=["cutoff"]), metrics=[mae, rmse, mape])
print("\n=== Per-series error (lower = better) ===")
print(eval_df.round(3))
model_cols = [c for c in eval_df.columns if c not in ("unique_id", "metric")]
leaderboard = (eval_df.groupby("metric")[model_cols].mean().T.sort_values("rmse"))
print("\n=== Leaderboard (mean across series) ===")
print(leaderboard.round(3))
best_model = leaderboard.index[0]
print(f"\n>>> Best model by mean RMSE: {best_model}")
We perform rolling cross-validation across three windows to measure each model’s forecasting performance. We calculate MAE, RMSE, and MAPE for every series and aggregate the results into a leaderboard. We identify the model with the lowest mean RMSE for subsequent forecasting and visualization.
Generating Probabilistic Forecasts with Prediction Intervals
Copy CodeCopiedUse a different Browser
fcst_df = tcf.forecast(df=panel, h=H, freq=FREQ, level=[80, 95])
print("\nForecast columns:", list(fcst_df.columns))
def plot_series(uid, point_model=best_model):
hist = panel[panel["unique_id"] == uid]; fc = fcst_df[fcst_df["unique_id"] == uid]
plt.figure(figsize=(11, 4)); plt.plot(hist["ds"], hist["y"], color="black", label="history")
if point_model in fc.columns:
plt.plot(fc["ds"], fc[point_model], color="C0", label=f"{point_model} forecast")
lo, hi = f"{point_model}-lo-95", f"{point_model}-hi-95"
if lo in fc.columns and hi in fc.columns:
plt.fill_between(fc["ds"], fc[lo], fc[hi], alpha=0.25, color="C0", label="95% interval")
plt.title(f"{uid} — {point_model}"); plt.legend(); plt.tight_layout(); plt.show()
for uid in panel["unique_id"].unique():
plot_series(uid)
We generate 12-month probabilistic forecasts with 80% and 95% prediction intervals. We define a reusable plotting function that displays historical values, point forecasts, and uncertainty ranges. We apply this function to each series to compare its observed history with the predicted future trajectory.
Detecting Anomalies Across the Forecasting Panel
Copy CodeCopiedUse a different Browser
print("\nRunning anomaly detection...")
anomalies_df = tcf.detect_anomalies(df=panel, h=H, freq=FREQ, level=99)
anom_cols = [c for c in anomalies_df.columns if c.endswith("-anomaly")]
if anom_cols:
flagged = anomalies_df[anomalies_df[anom_cols].any(axis=1)]
print(f"Flagged points (>=1 model): {len(flagged)}")
print(flagged[["unique_id", "ds", "y"] + anom_cols].head(20).to_string(index=False))
col = f"{best_model}-anomaly"
if col not in anomalies_df.columns: col = anom_cols[0]
sub = anomalies_df[anomalies_df["unique_id"] == "Synthetic"]
pts = sub[sub[col] == True]
plt.figure(figsize=(11, 4)); plt.plot(sub["ds"], sub["y"], color="black", label="value")
plt.scatter(pts["ds"], pts["y"], color="red", zorder=5, label=f"anomaly ({col})")
plt.title("Anomaly detection — Synthetic series"); plt.legend(); plt.tight_layout(); plt.show()
else:
print(anomalies_df.head())
Interpreting Forecasts with the TimeCopilot LLM Agent
Copy CodeCopiedUse a different Browser
from timecopilot import TimeCopilot
if os.environ.get("OPENAI_API_KEY") or os.environ.get("ANTHROPIC_API_KEY"):
llm = "openai:gpt-4o" if os.environ.get("OPENAI_API_KEY") else "anthropic:claude-sonnet-4-5"
tc = TimeCopilot(llm=llm, retries=3)
single = panel[panel["unique_id"] == "AirPassengers"]
result = tc.forecast(df=single, freq=FREQ, h=H,
query="Total air passengers expected over the next 12 months, and which months peak?")
out = result.output
print("\n=== AGENT REPORT ===")
print("Selected model:", out.selected_model)
print("Beats SeasonalNaive:", out.is_better_than_seasonal_naive)
print("Why:", out.reason_for_selection)
print("Answer:", out.user_query_response)
print(result.fcst_df.head())
else:
print("\n[Agent section skipped] No LLM key. Everything above ran key-free.")
print("\nDone.
image")
We detect anomalies across the panel and visualize the flagged observations in the synthetic series. We optionally initialize the TimeCopilot LLM agent when an OpenAI or Anthropic API key is available. We use the agent to select a model, evaluate it against SeasonalNaive, and explain the forecast in response to a practical question.
Conclusion
In conclusion, we created a unified TimeCopilot pipeline that takes us from data preparation to model evaluation, probabilistic forecasting, visualization, anomaly detection, and agent-driven interpretation. We compared traditional statistical methods with modern foundation models within a consistent cross-validation framework and selected the best-performing approach based on objective error metrics. We also quantified forecast uncertainty through prediction intervals and identified abnormal observations across multiple time series. By combining automated forecasting with an optional LLM agent, we produced both accurate numerical predictions and clear, decision-oriented insights within a single workflow.
Check out the Full Codes with Notebook. Also, feel free to follow us on Twitter and don’t forget to join our 150k+ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.
Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us
The post How to Build a Forecasting Pipeline with TimeCopilot Using Foundation Models and Automated Anomaly Detection appeared first on MarkTechPost.
News to Guide
ニュースの次に確認する
発表内容を、現在の料金や仕様と照らし合わせられる関連ガイドです。
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み