変化点分析

nAG Library for Python Example集

このページは、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を前提としています。

ctype = 1

時系列データ値の想定される分散を記述し、paramキーワード引数を使用してnAG関数に伝える必要があります。この値を変更すると、アルゴリズムの系列値の差異に対する感度が変わり、その結果、検出される変化点の数が変化します。

param = [0.2]

変化点を見つける

from naginterfaces.library import tsa
soln = tsa.cp_pelt(ctype, y, param=param)

変化点の位置は戻り値のタプルの 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(
        tau_i+1, tau_val, soln.sparam[0, tau_i], soln.sparam[1, 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
plt.plot(range(1, len(y)+1), y, color='r', linewidth=0.75)
last_cp = 1.
for tau_i, tau_val in enumerate(soln.tau):
    vl = plt.axvline(tau_val, label='Change point')
    hl = plt.hlines(
        soln.sparam[0, tau_i],
        xmin=last_cp, xmax=tau_val, color='g', label='Mean',
    )
    last_cp = tau_val
plt.xlim((1, len(y)))
t11 = ['1999 Initiation\nof Euro', '2008 Financial\nCrisis', '2016 UK EU\nReferendum']
t12 = [0, (2008-1999)*12, (2016-1999)*12]
plt.xticks(t12, t11, size='small')
plt.xlabel('Time - January 1999 to February 2020')
plt.ylabel('Euros per Pound')
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')
plt.legend(handles=[vl, hl], loc='upper right')
plt.show()

関連情報
MENU
© 日本ニューメリカルアルゴリズムズグループ株式会社 2024
Privacy Policy  /  Trademarks