ビジネス上のデータを眺めてみれば、時間という概念が紐づいた時系列データであるケースが多いです。
多くの時系列データは、上昇傾向や下降傾向といったトレンドや、夏に上がり冬に下がる、週末に上がり平日に下がるといった一定の周期性を持つケースが多いです。
そのような時系列データを手にしたとき、トレンドや季節性などの成分に分解することで、どのようなデータなのかを把握するところから始めることが多いです。
フリーの分析ツールであるR言語で把握するなら、特別な準備をしなくても、stlという関数を使い、STL分解(Seasonal Decomposition Of Time Series By Loess)を実施することで実現できます。
STL分解(Seasonal Decomposition Of Time Series By Loess)を実施することで、元データをトレンド、季節性、残差に分解することができます。
元データ = トレンド + 季節性 + 残差
- トレンド(Trend): 長期的に変動する要素
- 季節性(Seasonal): 一定の時間で周期的に変動する要素
- 残差(Remainder): 残りの細かく変動する要素
STL分解(Seasonal Decomposition Of Time Series By Loess)は、LOESS平滑化(locally estimated scatterplot smoothing)というノンパラメトリック回帰モデルを利用します。
理論的なお話しはさておき、今回は「(R編) 時系列データをサクッとSTLでトレンド・季節性に分解」というお話しをします。
超簡単です。
サンプルデータ
Box and Jenkins (1976) の有名な「Airline Passengers」(飛行機乗客数)のデータセット(csvファイル)を使って作業を行います。
「Airline Passengers」(飛行機乗客数)のデータセット(csvファイル)は、pandasを使い読み込みます。
CSVファイルは、https://www.salesanalytics.co.jp/591h上にあるものを使います
# データセットの読み込み url <- 'https://www.salesanalytics.co.jp/591h' table <- read.csv(url)
データの中を見てみます。
以下、コード(10レコードだけ表示)です。
head(table,10)
以下、実行結果です。
月別の乗客数のデータであることが分かります。
どのようなデータなのか、その情報を確認してみます。
以下、コードです。
str(table)
以下、実行結果です。
データフレーム型(DataFrame)で、変数は「Month」と「Passengers」の2つです。
データ数(行)は144あり、「Month」の型は因子型(Factor)であり、「Passengers」の型は整数型(int)であることが分かります。
対象データ(Passengers)を時系列型(ts)へ変換する必要があるため、変換します。
以下、コードです。
Passengers<-ts(table$Passengers,frequency=12,start=c(1949,1))
どのように変換されたのか確認してみます。
以下、コードです。
str(Passengers)
以下、実行結果です。
対象データ(Passengers)が時系列型(ts)に変換されていることが分かります。
グラフで確認
読み込んだ「Airline Passengers」(飛行機乗客数)のデータセットをグラフで眺めてみたいと思います。
以下、コードです。
plot(Passengers)
以下、実行結果です。
plot関数だけで十分グラフ化されるので、このままでも問題ないですが、もう少し美しいグラフを手軽に作成するために、autoplot関数を使い簡単にそれなりのグラフを作成したいと思います。
今回はライブラリー「ggfortify」を使います。もし、インストールされていない方は、以下を参考にインストールして頂ければと思います。
# ggfortifyのインストール install.packages('ggfortify', dependencies = TRUE)
インストールされた「ggfortify」を使うとき、ロード(読み込み)する必要があります。
以下、コードです。
# ggfortifyの読み込み library(ggfortify)
では実際、autoplot関数を使い、plot関数よりもちょっとだけ美しいグラフを手軽に作成します。
以下、コードです。
autoplot(Passengers, #グラフ化するデータ ts.colour = 'blue', #折れ線の色 xlab='Month', #ヨコ軸のラベル ylab='Monthly Number of Airline Passengers', #タテ軸のラベル main='Passengers') #グラフタイトル
以下、実行結果です。
トレンドとして上昇傾向であり、季節性もありそうなことが分かります。
STL分解(Seasonal Decomposition Of Time Series By Loess)
STL分解(Seasonal Decomposition Of Time Series By Loess)は非常に簡単です。1行のコードで事足ります。
STL分解(Seasonal Decomposition Of Time Series By Loess)を実施し、元データをトレンド、季節性、残差に分解していきたいと思います。。
元データ = トレンド + 季節性 + 残差
以下、コードです。
# STL分解 stl <- stl(Passengers,s.window="per", robust=TRUE)
どのように分解されたのか、グラフで確認したいと思います。
以下、コードです。
autoplot(stl, #グラフ化するデータ ts.colour = 'blue', #折れ線の色 xlab='Month', #ヨコ軸のラベル ylab='Monthly Number of Airline Passengers', #タテ軸のラベル main='Passengers') #グラフタイトル
以下、実行結果です。
STL分解(Seasonal Decomposition Of Time Series By Loess)した結果を抽出したい、という要望もあることでしょう。実際に取り出してみたいと思います。
以下、コードです。
# STL分解結果のデータ stl_o = rowSums(stl$time.series) #観測データ(STL分解前の元のデータ)=トレンド+季節性+残差 stl_t = stl$time.series[,2] #トレンド(Trend) stl_s = stl$time.series[,1] #季節性(Seasonal) stl_r = stl$time.series[,3] #残差(Remainder)
取り出したデータ(トレンド、季節性、残差)の中身を見てみましょう。
では、トレンド(trend)を見てみます。
以下、コード(10レコードだけ表示)です。
head(stl_t,10)
以下、実行結果です。
グラフ化してみます。
以下、コードです。
autoplot(stl_t, #グラフ化するデータ ts.colour = 'blue', #折れ線の色 xlab='Month', #ヨコ軸のラベル ylab='Monthly Number of Airline Passengers', #タテ軸のラベル main='Passengers') #グラフタイトル
以下、実行結果です。