ホリケン's diary

趣味はでぃーぷらーにんぐ

【R】仮想通貨の時系列解析(1)

導入


 Bitcoinの価格データ(2011/8/27-2018/2/22)を元に解析をした。仮想通貨を含む証券データは様々な要因から変動しているが、価格データ単体からどれほど情報を抜き取れるか興味があったのでこれを題材とした。
 仮想通貨の時系列解析(1)~でデータの記述を、(2)で状態空間モデルでのモデリングをする。時系列解析については過去の記事(時系列解析をゆるっと解説(1),(2))を参考にしてもらいたい。


データの可視化


以下の4つの指標に基づき可視化を行い、データの特徴を調べた。

  • 時系列プロット
  • ヒストグラム
  • 自己相関係数
  • スペクトル

oldpar = par(no.readonly=TRUE)
par(mfrow=c(2,2)); par(oma=c(0,0,0,0)); par(mar=c(4,4,2,1))

# (a) Bitcoin価格の時系列変化
ts.plot(data, main="(a)")

# (b) ヒストグラム
hist(data, main="(b)", xlab="price")

# (c) 自己相関係数
acf(data,  main="(c)", type="correlation")

# (d) スペクトル
plot.spectrum = function(dat, lab="", main="",
                         y_max=1, tick=c(8,4), unit=1){
  # データの周波数領域変換
  dat_FFT = abs(fft(as.vector(dat)))
  
  # グラフ横軸(周波数)の表示に関する準備
  data_len = length(dat_FFT)
  freq_tick = c(data_len, tick, 2)
  
  # 周波数領域でのデータをプロット
  plot(dat_FFT/max(dat_FFT), type="l", main=main,
       ylab="sqectrum", ylim=c(0, y_max),
       xlab="f", xlim=c(1,data_len/2), xaxt="n")
  axis(side=1, at=data_len/freq_tick * unit + 1,
       labels = sprintf("1/%d", freq_tick), cex.axis=0.7)
}
plot.spectrum(data, main="(d)")

par(oldpar)


結果

f:id:knto-h:20180725172218p:plain

左上の図が通常の時系列プロットである。ビットコイン、初期のだいぶ長い間は注目がされず低価格だったが一度話題に上がると爆発的に価格が跳ね上がったのがわかる。これらの結果を分析をしようというのだが、、、データが2012年からのビットコインの価格変化ということもあり明らかに非定常データというのが伺えるため傾向が掴みにくい。周期性がないことは右下のスペクトルの図から伺える。0~800, 800~1100, 1100~1800, 1800~2800, 2800~とトレンドが変化していそう。トレンド変化を含んだデータでありその変化点を指定することなくモデリングを行いたいため、今回は状態空間モデルをモデリングの手法として利用することにした。また、元データでは指数的な変化がみてとれるので指数成分を取り除く変数変換をほどこすことにする。


対数変換による変数変換

f:id:knto-h:20180725175808p:plain

ほぼ線形な増加志向のグラフとなった。依然として周期性はみえない。変数変換をかましたデータは元データに比べてだいぶ様子が変わったのがわかる。


Box-Cox変換による変数変換

Box-Cox変換とは以下の式で定義される変数変換手法

library(car)
p1 = powerTransform(data)
data = bcPower(data, p1$lambda)
{\displaystyle 
\begin{eqnarray}
z_n =
  \left\{
    \begin{array}{l}
     \lambda^{-1}(y_n^\lambda - 1) & \lambda \neq0 \\
     \log y_n & \lambda=0
    \end{array}
  \right.
\end{eqnarray}
}

 \lambda=0の時は対数、 \lambda=-1の時は逆数、 \lambda=0.5の時は平方根をとる変換となる。 RではcarパッケージのpowerTransform関数によって最適な \lambdaを推定してくれる("最適な \lambda"の定義はわからないが、時系列データの分散がより正規分布に近づくような \lambdaを選択しているのだと想像している)。
powerTransform関数を今回のデータにかました結果、 \lambda=1.80となりそれを元にプロットした図が下の通りである。以降のデータにはこの \lambda=1.80のBox-Cox変換をかましたデータを扱うことにする。
f:id:knto-h:20180726182422p:plain


この記事ではデータの下準備として特徴を把握するとともに適切な前処理を考察した。続く(2)では実際に状態空間モデルでモデリングする。