koji/メガネ男の日誌

日々の学び、活動状況を記録します。仕事のことは少なめ。

時系列解析ライブラリ sktimeとProphetを比較してみた

f:id:kj_man666:20200705192646j:plain

時系列解析に使えるライブラリ、sktimeが公開されていましたので、同じく時系列解析のライブラリ、Prophetと比較してみました。

学習に使ったデータは気象庁の気温のデータです。

なお、ブログのコードはこちらになります。

気象庁のデータも入れています)

なお、気象庁のデータをご自身で取得する場合は、下記のProphetの記事を参照されるといいでしょう。

qiita.com

なお、Prophet のインストールはcondasktime のインストールは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())

f:id:kj_man666:20200705183630p:plain

# グラフ表示
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()

f:id:kj_man666:20200705184158p:plain

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は滑らかな予測となっています。

f:id:kj_man666:20200705190755p:plain

決定係数で精度を評価してみましょう。

最も当てはまりの良い場合、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

pythondatascience.plavox.info