ゼロショット時系列予測｜TimeGPT-1の初期調査

# はじめに

現在，大規模言語モデル (LLM) の話題が絶えず，社会での利用が進んでいるところである．これらの話題の中心には，基盤モデル (Foundation Model: FM) である GPT-4 とそれを対話形式に適するようにチューニングした ChatGPT (GPT-4 Turbo) というLLM がある．基盤モデルとは大量のデータから教師なし学習で高い汎用性を獲得したモデルを指し，そこから教師ありのチューニングを経て用途毎のモデルを得るものである．

GPT3.5 Turbo を皮切りに PaLmやLLaMA，StableLMなど多くの基盤モデル兼LLMが登場している最中であり，画像や音声に対応したマルチモーダルなモデルも現れ，様々なタスク（画像，音声…）に利用されている．

LLMのコア技術となるのが Transformer (モデルないしはアーキテクチャ)であり，登場してまもない間はどんなタスクにもTransformerを適用する流れがあった．これはCNNやGAN など当時のトレンド技術が出現した際も他のタスクに適用されてきた．そのため，現在の流行の中心である基盤モデルも様々なタスクに用いるのは当然の流れであり，ここで紹介する時系列に関するタスクに利用されることも自然である．

時系列データは様々な箇所にありながら，専門的な知識を必要とするなど，社会的な活用が不十分であると私は認識している．そこで，この問題にアプローチが可能と思われる，おそらくは初の時系列基盤モデルTimeGPT-1 [1] について取り上げて調査をしてみることとした．

# TimeGPTとは

下図にTImeGPTのアーキテクチャを示す [1] ．基本的にはGPTなどのLLMと同じTransformerベースであるが，時系列を直接入力として与えている．LLMのような次の単語予測予測(Softmax)と異なり，予測の誤差について最適化するようにするなど，時系列を扱うことに適した形にカスタマイズしているようである．

![architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120544/dc567d11-1343-7f2c-03e4-cb5fd3110284.png)


TimeGPT の特筆すべきは LLM と同様に Zero-shot でタスクを実行できる点である．すなわち，時系列の予測に必要だった，特徴量を抽出する作業 (特徴量エンジニアリング) を省略することが可能であり，分析プロセスを簡略化できる．これは専門家のほか，ビジネスユーザに対して大きな利点となる．論文中では欠損値の補完と標準化のみを実施し，トレーニングに用いているらしいので，この２点が可能であれば非専門家であっても比較的容易に時系列の予測が可能であると思われる．この程度であれば，一般的なノーコードツールで十分可能である．

下図のゼロショット予測の結果[1]もそれほど悪いものではなく，データの粒度や形状に依存するようであるが，従来手法より優位となる場合があるようである．

![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120544/cc55c885-0e71-75f9-ff08-d14e84af17e7.png)


公式の Document によれば用途はメインの時系列の予測の他，部分的な予測ができるとのことで異常検知にも利用できるようである[2]．

直近のAWSのイベント (AWS re:Invent 2023) で関連動画が投稿されている[3]．このように，注目されつつあり，今後の活用に期待できるモデルであるように感じる．

さて，データ分析といえば ChatGPT に搭載されている，Code Interpreter でもノーコードで時系列の予測ができるはずである．こちらは仕組みとして，GPTが自然言語で命令を受け取り，コードを生成し，サンドボックス内で実行した結果を自然言語に埋め込んで返すと理解している．この場合，複数の処理ステップを踏んでおり，分析の都度コードを生成するため実行のコストが高いはずである．一方でTimeGPTは時系列を直接与えるためこの実行コストが相対的に低いと考えられる．

このようにTimeGPTはゼロショットで効率的に，ノーコードで時系列を活用できる可能性があり，多くの領域での活用が期待できる．

# TimeGPTを始める

## API トークンを取得

