Pythonで時系列のデータを
分析してみよう。
2018年9月17日
@kobanyn
PyCon JP 2018
Tatsuya Kobayashi
自己紹介
● 名前:@kobanyn(小林達也)
● 所属:株式会社日本システム技研
● 仕事:Djangoのお仕事をしています
今年もスポンサーしています
IoTのコミュニティ活動しています
株式会社日本システム技研(JSL)
● Python/Django を使用したWebアプリケー
ションの受託開発及び、プロダクト開発
● コミュニティスペース
「GEEKLAB.NAGANO」の運営
● 関東圏のお客様を中心にリモートワークで
お仕事をやらせて頂いている
● 長野で最もPythonitaを抱えている!!
● なにかお仕事のご依頼、お問い合わせあれ
ば是非!!
今日のゴール
● 時系列データ分析の概要をつかむ
● Jupyter Notebookの概要をつかむ
● 統計モデルをつかってなんとなく分かった感じになる
● 簡単に予測ができるようになって分かった気になる
今日の話について
● 向いてる人
○ 時系列データ分析に興味はあるが、経験や知識はない
○ IoTでデータ収集をしたが、分析はしたことがない
● 向いていない人
○ ガチなデータ分析を業務で使いこなしている
他の部屋にGo!!
今日お話すること
1. Jupyter Notebookって何?
2. 時系列データ分析って何?
3. 統計モデルをつかって予測してみる
a. 季節調整モデル
b. 自己相関と偏自己相関
c. SARIMA
Jupyter Notebookとは?
Jupyter Notebookとは?
● ウェブブラウザで動作します
● 対話型でPythonなどプログラムを実行することができる
多機能なエディター
● マークダウン形式でメモを記述したり、グラフを表示し
たりしながら作成します
● 全体を表現力のあるドキュメントとしてファイル保存で
きます
データ解析の環境導入に。
● ツールやライブラリを手元のパソコンで動かすには、い
くつかの方法がありますが、Anacondaでの導入をお勧め
します
● データ解析環境を導入するための無償のディストリビュ
ーションです
● 必要なパッケージが一括でインストールできる
時系列データ分析とは?
時系列データ分析とは?
● その名の通り、時系列データを解析する手法です
● 過去のデータを統計的に解析することで、変化の規則性
など未来予想の情報を得ることが出来ます
時系列データ分析の
練習をしよう
JupyterでPandasを使って見よう
飛行機乗客数のデータを使ってPandasで読み込んでみよう
In [ 1 ]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 15, 6
Pandasをインポートします。
numpyをインポートします。
matplotlibをインポートします。
マジックコマンドでインラインを指定
matplotlibのデフォルト設定を変更
グラフのサイズを変更(横,縦)
JupyterでPandasを使って見よう
飛行機乗客数のデータを使ってPandasで読み込んでみよう
In [ 2 ]:
dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m')
data = pd.read_csv('AirPassengers.csv',
index_col='Month',
date_parser=dateparse,
dtype='float')
data.head()
ファイル名を指定
先頭の5行を表示する
デフォルトで先頭の5行を表示
CSVの見出しを指定
datatype型を指定
データ型を指定しましょう
JupyterでPandasを使って見よう
飛行機乗客数のデータを使ってPandasで読み込んでみよう
Out [ 2 ]:
data.head()で
DataFrameの先頭5行目を表示します
Month #Passengers
0 1949-01-01 112.0
1 1949-02-01 118.0
2 1949-03-01 132.0
3 1949-04-01 129.0
4 1949-05-01 121.0
JupyterでPandasを使って見よう
飛行機乗客数のデータを使ってPandasで読み込んでみよう
Out [ 2 ]:
data.tail()で
DataFrameの末尾の5行目を表示します
Month #Passengers
139 1960-08-01 606.0
140 1960-09-01 508.0
141 1960-10-01 461.0
142 1960-11-01 390.0
143 1960-12-01 432.0
1949年1月から1960年12月までの
144件のデータがあります。
グラフで表示してみよう
グラフで表示してみよう
In [ 3 ]: data.plot()
グラフで表示してみよう
飛行機乗客数のデータを使ってPandasで読み込んでみよう
Out [ 3 ]: <matplotlib.axes._subplots.AxesSubplot at 0x1c1500ed30>
右肩上がりに増えているような傾向を
トレンドといいます
周期的に繰り返す変動は季節性と呼びま
す
トレンドと季節性を除いたその他変動成
分を残差とよびます
季節調整モデルを
表示しよう
季節調整モデルを表示しよう
飛行機乗客数のデータを、トレンド、季節性、残差にそれぞれ分解しよう
In [ 4 ]:
import statsmodels.api as sm
res = sm.tsa.seasonal_decompose(data)
original = data
trend = res.trend
seasonal = res.seasonal
residual = res.resid
plt.figure(figsize=(8, 8))
version 0.8.0以上
季節調整モデルを作成
オリジナルデータ
トレンドデータ
季節性データ
残差データ
グラフ描画枠作成、サイズ指定
季節調整モデルを表示しよう
オリジナル、トレンド、季節性、残差をそれぞれ表示しよう
In [ 4 ]:
# オリジナルデータのプロット
plt.subplot(411)
plt.plot(original)
plt.ylabel('Original')
# trend データのプロット トレンド
plt.subplot(412)
plt.plot(trend)
plt.ylabel('Trend')
# seasonalデータ のプロット 季節性
plt.subplot(413)
plt.plot(seasonal)
plt.ylabel('Seasonality')
# residual データのプロット 残差
plt.subplot(414)
plt.plot(residual)
plt.ylabel('Residuals')
plt.tight_layout() # グラフの間隔を自動調整
季節調整モデルを表示しよう
オリジナルデータ
トレンドデータ
季節性データ
残差データ
季節調整モデルを表示しよう
トレンド、季節性、残差に分解されたか確かめよう
In [ 5 ]:
sum_three_data = trend + seasonal + residual # トレンド + 季節性 + 残差
plt.figure(figsize=(8, 4))
plt.plot(original, label='original')
plt.plot(sum_three_data, label='trend +season +resid', linestyle='--')
plt.legend(loc='best') 凡例表示を設定
観測データ=トレンド成分 + 季節性 + 残差
時系列データを使うときに
抑えておきたい
自己相関とは?
自己相関とは
● 自己相関(ACF:Autocorrelation Function)
● 過去の値が現在のデータにどれくらい影響しているか?
その関係性を調べます
● ズラしたデータのステップ数をラグ(lag)と呼ぶ
● StatsModelsのtsa.stattools.acf()で求めます。第一引数は
データ、オプション引数nlagsでラグ数を指定します(デ
フォルト40)
偏自己相関とは?
偏自己相関とは
● 偏自己相関(PACF:Pertial Autocorrelation Function)
● 偏自己相関は自己相関係数から、時間によって受ける影
響を除去した自己相関
● 今日と二日前の関係には間接的に一日前の影響が含まれ
ます。偏自己相関を使うと、一日前の影響を除いて今日
と二日前だけの関係を調べられます
● StatsModelsのtsa.stattools.pacf()で求めます。
自己相関(ACF)と偏自己相関(PACF)
● 自己相関係数
値の範囲は-1~1
正負の関係や絶対値が1に近いほど相関が強い
● ラグと自己相関でプロットしたグラフを
『コレログラム』といいます
自己相関(ACF)と偏自己相関(PACF)
自己相関と偏自己相関のデータを作成しグラフにしよう
In [ 6 ]:
fig = plt.figure(figsize=(8, 8))
ax1 = fig.add_subplot(211)
sm.graphics.tsa.plot_acf(data, lags=40, ax=ax1)
ax2 = fig.add_subplot(212)
sm.graphics.tsa.plot_pacf(data, lags=40, ax=ax2)
plt.tight_layout()
自己相関(ACF)のグラフ
偏自己相関(PACF)
グラフ間のスキマ調整を行う
自己相関(ACF)と偏自己相関(PACF)
In [ 6 ]:
一日前の値が今日にどれくらい影響して
いるかが分かる
ズラしたデータのステップ数を
ラグ(lag)と呼ぶ
今日と二日前の関係には間接的に一日前
の影響が含まれます
偏自己相関を使うと、一日前の影響を除
いて今日と二日前だけの関係を調べられ
ます
自己相関(ACF)と偏自己相関(PACF)
In [ 6 ]:
自己相関係は、コサインカーブが減衰して
いくような規則正しい形になっています
データが「24ずれたところで自己相関が
極端に高くなり、
「12」、「36」で自己相関が極端に低く
なっています
したがって、このデータは「24」の周期
をもっており、似たような形を繰り返して
いることが推測できます
水色が95%の信頼区間になります
SARIMAモデルを使ってみよ
う
SARIMAモデルを使ってみよう
● SARIMAはSeasonal AutoRegressive Integrated Moving
Average(季節自己回帰和分移動平均)の略です
● S(季節)、AR(自己回帰)、I(和分)とMA(移動平
均)が合わさった形
● SARIMAモデルは、一般的にSARIMA(p, d, q)(P, D, Q)[s]
と表記されます
SARIMA(p, d, q)(P, D, Q)[s]
● パラメータp、d、qは
ARIMAに適用する自己回帰、差分、移動平均の次数
● P、D、Qは、季節調整に適用する次数
● 最後 s は季節調整に適用する周期を指定します
SARIMA(p, d, q)(P, D, Q)[s]
テストデータ1年を除いてモデル作成しよう
In [ 7 ]:
sarimax_train = sm.tsa.SARIMAX(passengers_train2,
order=(3, 1, 3),
seasonal_order=(0, 1, 1, 12),
enforce_stationarity = False,
enforce_invertibility = False
).fit()
自己回帰、差分、移動平均の次数
季節調整に適用する次数、最後周期
和分過程に自己回帰モデルを適用する
移動平均モデルの反転可能条件を維持し
ない
作ったモデルで最後の1年
の値を予測をしてみよう。
予測してみよう]
飛行機乗客数のデータ1年を除いてモデル作成しよう
In [ 8 ]:
sarimax_train2_pred = sarimax_train.predict('1959-12', '1960-12')
plt.plot(data, c="r", label="actual")
plt.plot(sarimax_train2_pred, c="b", label="model-pred", alpha=0.7) # 透過率70%
plt.legend(loc='best') 凡例を自動で適切に表示
予測データ作成
予測してみよう
予測してみよう
予測(赤線)と実践(青線)がほぼ同
じになっていることがわかります。
予測した1年を拡大して
みよう
予測した1年を拡大してみよう
飛行機乗客数のデータ1年を除いてモデル作成しよう
In [ 9 ]:
predict_dy = sarimax_train.get_prediction(start ='1959-12', end='1960-12')
predict_dy_ci = predict_dy.conf_int(alpha=0.05)
plt.plot(passengers_test2, label="Actual")
plt.plot(predict_dy.predicted_mean, c="b", label="model-pred", alpha=0.7)
plt.fill_between(predict_dy_ci.index, predict_dy_ci.iloc[:, 0], predict_dy_ci.iloc[:, 1],
color='g', alpha=0.2)
plt.legend(loc='upper left')
信頼区間のデータを取得
指定範囲を
塗りつぶす
凡例を左上に表示
拡大したグラフはこちら
SARIMAモデルの最適
なパラメータを探す
SARIMAモデルの最適なパラメータは
自動でARMAのパラメータを抽出する関数があります
P = 3、q = 2となっています。
表は、縦 P、横がqを表します
SARIMAモデルの最適なパラメータを探す
SARIMAモデルの最適なパラメータは
aicが最小となる値
SARIMA(p, d, q)(P, D, Q)[s]
テストデータ1年を除いてモデル作成しよう
In [ 7 ]:
sarimax_train = sm.tsa.SARIMAX(passengers_train2,
order=(3, 1, 3),
seasonal_order=(0, 1, 1, 12),
enforce_stationarity = False,
enforce_invertibility = False
).fit()
自己回帰、差分、移動平均の次数
季節調整に適用する次数、最後周期
和分過程に自己回帰モデルを適用する
移動平均モデルの反転可能条件を維持し
ない
環境
● python 3.6.6
● matplotlib 2.2.3
● statsmodels 0.8.0
● pandas 0.23.4
まとめ
● 選ばれた結果は過剰に信用するのではなく、ある程度疑
ってかかりながら解析を進めることが重要です
● 他のデータ使ったモデル作成にも挑戦してみよう
● 最初は知見のあるサイトを見て、真似して同じ結果にな
るかを検証しましょう
● 異常検知を予兆できるように知見を得たい(外れ値から
検出、異常状態検出、変化点検出)
おわりに
● AirPassengers.csvは?
https://datamarket.com/data/set/22u3/international-airline-passengers-
monthly-totals-in-thousands-jan-49-dec-60#!ds=22u3&display=line
● Githubにスライドで使用したJupyter Notebookを保存して
います
https://github.com/Kobayashi2334/time_series
ご静聴ありがとうございました

Pythonで時系列のデータを分析してみよう