• 0 - 1. の時系列データとは?
  • 0 -2.  Time series modelとは?
  • 1. ARIMAの簡単な説明
  • 2.金の価格データの分析
  • 3. ARIMAモデルの構築
  • 4.モデルの評価
  •  5.モデルの活用


    0-1. 時系列データとは?

    時系列データは、一定の時間間隔で出力されたデータである。私たちがお金を稼ぐために興味を持つ株式、有価、債券金利、家の値など、すべてが時系列データである。

    時系列データは、傾向 - サイクル、季節性、残差の合計、あるいは積で見ることができる。

  • 傾向(trend)は、長期的に増加あるいは減少を説明する部分である。
  • 季節性(seasonality)は、特定の期間(日単位、四半期、10年ごとなど)ごとに表示されるパターンを説明する部分である。
  • サイクル(cycle)は、季節性同様に同様のパターンを示すことを説明する部分であるが、季節性は違い固定された頻度ではない。

下の図は、オーストラリアの月の星糖尿病の薬の販売量とSTLを利用して、生データをトレンドと季節性、残差に分離した例である。

 


  図1.  オーストラリアの毎月の糖尿病薬の販売台数

図2.    糖尿病治療薬の売上高(Observed)の傾向(Trend)と季節性(Seasonal)と残差(Residual)へ分離

    上記の例は、傾向と季節性が明確に表示される。私たちは、上記の分解だけを通しても、2009年の糖尿病薬の販売台数を予測することができるだろう。

     しかし、明確な傾向と季節性を持たない株や金の価格、原油価格などはどのように予測することができますか?これらの問題を解決するための一つのアプローチがTime Seires Modelである。

 

    0-2. 時系列モデル(Time series model)とは?


     時系列データを分析する方法は大きく2つのアプローチが考えられる。 Explanatory models(あるいはAssociative Model)とTime Series Modelである(もちろん、両方を混合して使用するモデルもある)。

    「オーストラリアの毎月の糖尿病薬の販売台数」を例に挙げてみよう。私たちは、薬の月の販売台数(独立変数)を予測し、分析するために薬の販売量と相関関係があると推定されている「総人口」、「年齢構成」、「月平均気温」などを従属変数とするモデルを構築するすることができるだろう。これらのモデルをExplanatory Modelと呼ぶ。

    これに比べてTime Series Modelは、時間を従属変数として独立変数を説明するモデルである。たとえば、各年度の販売量が2001年:10本、2002年:12本、2003年:15本、2004年:17日の場合、2005年の販売台数は、一定の確率で19〜22個であるが推論を下すモデルある。

     代表的な時系列モデルのARIMA、Prophet、LSTMがあり、このモデルの簡単な説明と、金相場を例示としてモデルの構築と予測を試みるようにする。


    1. ARIMAの簡単な説明

    ARIMA(AutoRegressive Integrated Moving Average)は、自己回帰モデル(AR)と移動平均モデル(MA)とデータの正常性を確保するための差分(I)を合わせたモデルである。 ARIMAモデルはAR、I、MAの次数を決める必要がありますが、これARIMA(p、d、q)で表す。 ARの次数はp、Iの次数はd、MAの次数はqに表す。 ARIMA(1,1,0)の場合、AR(1)とI(1)を合わせたモデルという意味である。

     ARIMAモデルは、時系列データの正常性(stationary)を前提条件としている。時系列データから呼ばれる正常性とはデータの特性が時間に依存しないというものである。その条件を満たすためには、時間平均と分散、特定の時差との間の共分散が時間に応じて変化しない必要がある。

  • 自己回帰モデル(AR)
    現在のデータを過去のデータの線形結合で説明する。今日の値は、昨日の値自体に影響を受ける。もし係数が正の場合、昨日の値が大きい値であれば、今日の値も大きな値を有し、負の場合、昨日の値が大きい値であれば、今日の値は小さな値となる。 ARモデルの式は下記のようだ。


    yt:t時点での観測値
    yt-1:t-1時点での観測値
    c:定数項
    φ:自己回帰モデルの係数
    εt:エラー項、白色雑音


    自己回帰モデルは、AR(p)で表現し、pは次数を示す。       
    AR(1)モデルの場合:      
    yt = c +φ1yt-1 +εt      
    (条件:-1 <φ1<1)      


    AR(2)モデルの場合:      
    yt = c +φ1yt-1 +φ2yt-2 +εt     
    (条件:-1 <φ2<1       φ1+φ2<1、φ2-φ1<1)

          
    例として定数項があるAR(1)を描いてみよう。
    import numpy as np
    import matplotlib.pyplot as plt
    ar_process = []
    y = 140
    coff = 0.3
    const = 100
    for i in range(300):
     error = np.random.randn()
     y = const + y * coff + error
     ar_process.append(y)
    print(const / (1 - coff))
    plt.plot(ar_process)


    図3. AR(1)yt = 100 + 0.3yt-1 + eのグラフ


    グラフからわかるように、一定の平均(c /(1-φ1))と、一定の大きさの分散(ホワイトノイズの分散)の値を持つ通常の時系列であることを知ることができる。

     
  • 移動平均モデル(MA)

     現在のデータを過去のデータの誤差項の線形結合に説明する。今日の値は、昨日の値の誤差項に影響を受ける。係数が正であると、昨日の値が上昇する傾向であれば、今日の値も上昇する傾向になる。逆に負の場合は、昨日の値が上昇する傾向であれば、今日の値は下降する傾向になる。 MAモデルの式は下記の通りである。


    移動平均モデル

    yt:t時点での観測値
    c:定数項
    θ:自己回帰モデルの係数
    εt:t時点でのエラー項、白色雑
    εt-1:t-1時点でのエラー項、白色雑音


    移動平均モデルはMA(q)で表現し、自分の回帰モデルのようにqは次数を指す。

    簡単なMA(1)を描いてみよう。
    ma_process = []
    coff = 0.3
    const = 100
    error = np.random.randn()
    for i in range(300):
     ex_error = error
     error = np.random.randn()
     y = const + coff * ex_error + error
     ma_process.append(y)
    plt.plot(ma_process)
    


    図4.        MA(1)yt = 100 + 0.3et-1 + etのグラフ


    一定の値(c)を中心に振動する上時系列であることを確認することができる。
     
  • 差分(I)
    グラフを描いて確認したように、ARとMAモデルは、正常性の時系列を前提としたモデルである。差分は、正常の時系列ではないデータを正常化させる方法の一つである。 1次差分は、単に現在の時刻と、その前の時間の差である。つまり速度である。たとえば傾向があり、増加もしくは減少がある時系列は、正常性ではないが、その増加率、減少率が一定であれば、1次差分を通って正常化させることができる。 2次差分は、速度と速度の差であるため、加速度に考えてもよい。


            1次差分


            2次差分

         

     

    2.金の価格データの分析

     2000年からの金の相場を見てみましょう。

