このページは、nAGライブラリのJupyterノートブックExampleの日本語翻訳版です。オリジナルのノートブックはインタラクティブに操作することができます。
変化点分析
変化点とは、データセットの何らかの特徴が変化する時点のことです。単変量時系列の変化点を検出するには、tsa.cp_pelt
を使用できます。
以下の時系列を考えてみましょう。これは1999年1月から2020年2月までのEUR/GBP為替レートを示しています(数字は1ポンドあたりのユーロを示し、為替データはwww.macrotrends.netから取得しています)
= [
y 1.41, 1.47, 1.49, 1.49, 1.54, 1.56, 1.54, 1.52, 1.54, 1.56, 1.59, 1.61,
1.61, 1.67, 1.64, 1.69, 1.72, 1.61, 1.61, 1.64, 1.64, 1.69, 1.69, 1.67,
1.59, 1.59, 1.59, 1.61, 1.61, 1.69, 1.69, 1.64, 1.64, 1.64, 1.64, 1.61,
1.61, 1.67, 1.67, 1.64, 1.64, 1.56, 1.56, 1.61, 1.59, 1.61, 1.59, 1.59,
1.56, 1.54, 1.47, 1.45, 1.45, 1.41, 1.45, 1.45, 1.47, 1.43, 1.47, 1.45,
1.43, 1.47, 1.52, 1.52, 1.49, 1.52, 1.52, 1.54, 1.49, 1.45, 1.45, 1.47,
1.43, 1.45, 1.47, 1.47, 1.49, 1.49, 1.49, 1.47, 1.47, 1.49, 1.47, 1.49,
1.47, 1.49, 1.47, 1.45, 1.47, 1.47, 1.45, 1.47, 1.49, 1.49, 1.52, 1.49,
1.49, 1.52, 1.49, 1.49, 1.47, 1.49, 1.49, 1.49, 1.49, 1.45, 1.45, 1.43,
1.35, 1.33, 1.32, 1.27, 1.28, 1.28, 1.27, 1.28, 1.23, 1.27, 1.27, 1.19,
1.05, 1.12, 1.12, 1.10, 1.14, 1.16, 1.18, 1.18, 1.15, 1.10, 1.11, 1.11,
1.12, 1.15, 1.11, 1.14, 1.16, 1.20, 1.22, 1.22, 1.22, 1.15, 1.16, 1.19,
1.16, 1.18, 1.19, 1.14, 1.12, 1.15, 1.11, 1.15, 1.14, 1.18, 1.18, 1.18,
1.20, 1.20, 1.20, 1.20, 1.23, 1.25, 1.25, 1.28, 1.27, 1.27, 1.25, 1.23,
1.23, 1.16, 1.16, 1.19, 1.19, 1.18, 1.18, 1.15, 1.19, 1.20, 1.19, 1.22,
1.20, 1.22, 1.22, 1.22, 1.22, 1.23, 1.27, 1.27, 1.27, 1.30, 1.28, 1.27,
1.28, 1.33, 1.39, 1.39, 1.37, 1.41, 1.43, 1.43, 1.37, 1.37, 1.41, 1.43,
1.37, 1.33, 1.30, 1.25, 1.28, 1.30, 1.20, 1.19, 1.19, 1.15, 1.11, 1.19,
1.18, 1.18, 1.18, 1.18, 1.19, 1.15, 1.15, 1.12, 1.10, 1.14, 1.15, 1.14,
1.14, 1.15, 1.12, 1.15, 1.14, 1.15, 1.14, 1.14, 1.12, 1.14, 1.15, 1.13,
1.11, 1.14, 1.16, 1.16, 1.13, 1.11, 1.10, 1.10, 1.13, 1.16, 1.17, 1.18,
1.19, 1.18 ]
私たちは、データが正規分布から得られると仮定して、平均の変化を探したいと考えています。これは、cp_pelt
ルーチンのctype
パラメータを1
に設定することで選択されます。ctype
の他の値は、異なる分布やデータの特性に対して使用できますが、このノートブックのプロットはctype = 1
を前提としています。
= 1 ctype
時系列データ値の想定される分散を記述し、param
キーワード引数を使用してnAG関数に伝える必要があります。この値を変更すると、アルゴリズムの系列値の差異に対する感度が変わり、その結果、検出される変化点の数が変化します。
= [0.2] param
変化点を見つける
from naginterfaces.library import tsa
= tsa.cp_pelt(ctype, y, param=param) soln
変化点の位置は戻り値のタプルの tau
属性にあり、推定された分布パラメータは sparam
属性にあります。
以下は結果の表です:
print(' -- Change Points -- --- Distribution ---')
print(' Number Position Parameters')
print('='*50)
for tau_i, tau_val in enumerate(soln.tau):
print('{:4d} {:6d} {:12.2f} {:12.2f}'.format(
+1, tau_val, soln.sparam[0, tau_i], soln.sparam[1, tau_i],
tau_i ))
-- Change Points -- --- Distribution ---
Number Position Parameters
==================================================
1 50 1.60 0.20
2 109 1.47 0.20
3 186 1.19 0.20
4 210 1.34 0.20
5 254 1.15 0.20
時系列をプロットし、また変化点を垂直線として、対応する平均値を水平線としてプロットしてください。
# Jupyter の表示バックエンドを選択:
%matplotlib nbagg
import matplotlib.pyplot as plt
range(1, len(y)+1), y, color='r', linewidth=0.75)
plt.plot(= 1.
last_cp for tau_i, tau_val in enumerate(soln.tau):
= plt.axvline(tau_val, label='Change point')
vl = plt.hlines(
hl 0, tau_i],
soln.sparam[=last_cp, xmax=tau_val, color='g', label='Mean',
xmin
)= tau_val
last_cp 1, len(y)))
plt.xlim((= ['1999 Initiation\nof Euro', '2008 Financial\nCrisis', '2016 UK EU\nReferendum']
t11 = [0, (2008-1999)*12, (2016-1999)*12]
t12 ='small')
plt.xticks(t12, t11, size'Time - January 1999 to February 2020')
plt.xlabel('Euros per Pound')
plt.ylabel(
plt.title('Monthly EUR-GBP FX rate from January 1999 to February 2020\n'
'(FX data from www.macrotrends.net)\n'
'Showing change points determined in the mean')
=[vl, hl], loc='upper right')
plt.legend(handles plt.show()