Rについて
をベースに学んでいく。
今回は時系列分析(PP.269-295)を扱う*1。
前回
21. 時系列分析
時間と共に変動する現象に対して、時間の順序で測定・観測した結果を記録したデータを時系列データという。時系列データが伴う変動の振る舞いを統計的に分析するのが時系列データ分析の主要な目的で、そのような分野を時系列解析という。
21.1 時系列分析の基本概念
時系列データは通常、ある一定の時間間隔で測定・観測したものである。観測・測定値に関する観測回数の時系列データは、測定時点を添字として
のように記述される。
には時系列データを専門に扱うデータ型が存在する。
################## ### 時系列解析 ### ################## library("ggplot2") library("ggfortify") # データの読込 data(lh) data(UKgas) class(lh) # データ型 print(lh) # データ内容 print(UKgas) # 開始時点と終了時点 start(UKgas) end(UKgas) # 特定期間を抜き出す window(UKgas, c(1975,2),c(1979,3)) # 1975年2Qから1979年3Qまで ## 時系列データの図示 g_ts <- autoplot(UKgas) g_ts <- g_ts + theme_classic() g_ts <- g_ts + labs(x="年(四半期)", y = "天然ガス消費量[百万サーム]") g_ts <- g_ts + theme(plot.title = element_text(hjust = 0.5, size = 14), axis.title = element_text(size = 14), axis.text = element_text(size = 14), legend.title = element_text(size = 14), legend.text = element_text(size = 14), legend.position = "none") g_ts <- g_ts + scale_y_continuous(breaks = seq(0,1200,100),labels = seq(0,1200,100)) g_ts <- g_ts + geom_hline(yintercept = 0, linetype = 1) g_ts <- g_ts + geom_hline(yintercept = seq(0,1200,100), linetype = 3) plot(g_ts)
21.1.1 データオブジェクトの作成
### tsオブジェクトの作成 tmp <- ts(1:120,c(1995,6), frequency = 12) class(tmp) print(tmp)
21.1.2 ラグ処理
## ラグ処理 library("datasets") ldeaths lag(ldeaths,k = 1) plot(diff(UKgas,lag = 4)) # 以下は等価 diff(UKgas, lag = 2) UKgas - lag(UKgas, k = -2)
21.2 自己共分散と自己相関
時系列に対して各種統計量を定義できる。標本平均、自己共分散関数および自己相関関数はそれぞれ
で定義される。
パッケージには自己相関および自己共分散を計算する関数がある。
### 自己共分散と自己相関 library("stats") ls_acf <- acf(UKgas) df_acf <- data.frame(lag = ls_acf$lag, acf = ls_acf$acf) # g1 <- ggplot(df_acf,aes(x = lag, y = acf),type = "correlation") g1 <- g1 + geom_bar(stat = "identity") g1 <- g1 + theme_classic() g1 <- g1 + labs(x="ラグ", y = "標本自己相関関数") g1 <- g1 + theme(plot.title = element_text(hjust = 0.5, size = 14), axis.title = element_text(size = 14), axis.text = element_text(size = 14), legend.title = element_text(size = 14), legend.text = element_text(size = 14), legend.position = "none") g1 <- g1 + scale_y_continuous(breaks = seq(0,1,0.25),labels = seq(0,1,0.25)) g1 <- g1 + geom_hline(yintercept = 0, linetype = 1) g1 <- g1 + geom_hline(yintercept = seq(0,1,0.25), linetype = 3) plot(g1)
21.3 スペクトル分析
時系列データは、トレンド、周期成分およびノイズなど、複数の成分が混合しているものと考えられる。時系列データに隠された周期性を解析する方法としてスペクトル解析がある。
時系列における自己共分散の変換が可能であるとき、上で定義される関数
をパワースペクトル密度関数と呼ぶ。標本の自己共分散を用いて定義したもの
をピリオドグラムという。ただし周波数はである。
library("ggplot2") data(UKgas) vc_frq <- spec.pgram(UKgas)$freq vc_spc <- spec.pgram(UKgas)$spec df_spc <- data.frame(frq = vc_frq, var = "spectrum", spc = log10(vc_spc)) g2 <- ggplot(df_spc,aes(x = frq, y = spc, color = var, fill = var)) g2 <- g2 + geom_line() + geom_point() g2 <- g2 + theme_classic() g2 <- g2 + labs(x = "周波数", y = "スペクトル") g2 <- g2 + theme(plot.title = element_text(hjust = 0.5, size = 14), axis.title = element_text(size = 14), axis.text = element_text(size = 14), legend.title = element_text(size = 14), legend.text = element_text(size = 14), legend.position = "none") g2 <- g2 + scale_x_continuous(breaks = seq(0,vc_frq[length(vc_frq)],0.5), labels = seq(0,vc_frq[length(vc_frq)],0.5)) g2 <- g2 + scale_y_continuous(breaks = seq(floor(min(log10(vc_spc))),ceiling(max(log10(vc_spc))),1), labels = 10^seq(floor(min(log10(vc_spc))),ceiling(max(log10(vc_spc))),1)) g2 <- g2 + geom_hline(yintercept = 0, linetype = 1) g2 <- g2 + geom_hline(yintercept = seq(floor(min(log10(vc_spc))),ceiling(max(log10(vc_spc))),1), linetype = 3) plot(g2)
21.4 ランダムウォークと単位根
時系列解析も、回帰分析と同じく、収集したデータからモデルを構築し、将来の予測やシステム制御等を行うのを目的とする。ある時系列データが、
で表せ、更に単位根、すなわとのとき、このはランダムウォークであるという。ランダムウォークは非定常であるから、時系列データを分析するには、まずそのデータがランダムウォークであるか否かを調べることが重要である。
時系列データが単位根なのかを検定することを単位根検定という。すなわち単位根検定は
- 帰無仮説:単位根が存在する(すなわち)
- 対立仮説:単位根が存在しない(すなわち)
を検定する仮説検定である。これを具体的に解くための手法はいくつか存在する。
パッケージには-検定が実装されている。
################## ### 単位根検定 ### ################## library("tseries") df_UKgas_log_diff <- log(UKgas) - log(lag(UKgas,k = 4)) # 単位根か否か PP.test(df_UKgas_log_diff) # 帰無仮説は棄却できない=単位根とは言えない adf.test(df_UKgas_log_diff) # 帰無仮説は棄却できない=単位根とは言えない
21.5 ARモデル
時点から時点までの各データの関係式
を自己回帰モデル(モデル)という。
ではの()関数を用いればよい。
# ARモデル ls_ar_UKgas <- ar(df_UKgas_log_diff) # 特に指定しないとAICを用いて次数を自動的に決定
21.5.1 モデルの診断
モデルの診断として、残差分析には、-検定などにより各残差間の独立性を検定できる。また-検定により、正規性の有無も検定できる。
Box.test(x = ls_ar_UKgas$resid,type = "Ljung") # Ljung-Box検定。デフォルトではBox-Pierce検定。帰無仮説を棄却できそう。 jarque.bera.test(x = ls_ar_UKgas$resid[!is.na(ls_ar_UKgas$resid)]) # Jarque-Bera検定。正規性も否定はできなさそう
21.5.2 予測
predict(ls_ar_UKgas,n.ahead = 12)
21.6 ARMA/ARIMAモデル
モデルに誤差の移動平均を加えたモデル
をモデルという。
の階差分のモデルを自己回帰和分移動平均()モデルという。
################### ### ARIMAモデル ### ################### ls_arima <- arima(x = log(UKgas),order = c(4,4,1)) tsdiag(ls_arima,gof.lag = 12) # tsdiag:残差分析のための関数
21.7 その他のモデル
21.7.1 ARFIMAモデル
差分の階数を実数に拡張したモデルを自己回帰実数和分移動平均()モデルという。パッケージを用いると、適切な差分階数を推定した上で、モデルの係数を決めて同モデルを構築できる。
#################### ### ARFIMAモデル ### #################### library("fracdiff") data(AirPassengers) d_estimate <- fdGPH(AirPassengers)$d # 差分パラメータの推定 ls_arfima <- fracdiff(x = AirPassengers, nar = 3, dtol = d_estimate, nma = 1) # モデルパラメータの推定
21.7.2 GARCHモデル
時系列データが、条件付き平均および条件付き分散を持つ正規分布に従うとし、また
と書けるとするモデルをモデルという。これを更に拡張した
をモデルという。これを更に拡張したモデルも他に提案されている。
モデルの構築にはの()関数などを用いればよい。
21.8 成分の分解
時系列データのうち周期性を持つものについて、
といった形で分解することで周期成分を抽出するモデルを考えることもできる。
パッケージの()関数でこのモデルを考えることができる。
###################### ### 周期成分の抽出 ### ##################### df_UKgas_stl <- stl(UKgas,s.window = "per") plot(df_UKgas_stl)
21.9 多変量時系列解析
多変量時系列データに関するモデルを構築することもでき、その中でもモデルが最もよく用いられる。
################# ### VARモデル ### ################# library("tseries") data("USeconomic") USe_d <- diff(USeconomic[,1:2]) ts.plot(USe_d) acf(USe_d) USe_d_var <- ar(x = USe_d, order.max = 2, aic = F) str(USe_d_var) summary(USe_d_var) plot(USe_d_var$resid)
21.10 カオス時系列
不規則に変動する時系列データを非線形的に扱う手法として、カオス理論に基づく方法がある。そのためにはパッケージを用いる。
補足 スペック情報
エディション | Windows 10 Home |
バージョン | 20H2 |
プロセッサ | Intel(R) Core(TM) i5-1035G4 CPU @ 1.10GHz 1.50 GHz |
実装 RAM | 8.00 GB |
システムの種類 | 64 ビット オペレーティング システム、x64 ベース プロセッサ |
R バージョン | 4.1.3 (March, 2022) |
RStudio バージョン | 2022.02.2 Build 485 |
*1:時系列解析は別途しっかりと扱うつもりであるため、ここでは簡単に扱う。