:::note warn
**TimeGPTは現在ベータ版であり (2023-12-09)，APIキーを取得するだけでは継続的に利用ができません．（確認したところサブスクリプション契約のページも見当たらない）**
:::

クレジットが１しかないので後述のPythonコードでAPIを呼び出すと，最初の１回以降は下記のエラーを返されます．

```
ApiError: status_code: 429, body: {'data': None, 
'message': 'Too many requests', 
'details': 'You have reached your request limit, ...
```

---

以降は実際にTimeGPTを利用してみる手順を記載する．LLMと同様，大規模な基盤モデルでありパラメータは公開されていないクローズドなモデルなのでAPIからアクセスする．

APIキーを取得するには公式のDocumentページ[2]から上部の Get Token をクリックし任意のアカウントでサインアップする (Google or Github)．画面の指示に従い，開発者ポータル画面に遷移できたら API Keys のメニューから新しいAPIキーを生成します．

![officialdocument.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120544/806a664e-f4ee-3528-4561-c9fe7ebefd2e.png)

## がっつり使うには

APIは上記手順で取得できるが，現在(23-12-09) では割り当てられたクレジットが1しかないため，API に2回以上アクセスすると直ぐに Error 429 を返してくる．これは，TimeGPTが現在ベータでありユーザを絞っているためである．

継続してモデルにアクセスする場合は，公式Webページにアクセスし， **Submit interest** を選択し利用申請をする．Google で ”timegpt” を検索すると前述のAPIトークンを発行する Document がトップに来るのでややこしいが，上記とは別のページなので間違えないようにする．

![submit_interest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120544/dae29fc8-2de6-c9dd-eeba-04154a41f6d9.png)


## Pythonライブラリのインストール

TimeGPTにPythonを用いてAPIアクセスするために必要なライブラリをインストールする．

```bash
python3 -m pip install nixtlats
```

## データを用意

TimeGPT-1 は時間の粒度 (時，日，週，月) で精度が変化する旨が論文に掲載されているため，いろいろな粒度，タイプのデータセットを用意する．

| 名称 | 概要 | URL | サンプリング間隔 |
| --- | --- | --- | --- |
| AirPassengers | 飛行機の乗客数．Rの標準データセット．（1949〜1960年） | https://github.com/vincentarelbundock/Rdatasets/blob/master/csv/datasets/AirPassengers.csv | 年 |
| Nile | ナイル川の年間流量．Rの標準データセット．（1871年〜1970年） | https://github.com/vincentarelbundock/Rdatasets/blob/master/csv/datasets/Nile.csv | 年 |
| 仮装通貨の終値一覧 （GMOコイン） | 仮想通貨の終値．(CoinMarketCap) | https://coin.z.com/jp/corp/information/closing-prices/ | 日 |
| マウナロアの週間大気CO2データ | ハワイ州マウナロア天文台のCO2濃度データ．(4回/時 で測定し，6時間以上の測定ができた場合を記録) | https://www.statsmodels.org/dev/datasets/generated/co2.html | 分 (15分) |

# 動かす

## コードの用意

公式Webページのクイックスタート[5]にあるPythonコードを利用する．下記の数行のコードで予測を実行できる．

```python
# Importing necessary modules.
import pandas as pd  
from nixtlats import TimeGPT  # Importing the TimeGPT class from nixtlats library.

# Initializing the `TimeGPT` class with a token from the environment variable.
timegpt = TimeGPT(token='YOUR-TIMEGPT_TOKEN') #https://dashboard.nixtla.io

# Check if the token provided is valid.
if timegpt.validate_token():
    print("Token validation successful!")  # Token is valid.
else:
    # Raise an exception if token validation fails.
    raise Exception("Token validation failed! Please check go to https://dashboard.nixtla.io/ to get your token.")

# Loading the air passengers dataset from a remote URL as an example
df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/air_passengers.csv')

# Forecasting the next 12 horizons using TimeGPT
timegpt_fcst_df = timegpt.forecast(df=df, h=12, time_col='timestamp', target_col='value')

# Plotting the original data combined with the forecasted data.
pd.concat([df, timegpt_fcst_df]).set_index('timestamp').plot()
```

