timesfm-forecasting について
timesfm-forecasting は、TimesFM による単変量時系列のローカルなゼロショット予測スキルです。予測区間や一括処理に対応し、モデル読み込み前にシステムリソースを確認します。
主な機能
- 01単変量のゼロショット予測
- 02点予測と分位点予測
- 03共変量を使った予測
- 04時系列の一括処理
- 05読み込み前のリソース確認
活用シーン
- 01売上やセンサー値の予測
- 02予測区間の生成
- 03複数時系列の一括予測
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ crazymsn/ academic-skills --skill timesfm-forecastingインストール後、Claude Code で/timesfm-forecastingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
examples/anomaly-detection/detect_anomalies.pyexamples/anomaly-detection/output/anomaly_detection.jsonexamples/covariates-forecasting/demo_covariates.pyexamples/covariates-forecasting/output/covariates_metadata.jsonsales_with_covariates.csvexamples/global-temperature/generate_animation_data.pygenerate_gif.pygenerate_html.pyREADME.mdrun_example.shrun_forecast.pytemperature_anomaly.csvvisualize_forecast.pyexamples/global-temperature/output/animation_data.jsonforecast_output.csvforecast_output.jsoninteractive_forecast.htmlreferences/api_reference.mddata_preparation.mdsystem_requirements.mdscripts/check_system.pyforecast_csv.py詳細
TimesFM 予測
概要
TimesFM(Time Series Foundation Model)は、Google Research が開発した、時系列予測用の事前学習済みデコーダー専用基盤モデルです。ゼロショットで動作し、任意の単変量時系列を入力すると、学習なしで点予測と、校正済みの分位点予測区間を返します。
このスキルは、TimesFM を安全かつエージェントに適したローカル推論用にラップします。モデルの読み込み前に RAM、GPU メモリ、ディスク容量を確認する必須の事前チェックシステムを備えているため、エージェントによってユーザーのマシンがクラッシュすることはありません。
主な数値:TimesFM 2.5 は 2 億パラメーター(ディスク上で約 800 MB、CPU で約 1.5 GB の RAM、GPU で約 1 GB の VRAM)を使用します。アーカイブ済みの v1/v2 500M パラメーターのモデルには約 32 GB の RAM が必要です。 必ず最初にシステムチェッカーを実行してください。
このスキルを使用する場面
以下の場合にこのスキルを使用してください。
- あらゆる単変量時系列(売上、需要、センサー、バイタル、価格、天気)を予測する場合
- カスタムモデルを学習させずにゼロショット予測を行いたい場合
- 校正済みの予測区間(分位点)を含む確率的予測が必要な場合
- 任意の長さの時系列を扱う場合(モデルは 1~16,384 個のコンテキストポイントを処理します)
- 数百または数千の時系列を効率よくバッチ予測する必要がある場合
- ARIMA/ETS のパラメーターを手動で調整する代わりに、基盤モデルを利用したい場合
以下の場合は、このスキルを使用しないでください。
- 係数を解釈できる古典的な統計モデルが必要な場合 →
statsmodelsを使用してください - 時系列の分類やクラスタリングが必要な場合 →
aeonを使用してください - 多変量ベクトル自己回帰やグレンジャー因果性が必要な場合 →
statsmodelsを使用してください - データが表形式の場合(時系列データではない場合)→
scikit-learnを使用してください
異常検知についての注意:TimesFM に異常検知機能は組み込まれていませんが、分位点予測を予測区間として使用できます。90% 信頼区間(q10~q90)の範囲外の値は、統計的に異常です。詳しい例については、
examples/anomaly-detection/ディレクトリを参照してください。
⚠️ 必須の事前チェック:システム要件の確認
重要 — 初めてモデルを読み込む前に、必ずシステムチェッカーを実行してください。
python scripts/check_system.py
このスクリプトでは、次の項目を確認します。
- 利用可能な RAM — 4 GB 未満の場合は警告し、2 GB 未満の場合は処理を中断します
- GPU の利用可否 — CUDA/MPS デバイスと VRAM を検出します
- ディスク容量 — 約 800 MB のモデルをダウンロードできる空き容量があるか確認します
- Python バージョン — 3.10 以降が必要です
- 既存のインストール状況 —
timesfmとtorchがインストールされているか確認します
注意: モデルの重みはこのリポジトリには保存されていません。TimesFM の重み(約 800 MB)は、初回使用時に HuggingFace からオンデマンドでダウンロードされ、
~/.cache/huggingface/にキャッシュされます。 事前チェックにより、ダウンロードを開始する前に十分なリソースがあることを確認できます。
flowchart TD
accTitle: Preflight System Check
accDescr: Decision flowchart showing the system requirement checks that must pass before loading TimesFM.
start["🚀 Run check_system.py"] --> ram{"RAM ≥ 4 GB?"}
ram -->|"Yes"| gpu{"GPU available?"}
ram -->|"No (2-4 GB)"| warn_ram["⚠️ Warning: tight RAM<br/>CPU-only, small batches"]
ram -->|"No (< 2 GB)"| block["🛑 BLOCKED<br/>Insufficient memory"]
warn_ram --> disk
gpu -->|"CUDA / MPS"| vram{"VRAM ≥ 2 GB?"}
gpu -->|"CPU only"| cpu_ok["✅ CPU mode<br/>Slower but works"]
vram -->|"Yes"| gpu_ok["✅ GPU mode<br/>Fast inference"]
vram -->|"No"| cpu_ok
gpu_ok --> disk{"Disk ≥ 2 GB free?"}
cpu_ok --> disk
disk -->|"Yes"| ready["✅ READY<br/>Safe to load model"]
disk -->|"No"| block_disk["🛑 BLOCKED<br/>Need space for weights"]
classDef ok fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
classDef warn fill:#fef9c3,stroke:#ca8a04,stroke-width:2px,color:#713f12
classDef block fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#7f1d1d
classDef neutral fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#1f2937
class ready,gpu_ok,cpu_ok ok
class warn_ram warn
class block,block_disk block
class start,ram,gpu,vram,disk neutral
モデルバージョン別のハードウェア要件
| モデル | パラメーター | RAM(CPU) | VRAM(GPU) | ディスク | コンテキスト |
|---|---|---|---|---|---|
| TimesFM 2.5(推奨) | 200M | ≥ 4 GB | ≥ 2 GB | 約 800 MB | 最大 16,384 |
| TimesFM 2.0(アーカイブ済み) | 500M | ≥ 16 GB | ≥ 8 GB | 約 2 GB | 最大 2,048 |
| TimesFM 1.0(アーカイブ済み) | 200M | ≥ 8 GB | ≥ 4 GB | 約 800 MB | 最大 2,048 |
推奨: 古いチェックポイントを使用する特別な理由がない限り、常に TimesFM 2.5 を使用してください。より小型で高速なうえ、8 倍長いコンテキストに対応しています。
🔧 インストール
ステップ 1:システムを確認する(必ず最初に実行)
python scripts/check_system.py
ステップ 2:TimesFM をインストールする
# Using uv (recommended by this repo)
uv pip install timesfm[torch]
# Or using pip
pip install timesfm[torch]
# For JAX/Flax backend (faster on TPU/GPU)
uv pip install timesfm[flax]
ステップ 3:ハードウェアに対応した PyTorch をインストールする
# CUDA 12.1 (NVIDIA GPU)
pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cu121
# CPU only
pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cpu
# Apple Silicon (MPS)
pip install torch>=2.0.0 # MPS support is built-in
ステップ 4:インストールを確認する
import timesfm
import numpy as np
print(f"TimesFM version: {timesfm.__version__}")
print("Installation OK")
🎯 クイックスタート
最小限の例(5 行)
import torch, numpy as np, timesfm
torch.set_float32_matmul_precision("high")
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch"
)
model.compile(timesfm.ForecastConfig(
max_context=1024, max_horizon=256, normalize_inputs=True,
use_continuous_quantile_head=True, force_flip_invariance=True,
infer_is_positive=True, fix_quantile_crossing=True,
))
point, quantiles = model.forecast(horizon=24, inputs=[
np.sin(np.linspace(0, 20, 200)), # any 1-D array
])
# point.shape == (1, 24) — median forecast
# quantiles.shape == (1, 24, 10) — 10th–90th percentile bands
CSV から予測する
import pandas as pd, numpy as np
df = pd.read_csv("monthly_sales.csv", parse_dates=["date"], index_col="date")
# Convert each column to a list of arrays
inputs = [df[col].dropna().values.astype(np.float32) for col in df.columns]
point, quantiles = model.forecast(horizon=12, inputs=inputs)
# Build a results DataFrame
for i, col in enumerate(df.columns):
last_date = df[col].dropna().index[-1]
future_dates = pd.date_range(last_date, periods=13, freq="MS")[1:]
forecast_df = pd.DataFrame({
"date": future_dates,
"forecast": point[i],
"lower_80": quantiles[i, :, 2], # 20th percentile
"upper_80": quantiles[i, :, 8], # 80th percentile
})
print(f"\n--- {col} ---")
print(forecast_df.to_string(index=False))
共変量を使用した予測(XReg)
TimesFM 2.5+ は、forecast_with_covariates() を通じて外生変数をサポートします。timesfm[xreg] が必要です。
# Requires: uv pip install timesfm[xreg]
point, quantiles = model.forecast_with_covariates(
inputs=inputs,
dynamic_numerical_covariates={"price": price_arrays},
dynamic_categorical_covariates={"holiday": holiday_arrays},
static_categorical_covariates={"region": region_labels},
xreg_mode="xreg + timesfm", # or "timesfm + xreg"
)
| 共変量の種類 | 説明 | 例 |
|---|---|---|
dynamic_numerical | 時間とともに変化する数値 | 価格、気温、販促費 |
dynamic_categorical | 時間とともに変化するカテゴリ | 休日フラグ、曜日 |
static_numerical | 系列ごとの数値 | 店舗規模、アカウントの利用期間 |
static_categorical | 系列ごとのカテゴリ | 店舗の種類、地域、商品カテゴリ |
XReg のモード:
"xreg + timesfm"(デフォルト):TimesFM が最初に予測し、その後 XReg が残差を調整します"timesfm + xreg":XReg が最初にフィッティングし、その後 TimesFM が残差を予測します
合成小売データを使った完全な例については、
examples/covariates-forecasting/をご覧ください。
異常検知(分位点区間を使用)
TimesFM に異常検知機能は組み込まれていませんが、分位点予測によって予測区間が自然に得られるため、異常を検知できます。
point, q = model.forecast(horizon=H, inputs=[values])
# 90% prediction interval
lower_90 = q[0, :, 1] # 10th percentile
upper_90 = q[0, :, 9] # 90th percentile
# Detect anomalies: values outside the 90% CI
actual = test_values # your holdout data
anomalies = (actual < lower_90) | (actual > upper_90)
# Severity levels
is_warning = (actual < q[0, :, 2]) | (actual > q[0, :, 8]) # outside 80% CI
is_critical = anomalies # outside 90% CI
| 深刻度 | 条件 | 解釈 |
|---|---|---|
| 正常 | 80% 信頼区間内 | 予測される挙動 |
| 警告 | 80% 信頼区間外 | まれではあるが起こり得る |
| 重大 | 90% 信頼区間外 | 統計的にまれ(確率 < 10%) |
可視化を含む完全な例については、
examples/anomaly-detection/をご覧ください。
# Requires: uv pip install timesfm[xreg]
point, quantiles = model.forecast_with_covariates(
inputs=inputs,
dynamic_numerical_covariates={"temperature": temp_arrays},
dynamic_categorical_covariates={"day_of_week": dow_arrays},
static_categorical_covariates={"region": region_labels},
xreg_mode="xreg + timesfm", # or "timesfm + xreg"
)
📊 出力の理解
分位点予測の構造
TimesFM は (point_forecast, quantile_forecast) を返します。
point_forecast:形状(batch, horizon)— 中央値(0.5 分位点)quantile_forecast:形状(batch, horizon, 10)— 10 個のスライス:
| インデックス | 分位点 | 用途 |
|---|---|---|
| 0 | 平均 | 平均予測 |
| 1 | 0.1 | 80% PI の下限 |
| 2 | 0.2 | 60% PI の下限 |
| 3 | 0.3 | — |
| 4 | 0.4 | — |
| 5 | 0.5 | 中央値(= point_forecast) |
| 6 | 0.6 | — |
| 7 | 0.7 | — |
| 8 | 0.8 | 60% PI の上限 |
| 9 | 0.9 | 80% PI の上限 |
予測区間の抽出
point, q = model.forecast(horizon=H, inputs=data)
# 80% prediction interval (most common)
lower_80 = q[:, :, 1] # 10th percentile
upper_80 = q[:, :, 9] # 90th percentile
# 60% prediction interval (tighter)
lower_60 = q[:, :, 2] # 20th percentile
upper_60 = q[:, :, 8] # 80th percentile
# Median (same as point forecast)
median = q[:, :, 5]
flowchart LR
accTitle: Quantile Forecast Anatomy
accDescr: Diagram showing how the 10-element quantile vector maps to prediction intervals.
input["📈 Input Series<br/>1-D array"] --> model["🤖 TimesFM<br/>compile + forecast"]
model --> point["📍 Point Forecast<br/>(batch, horizon)"]
model --> quant["📊 Quantile Forecast<br/>(batch, horizon, 10)"]
quant --> pi80["80% PI<br/>q[:,:,1] – q[:,:,9]"]
quant --> pi60["60% PI<br/>q[:,:,2] – q[:,:,8]"]
quant --> median["Median<br/>q[:,:,5]"]
classDef data fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e3a5f
classDef model fill:#f3e8ff,stroke:#9333ea,stroke-width:2px,color:#581c87
classDef output fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
class input data
class model model
class point,quant,pi80,pi60,median output
🔧 ForecastConfig リファレンス
予測の動作はすべて timesfm.ForecastConfig で制御します。
timesfm.ForecastConfig(
max_context=1024, # Max context window (truncates longer series)
max_horizon=256, # Max forecast horizon
normalize_inputs=True, # Normalize inputs (RECOMMENDED for stability)
per_core_batch_size=32, # Batch size per device (tune for memory)
use_continuous_quantile_head=True, # Better quantile accuracy for long horizons
force_flip_invariance=True, # Ensures f(-x) = -f(x) (mathematical consistency)
infer_is_positive=True, # Clamp forecasts ≥ 0 when all inputs > 0
fix_quantile_crossing=True, # Ensure q10 ≤ q20 ≤ ... ≤ q90
return_backcast=False, # Return backcast (for covariate workflows)
)
| パラメーター | デフォルト | 変更する場合 |
|---|---|---|
max_context | 0 | 最長の過去ウィンドウに合わせて設定します(例:512、1024、4096) |
max_horizon | 0 | 予測の最大長に設定します |
normalize_inputs | False | 必ず True に設定してください — スケール依存の不安定さを防ぎます |
per_core_batch_size | 1 | スループットを高めるには増やし、OOM が発生する場合は減らします |
use_continuous_quantile_head | False | 較正済みの予測区間を得るには True に設定してください |
force_flip_invariance | True | プロファイリングで悪影響が確認されない限り、True のままにします |
infer_is_positive | True | 負の値を取り得る系列(気温、リターン)では False に設定します |
fix_quantile_crossing | False | 分位点の単調性を保証するには True に設定してください |
📋 よくあるワークフロー
ワークフロー 1:単一系列の予測
flowchart TD
accTitle: Single Series Forecast Workflow
accDescr: Step-by-step workflow for forecasting a single time series with system checking.
check["1. Run check_system.py"] --> load["2. Load model<br/>from_pretrained()"]
load --> compile["3. Compile with ForecastConfig"]
compile --> prep["4. Prepare data<br/>pd.read_csv → np.array"]
prep --> forecast["5. model.forecast()<br/>horizon=N"]
forecast --> extract["6. Extract point + PI"]
extract --> plot["7. Plot or export results"]
classDef step fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#1f2937
class check,load,compile,prep,forecast,extract,plot step
import torch, numpy as np, pandas as pd, timesfm
# 1. System check (run once)
# python scripts/check_system.py
# 2-3. Load and compile
torch.set_float32_matmul_precision("high")
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch"
)
model.compile(timesfm.ForecastConfig(
max_context=512, max_horizon=52, normalize_inputs=True,
use_continuous_quantile_head=True, fix_quantile_crossing=True,
))
# 4. Prepare data
df = pd.read_csv("weekly_demand.csv", parse_dates=["week"])
values = df["demand"].values.astype(np.float32)
# 5. Forecast
point, quantiles = model.forecast(horizon=52, inputs=[values])
# 6. Extract prediction intervals
forecast_df = pd.DataFrame({
"forecast": point[0],
"lower_80": quantiles[0, :, 1],
"upper_80": quantiles[0, :, 9],
})
# 7. Plot
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(values[-104:], label="Historical")
x_fc = range(len(values[-104:]), len(values[-104:]) + 52)
ax.plot(x_fc, forecast_df["forecast"], label="Forecast", color="tab:orange")
ax.fill_between(x_fc, forecast_df["lower_80"], forecast_df["upper_80"],
alpha=0.2, color="tab:orange", label="80% PI")
ax.legend()
ax.set_title("52-Week Demand Forecast")
plt.tight_layout()
plt.savefig("forecast.png", dpi=150)
print("Saved forecast.png")
ワークフロー 2:バッチ予測(複数の系列)
import pandas as pd, numpy as np
# Load wide-format CSV (one column per series)
df = pd.read_csv("all_stores.csv", parse_dates=["date"], index_col="date")
inputs = [df[col].dropna().values.astype(np.float32) for col in df.columns]
# Forecast all series at once (batched internally)
point, quantiles = model.forecast(horizon=30, inputs=inputs)
# Collect results
results = {}
for i, col in enumerate(df.columns):
results[col] = {
"forecast": point[i].tolist(),
"lower_80": quantiles[i, :, 1].tolist(),
"upper_80": quantiles[i, :, 9].tolist(),
}
# Export
import json
with open("batch_forecasts.json", "w") as f:
json.dump(results, f, indent=2)
print(f"Forecasted {len(results)} series → batch_forecasts.json")
ワークフロー 3:予測精度の評価
import numpy as np
# Hold out the last H points for evaluation
H = 24
train = values[:-H]
actual = values[-H:]
point, quantiles = model.forecast(horizon=H, inputs=[train])
pred = point[0]
# Metrics
mae = np.mean(np.abs(actual - pred))
rmse = np.sqrt(np.mean((actual - pred) ** 2))
mape = np.mean(np.abs((actual - pred) / actual)) * 100
# Prediction interval coverage
lower = quantiles[0, :, 1]
upper = quantiles[0, :, 9]
coverage = np.mean((actual >= lower) & (actual <= upper)) * 100
print(f"MAE: {mae:.2f}")
print(f"RMSE: {rmse:.2f}")
print(f"MAPE: {mape:.1f}%")
print(f"80% PI Coverage: {coverage:.1f}% (target: 80%)")
⚙️ パフォーマンスの調整
GPU アクセラレーション
import torch
# Check GPU availability
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"VRAM: {torch.cuda.get_device_properties(0).total_mem / 1e9:.1f} GB")
elif hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
print("Apple Silicon MPS available")
else:
print("CPU only — inference will be slower but still works")
# Always set this for Ampere+ GPUs (A100, RTX 3090, etc.)
torch.set_float32_matmul_precision("high")
バッチサイズの調整
# Start conservative, increase until OOM
# GPU with 8 GB VRAM: per_core_batch_size=64
# GPU with 16 GB VRAM: per_core_batch_size=128
# GPU with 24 GB VRAM: per_core_batch_size=256
# CPU with 8 GB RAM: per_core_batch_size=8
# CPU with 16 GB RAM: per_core_batch_size=32
# CPU with 32 GB RAM: per_core_batch_size=64
model.compile(timesfm.ForecastConfig(
max_context=1024,
max_horizon=256,
per_core_batch_size=32, # <-- tune this
normalize_inputs=True,
use_continuous_quantile_head=True,
fix_quantile_crossing=True,
))
メモリに制約のある環境
import gc, torch
# Force garbage collection before loading
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
# Load model
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch"
)
# Use small batch size on low-memory machines
model.compile(timesfm.ForecastConfig(
max_context=512, # Reduce context if needed
max_horizon=128, # Reduce horizon if needed
per_core_batch_size=4, # Small batches
normalize_inputs=True,
use_continuous_quantile_head=True,
fix_quantile_crossing=True,
))
# Process series in chunks to avoid OOM
CHUNK = 50
all_results = []
for i in range(0, len(inputs), CHUNK):
chunk = inputs[i:i+CHUNK]
p, q = model.forecast(horizon=H, inputs=chunk)
all_results.append((p, q))
gc.collect() # Clean up between chunks
🔗 他のスキルとの連携
statsmodels との連携
古典的なモデル(ARIMA、SARIMAX)には、比較のベースラインとして statsmodels を使用します。
# TimesFM forecast
tfm_point, tfm_q = model.forecast(horizon=H, inputs=[values])
# statsmodels ARIMA forecast
from statsmodels.tsa.arima.model import ARIMA
arima = ARIMA(values, order=(1,1,1)).fit()
arima_forecast = arima.forecast(steps=H)
# Compare
print(f"TimesFM MAE: {np.mean(np.abs(actual - tfm_point[0])):.2f}")
print(f"ARIMA MAE: {np.mean(np.abs(actual - arima_forecast)):.2f}")
matplotlib / scientific-visualization との連携
予測区間を含む予測を、出版品質の図としてプロットします。
exploratory-data-analysis との連携
予測の前に時系列の EDA を実行し、トレンド、季節性、定常性を把握します。
📚 利用可能なスクリプト
scripts/check_system.py
必須の事前チェックツールです。 最初にモデルを読み込む前に実行してください。
python scripts/check_system.py
出力例:
=== TimesFM System Requirements Check ===
[RAM] Total: 32.0 GB | Available: 24.3 GB ✅ PASS
[GPU] NVIDIA RTX 4090 | VRAM: 24.0 GB ✅ PASS
[Disk] Free: 142.5 GB ✅ PASS
[Python] 3.12.1 ✅ PASS
[timesfm] Installed (2.5.0) ✅ PASS
[torch] Installed (2.4.1+cu121) ✅ PASS
VERDICT: ✅ System is ready for TimesFM 2.5 (GPU mode)
Recommended: per_core_batch_size=128
scripts/forecast_csv.py
システムの自動チェックを含む、CSV の予測をエンドツーエンドで実行します。
python scripts/forecast_csv.py input.csv \
--horizon 24 \
--date-col date \
--value-cols sales,revenue \
--output forecasts.csv
📖 リファレンスドキュメント
詳細なガイドは references/ にあります。
| ファイル | 内容 |
|---|---|
references/system_requirements.md | ハードウェアの段階、GPU/CPU の選択、メモリの推定式 |
references/api_reference.md | ForecastConfig の全ドキュメント、from_pretrained のオプション、出力の形状 |
references/data_preparation.md | 入力形式、NaN の処理、CSV の読み込み、共変量の設定 |
よくある落とし穴
- システムチェックを実行しない → RAM が少ないマシンではモデルの読み込みがクラッシュします。必ず最初に
check_system.pyを実行してください。 model.compile()を忘れる →RuntimeError: Model is not compiledが発生します。forecast()の前に必ずcompile()を呼び出してください。normalize_inputs=Trueを設定しない → 値が大きい系列では予測が不安定になります。- RAM が 32 GB 未満のマシンで v1/v2 を使用する → 代わりに TimesFM 2.5(パラメーター数 200M)を使用してください。
fix_quantile_crossing=Trueを設定しない → 分位点が単調にならない場合があります(q10 > q50)。- 小型 GPU で
per_core_batch_sizeを大きくしすぎる → CUDA の OOM が発生します。小さな値から始めて、徐々に増やしてください。 - 2 次元配列を渡す → TimesFM が想定するのは 2 次元行列ではなく、1 次元配列のリストです。
torch.set_float32_matmul_precision("high")を忘れる → Ampere 以降の GPU で推論が遅くなります。- 出力の NaN を処理しない → 系列が非常に短い場合に問題が発生することがあります。必ず
np.isnan(point).any()を確認してください。 - 負の値を取り得る系列で
infer_is_positive=Trueを使用する → 予測値がゼロに制限されます。気温やリターンなどでは False に設定してください。
モデルのバージョン
timeline
accTitle: TimesFM Version History
accDescr: Timeline of TimesFM model releases showing parameter counts and key improvements.
section 2024
TimesFM 1.0 : 200M params, 2K context, JAX only
TimesFM 2.0 : 500M params, 2K context, PyTorch + JAX
section 2025
TimesFM 2.5 : 200M params, 16K context, quantile head, no frequency indicator
| バージョン | パラメーター数 | コンテキスト | 分位点ヘッド | 頻度フラグ | ステータス |
|---|---|---|---|---|---|
| 2.5 | 200M | 16,384 | ✅ 連続(30M) | ❌ 廃止 | 最新 |
| 2.0 | 500M | 2,048 | ✅ 固定バケット | ✅ 必須 | アーカイブ済み |
| 1.0 | 200M | 2,048 | ✅ 固定バケット | ✅ 必須 | アーカイブ済み |
Hugging Face のチェックポイント:
google/timesfm-2.5-200m-pytorch(推奨)google/timesfm-2.5-200m-flaxgoogle/timesfm-2.0-500m-pytorch(アーカイブ済み)google/timesfm-1.0-200m-pytorch(アーカイブ済み)
リソース
- 論文:A Decoder-Only Foundation Model for Time-Series Forecasting(ICML 2024)
- リポジトリ:https://github.com/google-research/timesfm
- Hugging Face:https://huggingface.co/collections/google/timesfm-release-66e4be5fdb56e960c1e482a6
- Google ブログ:https://research.google/blog/a-decoder-only-foundation-model-for-time-series-forecasting/
- BigQuery との統合:https://cloud.google.com/bigquery/docs/timesfm-model
例
実際に動作するリファレンス例が examples/ に 3 つあります。API の正しい使用方法と想定される出力形状を確認するための正解例として使用してください。
| 例 | ディレクトリ | 内容 | 使用する場面 |
|---|---|---|---|
| 全球気温予測 | examples/global-temperature/ | 基本的な model.forecast() 呼び出し、CSV → PNG → GIF のパイプライン、NOAA の 36 か月分のコンテキスト | 開始点として、あらゆる単変量系列のベースラインにコピーして使用 |
| 異常検知 | examples/anomaly-detection/ | 2 段階の検知:コンテキストでの線形トレンド除去+Z スコア、予測での分位点 PI、2 パネルの可視化 | 過去データと予測データの外れ値検知が必要なタスク全般 |
| 共変量(XReg) | examples/covariates-forecasting/ | forecast_with_covariates() API(TimesFM 2.5)、共変量の分解、共有軸を使った 2x2 の可視化 | 小売、エネルギー、または既知の外生的要因がある系列 |
例の実行
# Global temperature (no TimesFM 2.5 needed)
cd examples/global-temperature && python run_forecast.py && python visualize_forecast.py
# Anomaly detection (uses TimesFM 1.0)
cd examples/anomaly-detection && python detect_anomalies.py
# Covariates (API demo -- requires TimesFM 2.5 + timesfm[xreg] for real inference)
cd examples/covariates-forecasting && python demo_covariates.py
期待される出力
| 例 | 主な出力ファイル | 合格基準 |
|---|---|---|
| global-temperature | output/forecast_output.json, output/forecast_visualization.png | point_forecast に12個の値があること。PNG にコンテキスト+予測+PI バンドが表示されていること |
| anomaly-detection | output/anomaly_detection.json, output/anomaly_detection.png | 2023年9月が CRITICAL として検出されること(z >= 3.0)。注入した異常値により、予測で CRITICAL が2件以上あること |
| covariates-forecasting | output/sales_with_covariates.csv, output/covariates_data.png | CSV に108行(3店舗 x 36週間)があること。店舗ごとに異なる価格配列があること |
品質チェックリスト
TimesFM のタスクを実行するたびに、成功を宣言する前にこのチェックリストを確認してください。
- 出力形状が正しい --
point_fcの形状は(n_series, horizon)、quant_fcの形状は(n_series, horizon, 10)です - 分位点インデックス -- インデックス0 = 平均、1 = q10、2 = q20 ... 9 = q90 です。0 = q0、1 = q10 ではありません。
- 頻度フラグ -- TimesFM 1.0/2.0:月次データには
freq=[0]を渡します。TimesFM 2.5:freq フラグは不要です。 - 系列の長さ -- コンテキストには32個以上のデータポイントが必要です(モデルの最小値)。それより短い場合は警告してください。
- NaN がないこと --
np.isnan(point_fc).any()は False である必要があります。まず入力系列に欠損がないか確認してください。 - 可視化の軸 -- 複数のパネルでデータを共有する場合は、
sharex=Trueを使用してください。すべての時間軸で同じ範囲を対象にする必要があります。 - Git LFS によるバイナリ出力の管理 -- PNG ファイルと GIF ファイルは
.gitattributesによって追跡する必要があります(リポジトリのルートでは設定済みです)。 - 大規模なデータセットをコミットしないこと -- 1 MB を超える実データセットは
tempfile.mkdtemp()にダウンロードし、コード内にその旨を記載してください。 -
matplotlib.use('Agg')-- ヘッドレス環境で実行する場合、pyplot をインポートする前に記述する必要があります。 -
infer_is_positive-- 気温の異常値、金融リターン、または負の値を取りうる系列ではFalseに設定してください。
よくある間違い
このスキルの例では、次のバグが発生しています。内容を確認してください。
-
分位点インデックスのずれ -- 最もよくある間違いです。
quant_fc[..., 0]は q0 ではなく、平均です。q10 = インデックス1、q90 = インデックス9 です。名前付き定数を必ず定義してください:IDX_Q10, IDX_Q20, IDX_Q80, IDX_Q90 = 1, 2, 8, 9。 -
内包表記での変数のシャドーイング -- ループ内で系列ごとの共変量辞書を作成する場合、ループ変数を内包表記の変数として使用しないでください。ループの外で別の
dict[str, ndarray]に蓄積してから、代入してください。# WRONG -- outer `store_id` gets shadowed: covariates = {store_id: arr[store_id] for store_id in stores} # inside outer loop over store_id # CORRECT -- use a different name or accumulate beforehand: prices_by_store: dict[str, np.ndarray] = {} for store_id, config in stores.items(): prices_by_store[store_id] = compute_price(config) -
CSV の列名が誤っている -- global-temperature の CSV では
anomalyではなくanomaly_cを使用します。アクセスする前に必ずprint(df.columns)を実行してください。 -
sharex=Trueでのtight_layout()警告 -- 無害です。plt.tight_layout(rect=[0, 0, 1, 0.97])で抑制するか、無視してください。 -
forecast_with_covariates()には TimesFM 2.5 が必須 -- TimesFM 1.0 にはこのメソッドがありません。pip install timesfm[xreg]をインストールし、チェックポイントgoogle/timesfm-2.5-200m-pytorchを使用してください。 -
将来の共変量は予測期間全体をカバーする必要がある -- 動的共変量(価格、販促、休日)は、コンテキストと予測期間の両方に値が必要です。コンテキストのみの配列は渡せません。
-
異常値のしきい値は一度だけ定義すること -- モジュールレベルの定数として
CRITICAL_Z = 3.0、WARNING_Z = 2.0を定義してください。インラインで3や2をハードコードしないでください。 -
コンテキストの異常検知には、生の値ではなく残差を使用する -- 必ず最初にトレンドを除去してから(線形の
np.polyfitまたは季節分解を使用)、残差の Z スコアを計算してください。トレンドのあるデータで生の値の Z スコアを使うと、誤解を招きます。
検証と確認
例の出力を回帰テストのベースラインとして使用してください。予測ロジックを変更した場合は、次の点を確認してください。
# Anomaly detection regression check:
python -c "
import json
d = json.load(open('examples/anomaly-detection/output/anomaly_detection.json'))
ctx = d['context_summary']
assert ctx['critical'] >= 1, 'Sep 2023 must be CRITICAL'
assert any(r['date'] == '2023-09' and r['severity'] == 'CRITICAL'
for r in d['context_detections']), 'Sep 2023 not found'
print('Anomaly detection regression: PASS')"
# Covariates regression check:
python -c "
import pandas as pd
df = pd.read_csv('examples/covariates-forecasting/output/sales_with_covariates.csv')
assert len(df) == 108, f'Expected 108 rows, got {len(df)}'
prices = df.groupby('store_id')['price'].mean()
assert prices['store_A'] > prices['store_B'] > prices['store_C'], 'Store price ordering wrong'
print('Covariates regression: PASS')"