今回の記事では、時系列分析が簡単に実装できるDartsについて紹介します。

Google colabを使用して、簡単にモデルを実装することができますので、ぜひ最後までご覧ください。

今回の内容

・時系列分析とは

・Dartsとは

・Dartsの導入

・データセットを準備する

・データセットの前処理

・モデルの実装例

時系列分析とは

時系列分析とは、時間の経過とともに変化する時系列データを分析することをいいます。

時系列データの具体例として、気温や降水状況などの気象情報、交通機関の乗客の推移、株価のチャートなど身近な場所に多く存在しています。

時系列分析において、データの変動の原因は以下のように分類されます。

1長期的な上昇/下降の傾向性を指す「トレンド」
21年の間で一定期間ごとに周期的に変化する「季節変動」
3複数年にまたがって周期的に変化する「循環変動」
4周期性や規則的な傾向性が見られない「不規則変動」

次系列分析は、日々の株価の変動や将来の市場規模の変化、売上実績の予想などに多くの場面で役立てられています。

Dartsとは

Dartsは時系列分析の実装を簡単に行えるPython ライブラリです。

ARIMAをはじめとした古典的なモデルからディープラーニングによる最新手法までさまざまなモデルに対応しており、学習から推論までを簡単に実装することができます。

単変量と多変量の両方の時系列とモデルをサポートしています。

詳細は以下のリンクからご確認ください。

Dartsの導入

ここからはGoogle colabを使用して、次系列分析を実装していきます。

今回紹介するコードは以下のボタンからコピーして使用していただくことも可能です。

Open In Colab

Google colabによる導入

まずはGoogleドライブをマウントして、作業フォルダを作成します。

from google.colab import drive
drive.mount('/content/drive')
%cd ./drive/MyDrive

公式からクローンします。

!git clone https://github.com/unit8co/darts
%cd darts

必要なライブラリをインストールします。

!pip install darts

インストールが終わったら、再起動します。

以上で導入が終わりました。

※pipのみで使用することができますが、サンプル用のCSVデータセットを使用するため、公式からクローンしています。

データセットを準備する

時系列データを読み込む方法は以下の通りです。

darts.datasetsからデータを読み込む

Dartsのデータセットから直接読み込むことができます。

まずは飛行機の乗客の推移を表すデータを読み込みます。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from darts import TimeSeries
from darts.datasets import AirPassengersDataset

# dartsから直接データセットをダウンロードする
series = AirPassengersDataset().load()
series.plot()

実行すると以下のようなグラフが表示されます。

CSVファイルからデータを読み込む

次にCSVファイルからデータセットを読み込む方法を紹介します。

先ほど読み込んだDartsのデータセットである、飛行機の乗客の推移を表す「AirPassengers.csv」というファイルを読み込み、内容を表示してみます。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from darts import TimeSeries

# CSVファイルからデータセットをダウンロードする
df = pd.read_csv("datasets/AirPassengers.csv", delimiter=",")
df

実行すると、以下のように表示されます。

indexMonth#Passengers
01949-01112
11949-02118
21949-03132
31949-04129
41949-05121
1401960-09508
1411960-10461
1421960-11390
1431960-12432

1ヶ月ごとの乗客数のデータセットであることがわかりました。

同様にグラフで表してみます。

series = TimeSeries.from_dataframe(df, "Month", "#Passengers")
series.plot()

先ほど同じグラフになっていることがわかります。

時系列データから表形式データへ変換

ここまで表形式データから時系列データに変換する方法を紹介しましたが、逆にもとに戻すこともできます。

TimeSeries.pd_dataframe()メソッドにより、時系列データから表形式データへ変換することができます。

TimeSeries.pd_dataframe(series)

データセットの前処理

ここからは前処理の方法を紹介します。

比率でデータを分割

時系列データを分割することができます。

以下の例では、全体を0.75の位置で分割します。

series1, series2 = series.split_before(0.75)
series1.plot()
series2.plot()

実行すると、以下のようなグラフが出力されます。

グラフが0.75の位置で分割され、前半が黒色、後半が青色になっていることがわかります。

分割したデータを表示することもできます。

TimeSeries.pd_dataframe(series1).tail()

実行すると、分割したデータを表形式で出力することができます。

Month#Passengers
1957-07-01 00:00:00465.0
1957-08-01 00:00:00467.0
1957-09-01 00:00:00404.0
1957-10-01 00:00:00347.0
1957-11-01 00:00:00305.0

分割位置を指定してデータを分割

次に分割位置を指定してデータを分割する方法を紹介します。

以下の例では、全体を後ろから36番目の位置で分割します。

series1, series2 = series[:-36], series[-36:]
series1.plot()
series2.plot()

実行すると、以下のようなグラフが出力されます。

グラフが全体を後ろから36番目の位置で分割され、前半が黒色、後半が青色になっていることがわかります。

学習データと検証データに分割

学習データと検証データに分割します。

以下の例では、全体を1958年1月で分割します。

train, val = series.split_before(pd.Timestamp("19580101"))
train.plot(label="training")
val.plot(label="validation")

実行すると、以下のようなグラフが出力されます。

季節変動性を確認する

データの特徴を掴むため、季節変動性の確認を行います。

for m in range(2, 25):
    is_seasonal, period = check_seasonality(train, m=m, alpha=0.05)
    if is_seasonal:
        print("There is seasonality of order {}.".format(period))

実行すると、以下のように表示されます。

There is seasonality of order 12.

12次の季節変動性があることがわかりました。

自己相関関数 (ACF) のラグも表示することができます。

from darts.utils.statistics import plot_acf, check_seasonality
plot_acf(train,alpha=0.05)

モデルの実装例

ここからは指数平滑法予測を例に、モデルの実装例を紹介していきます。

先ほど分割した学習データと検証データを用いて、予測を行います。

from darts.models import ExponentialSmoothing
from darts.metrics import mape

def eval_model(model):
    model.fit(train)
    forecast = model.predict(len(val))
    print("model {} obtains MAPE: {:.2f}%".format(model, mape(val, forecast)))
    series.plot()
    forecast.plot(label='forecast')
    return TimeSeries.pd_dataframe(forecast)

eval_model(ExponentialSmoothing())

実行すると以下のような結果とグラフおよび表が出力されます。

model ExponentialSmoothing(
trend=ModelMode.ADDITIVE, 
damped=False, 
seasonal=SeasonalityMode.ADDITIVE, 
seasonal_periods=12 obtains MAPE: 5.11%

グラフ

黒色が元のデータ、青色が予測のデータになっています。

それぞれの予測の値を確認することができます。

Month#Passengers
1958-11-01 00:00:00331.07829886018783
1958-02-01 00:00:00345.8201686361798
1958-01-01 00:00:00357.3323525767953
1959-11-01 00:00:00360.88592543149036
1958-10-01 00:00:00370.2797224292205
1959-02-01 00:00:00375.62779520748234
1958-12-01 00:00:00376.95827329776637
1959-01-01 00:00:00387.1399791480979
1958-04-01 00:00:00390.1919947229418
1960-11-01 00:00:00390.6935520027929

MAPE

MAPE(Mean Absolute Percentage Error)は平均絶対パーセント誤差のことです。

各データに対して「予測値と正解値との差を、正解値で割った値(=パーセント誤差)」の絶対値を計算し、その総和をデータ数で割った値(=平均値)を出力します。

時系列予測の評価関数として用いられます。

上記の結果では、MAPEは5.11%でした。

まとめ

最後までご覧いただきありがとうございました。

今回の記事では時系列分析が簡単に実装できるDartsについて紹介しました。