バックテストでは儲かるのに実際に動かしてみたら爆損した!
そんな経験はML Botterならば誰もが持っていると思います。今回はその理由を見せかけの回帰 という現象を用いて説明していこうと思います。
(ちょっとだけ算数を使いますが、だいぶ分かりやすく書いていきます )
まず、2つの無関係なランダムウォークx t x_t x t とy t y_t y t を考えます(ϵ \epsilon ϵ はホワイトノイズです)。
y t = y t − 1 + ϵ y t x t = x t − 1 + ϵ x t y_t = y_{t-1} + \epsilon_{yt} \\
x_t = x_{t-1} + \epsilon_{xt}
y t = y t − 1 + ϵ y t x t = x t − 1 + ϵ x t
これを線形回帰させてみます。
y t = α + β x t + ϵ t {\displaystyle y_{t}=\alpha +\beta x_{t}+\epsilon _{t}}
y t = α + β x t + ϵ t
もちろん2つの時系列は互いに無関係のランダムウォークなので、α \alpha α やβ \beta β の真の値は0であることはお分かりになると思います。これを実際に確かめてみましょう。
ピアソンの相関係数 r x y r_{xy} r x y の値は以下の式で与えられます。(ここまでは教科書にのってます)
r x y = ∑ t = 1 T ( x t − x ˉ ) ( y t − y ˉ ) ∑ t = 1 T ( x t − x ˉ ) 2 ∑ t = 1 n ( y t − y ˉ ) 2 r_{xy} = \frac{\sum_{t=1}^{T} (x_t - \bar{x})(y_t- \bar{y})}{\sqrt{\sum_{t=1}^{T} (x_t - \bar{x})^2 \sum_{t=1}^{n} (y_t - \bar{y})^2}}
r x y = ∑ t = 1 T ( x t − x ˉ ) 2 ∑ t = 1 n ( y t − y ˉ ) 2 ∑ t = 1 T ( x t − x ˉ ) ( y t − y ˉ )
ちょっとだけ変形して
r x y = 1 T ∑ t = 1 T 1 T ( x t − x ˉ ) 1 T ( y t − y ˉ ) 1 T 2 ∑ t = 1 T 1 T ( x t − x ˉ ) 2 ∑ t = 1 T 1 T ( y t − y ˉ ) 2 r_{xy} = \frac{\frac{1}{T} \sum_{t=1}^{T} \frac{1}{\sqrt{T}} (x_t - \bar{x})\frac{1}{\sqrt{T}} (y_t - \bar{y})}{\sqrt{\frac{1}{T^2}
\sum_{t=1}^{T}\frac{1}{T} (x_t - \bar{x})^2 \sum_{t=1}^{T}\frac{1}{T} (y_t - \bar{y})^2}}
r x y = T 2 1 ∑ t = 1 T T 1 ( x t − x ˉ ) 2 ∑ t = 1 T T 1 ( y t − y ˉ ) 2 T 1 ∑ t = 1 T T 1 ( x t − x ˉ ) T 1 ( y t − y ˉ )
さて、確率論に長けた皆様ならこの式を見てDonskerの定理 を使えることがわかりますね。
Donskerの定理
独立同一分布の確率変数の累積和の時系列は、あるスケーリングの下でブラウン運動に収束する。つまり、
X 1 , X 2 , X 3 , . . . . X n X_1,X_2,X_3, .... X_n X 1 , X 2 , X 3 , .... X n を平均0、分散1の独立同一分布の確率変数とすると、
1 n X n ( r ) → W ( r ) ( n → ∞ ) \sqrt{\frac{1}{n}} X_n(r) \rightarrow W(r) (n \rightarrow \infty)
n 1 X n ( r ) → W ( r ) ( n → ∞ )
このDonskerの定理を両辺に積分を取ることで拡張します(連続写像定理 )。
∫ 0 1 1 n X n ( r ) d r → ∫ 0 1 W ( r ) d r ( n → ∞ ) \int_0^1 \sqrt{\frac{1}{n}} X_n(r)dr \rightarrow \int_0^1 W(r)dr (n \rightarrow \infty)
∫ 0 1 n 1 X n ( r ) d r → ∫ 0 1 W ( r ) d r ( n → ∞ )
ここで
∫ 0 1 x t ( r ) d r = ∑ t = 1 T x t T \int_0^1 x_t(r)dr = \sum_{t=1}^{T} \frac{x_t}{T}
∫ 0 1 x t ( r ) d r = t = 1 ∑ T T x t
x t ˉ = ∑ t = 1 T x t T \bar{x_t}=\sum_{t=1}^{T} \frac{x_t}{T}
x t ˉ = t = 1 ∑ T T x t
の二つの式を用いることにより、
r x y r_{xy} r x y の式の分子は
1 T ∑ t = 1 T 1 T ( x t − x ˉ ) 1 T ( y t − y ˉ ) {\frac{1}{T} \sum_{t=1}^{T} \frac{1}{\sqrt{T}} (x_t - \bar{x})\frac{1}{\sqrt{T}} (y_t - \bar{y})}
T 1 t = 1 ∑ T T 1 ( x t − x ˉ ) T 1 ( y t − y ˉ )
→ ∫ 0 1 ( W 1 ( r ) d r − ∫ 0 1 W 1 ( r ) d r ) ( W 2 ( r ) d r − ∫ 0 1 W 2 ( r ) d r ) d r \rightarrow \int_0^1 \bigg(W_1(r)dr - \int_0^1 W_1(r)dr \bigg) \bigg(W_2(r)dr - \int_0^1 W_2(r)dr \bigg)dr
→ ∫ 0 1 ( W 1 ( r ) d r − ∫ 0 1 W 1 ( r ) d r ) ( W 2 ( r ) d r − ∫ 0 1 W 2 ( r ) d r ) d r
となることが分かります。
また、分母の方は
1 T 2 ∑ t = 1 T 1 T ( x t − x ˉ ) 2 ∑ t = 1 T 1 T ( y t − y ˉ ) 2 \sqrt{\frac{1}{T^2}
\sum_{t=1}^{T}\frac{1}{T} \bigg(x_t - \bar{x}\bigg)^2 \sum_{t=1}^{T}\frac{1}{T} \bigg(y_t - \bar{y}\bigg)^2}
T 2 1 t = 1 ∑ T T 1 ( x t − x ˉ ) 2 t = 1 ∑ T T 1 ( y t − y ˉ ) 2
→ ∫ 0 1 ( W 1 ( r ) d r − ∫ 0 1 W 1 ( r ) d r ) 2 d r ( W 2 ( r ) d r − ∫ 0 1 W 2 ( r ) d r ) 2 d r \rightarrow \sqrt{\int_0^1 \bigg(W_1(r)dr - \int_0^1 W_1(r)dr \bigg)^{2} dr \bigg(W_2(r)dr - \int_0^1 W_2(r)dr \bigg)^2dr}
→ ∫ 0 1 ( W 1 ( r ) d r − ∫ 0 1 W 1 ( r ) d r ) 2 d r ( W 2 ( r ) d r − ∫ 0 1 W 2 ( r ) d r ) 2 d r
となって、T T T が消滅しました。つまり、相関係数r x y r_{xy} r x y は0へは収束しない ということが分かります。計算が複雑なのでここでは割愛しますが、最小二乗法から導かれたα \alpha α とβ \beta β のF F F 検定統計量もβ = 0 \beta=0 β = 0 の帰無仮説を棄却します。
つまり何なのか
時系列の性質によっては全く無関係の二つの系列が統計的に有意であることを示してしまいます。これはとても恐ろしいことです。
例えば、ある特徴量Xを発見し、それを用いてビットコインの価格を予測するモデルを作ったとしましょう。まず、皆さんはその特徴量が本当に有意義であるのかを統計的に分析したりしますね。しかしながら、その特徴量が単位根を持つ過程(単位根過程 )であった場合、もしその特徴量が全く意味のないものであったとしても、統計的に有意な結果を示してしまいます。
また、これは古典的な統計モデルに限った話ではないです。あらゆる時系列モデルは、それが機械学習だろうとベイズモデルであろうと、系列の定常性を前提としていることが基本です。数学的アプローチの違いはあれど、時系列の性質を無視したモデルは必ず破綻をきたします。
実際に試してみよう
理論の話だけでは実感もないと思うので実際に試してみましょう。
Pythonを使って2つのランダムウォークを生成し、最小二乗法(OLS)によって導出された決定係数(R 2 R^2 R 2 )をみてみましょう。
import numpy as np
import statsmodels.api as sm
from matplotlib import pyplot as plt
plt.rcParams[ "figure.figsize" ] = ( 7 , 5 )
plt.rcParams[ "figure.facecolor" ] = 'grey'
x = np.cumsum(np.random.standard_normal(size= 1000000 ))
y = np.cumsum(np.random.standard_normal(size= 1000000 ))
plt.plot(x)
plt.plot(y)
plt.legend([ 'x' , 'y' ])
plt.show()
これで二つのランダムウォークを描画しています。ぱっと見た感じ、人間の目には相関があるようには見えませんね。
決定係数の求め方はPythonであれば色々とありますが、今回はstatsmodelsというパッケージを用いていきます。
最小二乗法を使う場合、決定係数は0から1の実数をとります。無相関であるはずの2つの系列は0.65という高い相関を示しています。
まとめ
全く意味の無い特徴量であっても、時系列の性質によっては統計的有意を示すことがあると分かりました。
モデルに落とし込む前に必ずADF検定などでデータの性質を調べ、不適格な特徴量はちゃんとモデルから外しましょう。