時系列解析ライブラリ sktimeとProphetを比較してみた
時系列解析に使えるライブラリ、sktimeが公開されていましたので、同じく時系列解析のライブラリ、Prophetと比較してみました。
学習に使ったデータは気象庁の気温のデータです。
なお、ブログのコードはこちらになります。
(気象庁のデータも入れています)
なお、気象庁のデータをご自身で取得する場合は、下記のProphetの記事を参照されるといいでしょう。
なお、Prophet のインストールはconda、sktime のインストールはpipを使用していますが、pipとcondaを混在させるのはよくないようですので再現する際は自己責任でお願いいたします。
内容を見てみましょう。
# ライブラリ import matplotlib.pyplot as plt import numpy as np import pandas as pd import os import datetime from IPython.display import display # 時系列データの分割 from sktime.forecasting.model_selection import temporal_train_test_split # sktime ナイーブベイズ from sktime.forecasting.naive import NaiveForecaster # Prophet from fbprophet import Prophet # 決定係数 from sklearn.metrics import r2_score %matplotlib inline
Prophetで読み込むデータは、日付データのカラムを ds 、学習データのカラム y と指定する必要があるようですので、指定します。
# カレントディレクトリをpathに指定 path = os.getcwd() # データの読込 df = pd.read_csv(path + "\data.csv", encoding="shift-jis", usecols=[0,1], names=["ds", "y"], header=2) df = df.drop(index=0, axis=0) df["ds"] = pd.to_datetime(df["ds"]) display(df.head()) display(df.tail())
# グラフ表示 fig = plt.figure(figsize=(20, 8)) plt.title("Tokyo tempreture 1990-2019") plt.xlabel("time") plt.ylabel("tempreture") plt.plot(df["ds"], df["y"], label="temp") plt.legend() plt.show()
sktimeのライブラリ、temporal_train_test_split()を使って、テストデータの2019/1/1~2019/12/31 1年分のデータとそれ以外の訓練データに分割します。
ホールドアウト法の train_test_split() と違い、ランダム配分は行わないので、時系列データを分割するときは便利ですね!
y_train, y_test = temporal_train_test_split(df, test_size=365)
Prophet の予測データの作成
model_pro = Prophet(weekly_seasonality=True, yearly_seasonality=True, daily_seasonality=True) # 学習 model_pro.fit(y_train) # 予測用の365日のDataFrameの作成 fyear = model_pro.make_future_dataframe(periods=365)
sktime(ナイーブベイズ)の予測データの作成
fh = np.arange(len(y_test))+1 # モデルの作成 model_sk = NaiveForecaster(strategy="seasonal_last", sp=365) # 学習 model_sk.fit(y_train["y"]) # 予測データの作成 forecast_sk = model_sk.predict(fh)
これでProphetとsktimeの予測データを作成できました。
グラフに表示してみましょう。
fig = plt.figure(figsize=(24, 8)) plt.plot(y_train["ds"][-731:-1], y_train["y"][-731:-1], label="y_train") plt.plot(y_test["ds"], y_test["y"], label="y_test") plt.plot(y_test["ds"], forecast_sk, label="sktime") plt.plot(y_test["ds"], forecast_pro["yhat"][-366:-1], label="prophet") plt.title("Tokyo tempreture 1990-2019") plt.xlabel("time") plt.ylabel("tempreture") plt.legend() plt.show()
実データ y_test と、予測データ sktime、prophet を見比べてみましょう。
sktimeは、日々のジグザグした変動をよく表現しています。
一方、prophetは滑らかな予測となっています。
決定係数で精度を評価してみましょう。
最も当てはまりの良い場合、1.0 となるそうです。
print("Prophet 決定係数:{}".format(r2_score(y_test["y"], forecast_pro["yhat"][-366:-1]))) print("sktime 決定係数:{}".format(r2_score(y_test["y"], forecast_sk)))
Prophet の決定係数:0.9015399553586755
sktime の決定係数:0.7408533090595817
Prophet は 日々の変動を反映していませんが、決定係数はsktimeよりも大きく精度が高いようです。
今回はProphetの方に軍配が上がりましたが、パラメーターを修整すると結果も変わりそうですね。
以上になります、最後までお読みいただきありがとうございました。
【参考サイト】 【sktime の GitHub】 この中のexamples > 01_forecasting.ipynb を参考にさせていただいております。 github.com