図5.    2000年から2020年3月末までの金の相場プグラフ

    大体的に上昇する傾向があることを確認することができる(2000年からの金を購入し、2020年までに持っていたら、なんと7倍!...約年10%の利率である!)。

def plot_rolling(data, interval):
 rolmean = data.rolling(interval).mean()
 rolstd = data.rolling(interval).std()
 #Plot rolling statistics:
 plt.figure(figsize=(10, 6))
 plt.xlabel('Date')
 orig = plt.plot(data, color='blue',label='Original')
 mean = plt.plot(rolmean, color='red', label='Rolling Mean')
 std = plt.plot(rolstd, color='black', label = 'Rolling Std')
 plt.legend(loc='best')
 plt.show()
plot_rolling(gold_price_series, 180)

 

前述のようにARIMAモデルは、正常性を前提とするモデルであるため、正常性を確認しなければならない。傾向があるということは、平均が時間に応じて変わるので、正常時系列で見ることができない。正常性を持たせるために、1次差分をしてみよう。

図6. 金の相場移動平均、移動標準偏差のグラフ

1図7. 次差分の時系列グラフ

一見0を中心に振動運動をする姿を見せているが、振幅(分散)は一定に見えない。定量的に、正常性を判断する方法はないだろうか?このような時に使用されるいくつかの統計的方法があるが、一番一般的なものとしてugmented Dickey-Fuller(ADF)検定法がある。

 

PythonでADF検定を行ってみよう。
 

from statsmodels.tsa.stattools import adfuller