このコードを利用して，APIのリファレンス[3]を参照しつつ，Jupyter Lab で動作確認をします．

```python
import pandas as pd
import matplotlib.pyplot as plt
from nixtlats import TimeGPT
```

```python
# データ読み込み
df = pd.read_csv("./dataset/AirPassengers.csv")
```

```python
# 標準化
df["value_z"] = (df["value"] - df["value"].mean())/df["value"].std()
```

```python
# 分割
df_train = df.iloc[:-10]
df_test  = df.iloc[-10:]
```

```python
# 時系列の形状を確認
plt.plot(df_train["time"], df_train["value_z"])
plt.plot(df_test["time"], df_test["value_z"])
plt.show()
```

```python
# APIキー読み込み
with open("timegpt_token.txt", 'r') as file:
    token = file.read()

# 初期化しインスタンス化
timegpt = TimeGPT(token=token)

# トークンの有効性を確認 (クレジットが不足すると弾かれます）
if timegpt.validate_token():
    print("Token validation successful!")
else:
    # Raise an exception if token validation fails.
    raise Exception("Token validation failed! Please check go to https://dashboard.nixtla.io/ to get your token.")
```

```python
# 予測をTimeGPTで実行し予測結果をDataFrameで得る　(df=データセット, h=予測するステップ)
df_timegpt_fcst = timegpt.forecast(df=df, h=12, time_col="time", target_col="value_z")
```

## 実行

ベータ利用の申請をしているが，なかなか返答がない（現在2週間ほど経過）ため，後ほどテストをしたいと考えている．アクセスができるようになったら下記を記録する．なお，既に精度評価を共有してくれている記事が見つかったのでこちら[7]を併せて参照させていただければと思う．

- 評価観点
    - actual, Time-GPT プロット
    - mae, mse

# まとめ

今回は，おそらく市場初の時系列に特化した基盤モデルを調査した．

結果として既存の分析手法と比較してもアクセスしやすく，LLMの例に倣ってGUIアプリ化することで誰でも時系列を分析できるようになる可能性があるように感じた．（実行はできていませんが）

今後の発展としては文献[1]でも触れられているが，外部の情報との統合が望まれる．例えば，世の中の出来事に影響される経済の分野の時系列，天候に影響される農業の時系列，分析に知識が必要な生体データなど，別の時系列との結びつけや知識の組み込みがよりTimeGPTの分析能力を向上させるはずである．これらはLLMでいうところのRAGに似たアプローチ，マルチモーダルなモデルの構築による時系列に関する知識の追加 (Few-shotなど) で対応することになるのではないかと感じました．

# 参考

[1] [https://arxiv.org/abs/2310.03589](https://arxiv.org/abs/2310.03589), Access: 2023-12-09.

[2] [https://docs.nixtla.io](https://docs.nixtla.io/), Access: 2023-12-09.

[3] [https://www.youtube.com/watch?v=5pYkT0rTCfE](https://www.youtube.com/watch?v=5pYkT0rTCfE), Access: 2023-12-09.

[4] [https://www.nixtla.io/#tgpt](https://www.nixtla.io/#tgpt), Access: 2023-12-09.

[5] [https://docs.nixtla.io/recipes/quick-start-python-sdk](https://docs.nixtla.io/recipes/quick-start-python-sdk), Access: 2023-12-09.

[6] [https://nixtlaverse.nixtla.io/nixtla/timegpt.html](https://nixtlaverse.nixtla.io/nixtla/timegpt.html), アクセス: 2023-12-09.

[7] [https://qiita.com/xxyc/items/1a0a0b3c85f77dcb45ec](https://qiita.com/xxyc/items/1a0a0b3c85f77dcb45ec), アクセス: 2023-12-09.