y = gold_price_series [ 'price(USD)」]
y_1diff = gold_price_series.diff()dropna()[ 'price(USD)」]
result = adfuller(y)

print(f '元データADF Statistic:{result [0] :. 3f}')
print(f '元データp-value:{result [1] :. 3f}')

result = adfuller(y_1diff)

print(f'1次差分ADF Statistic:{result [0] :. 3f} ')
print(f'1次差分p-value:{result [1] :. 3f} ')

差分をしていない生データは、p-valueが有意水準である0.05よりも大きいため、正常の時系列で見ることができない。

 


元データADF Statistic: -0.694

元データp-value: 0.848

1次差分ADF Statistic: -14.105

1次差分p-value: 0.000

 

ADF検定の結果

これに比べて、1次差分のデータは、p-valueが有意水準よりも小さいので、通常の時系列で見ることができる。

これにより差分(d)の次数は1人ARIMA(p、1、q)のモデル構築が必要であることがわかる。

 

3.ARIMAモデルの構築

まずは、適切なAR(p)とMA(q)を決める必要がある。一般的には、ACF(AutoCorrelation Function)とPACF(Partial AutoCorrelation Function)グラフを用いて定めることができるが、この投稿では、AICを基準に最適の次数を指定するようにする。
 


def my_auto_arima(data、order、sort = 'AIC'):

 order_list = []
 aic_list = []
 bic_lsit = []

 for p in range(order [0]):
    for d in range(order [1]):
       for q in range(order [2]):
          model = ARIMA(data、order =(p、d、q))

 try:
    model_fit = model.fit()
    c_order = f'p {p} d {d} q {q} '
    aic = model_fit.aic
    bic = model_fit.bic
    order_list.append(c_order)
    aic_list.append(aic)
    bic_list.append(bic)

 except:
    pass

 result_df = pd.DataFrame(list(zip(order_list、aic_list))、columns = [ 'order'、 'AIC'])
 result_df.sort_values(sort、inplace = True)

 return result_df


my_auto_arima(gold_price_series、[3,3,3])


ARIMAモデルfitting結果

ARIMA(2,1,2)が最適のモデルであることを確認することができる。実際にモデルのfitting結果を確認してみましょう。一応、金の相場は

y't = 0.2620(1-0.7617 + 0.9486)+ 0.7617 y't-1  -  0.9486 y't-2 + et  -  0.7777et-1 + 0.9608et-2を伴うARIMAモデルであることを確認することができる。

モデルのFitting結果を時系列グラフで確認してみよう。
 



model = ARIMA(gold_price_series、(2,1,2))

model_fit = model.fit()

print(model_fit.summary())

model_fit.plot_predict()

plt.show()


金の相場実測値とARIMAモデルの予測値

一見予測と実測値が完全に重なるように見える。グラフを拡大して詳細を調べてみよう。

model_fit.plot_predict(start = datetime.datetime(2020,1,3))
plt.show()

金の相場実測値とARIMAモデルの予測値(拡大)

モデルの予測値は、単に実際の値をshiftingしたのとほぼ同じ形を示すことがわかる。これモデルが実際の値(過去)に基づいて、すぐに次の値(現在の)を予測するためには、ほぼ前の値をそのまま使用するのが妥当だという結論になっていることである。


 その後、未知のデータについては、どのように予測するか調べてみよう。

 2019年までのデータでモデルをfittingし、2020年3月までの値を予測してみよう。

 

 


train、test = gold_price_series.loc [:datetime.datetime(2019,12,31),:]、gold_price_series.loc [datetime.datetime(2019,12,31):、:]

model = ARIMA(train、(2,1,2))

model_fit = model.fit()

full_forecast = model_fit.forecast(steps = test.shape [0])

forecast = pd.DataFrame(full_forecast [0]、index = test.index、columns = test.columns)

plt.plot(train.loc [datetime.datetime(2018,12,31):、:])

plt.plot(test)

plt.plot(forecast)


ARIMAの金の相場展望

緑の予測線を見れば分かるように、最後の値をほぼそのまま使用していることがわかる。一見見ては、金相場予測には使用が困難なモデルに見える。

4.モデルの評価

5.モデルの活用


 モデルの定量的な性能がどうか、相場予測に活用が可能かどうかは、今後Prophet、LSTMモデルポスティング後に同じ基準で比較評価をするようにする。

 
 
参考文献

 

 

 

ttps://otexts.com/fppkr/index.html

https://www.machinelearningplus.com/time-series/arima-model-time-series-forecasting-python/