時系列データを分析する際、データの「定常性」が分析の精度を分けます。
今回は、「定常性」について概要を解説し、定常でないデータを定常データにするための前処理実装を、Pandasを用いて紹介します。
今回は時系列データ分析における前処理だな。
定常とは
時系列における定常とは、ざっくり言うと
- どの期間のデータを取り出しても、平均が一定範囲に収まる
- どの期間のデータを取り出しても、分散が一定範囲に収まる
- 規則的な周期性がない
ようなものを指します。
次のグラフは、Microsoftの株価です。

このグラフから、データは定常といえるだろうか?
右肩上がりですね。業績はいいみたいですが、、
- 上昇トレンドが見られ、平均が一定ではない
- 株価が上昇するにつれ、そのばらつき(分散)が大きくなっている
このことから、この時系列データは定常ではないといえます。定常でないデータは非定常データと呼ばれます。
データ分析を行う際には、このような非定常データを定常に近いデータに変換していく必要があります。
非定常データを定常データに近づける方法
階差をとる
非定常データを定常に近いデータに近づける方法として「階差」をとるという方法があります。階差とは、あるデータとその1つ前のデータの差分のことです。階差をとることで、トレンドを除去し、平均をある程度一定にすることができます。
上記株価データの階差をとったグラフは以下のようになります。

上昇トレンドはなくなり、平均は一定になりました。階差をとる処理は、場合によって複数回実施することもあります。今回は一度だけ差分をとったので「一回差分」、2回階差計算を繰り返しタ場合を「二回差分」といったように表現します。
定常に近づいた感じがします!
うむ。だが、まだ期間によってばらつきに差がありそうだな。
対数変換、平方根変換
ばらつきをほぼ一定にするためには、元データを対数変換あるいは平方根変換する方法があります。今回は元データを対数変換してみます。

株価が上昇しても、そのばらつきはある程度一定になりました。このデータで階差をとってグラフを描いてみます。

平均、分散ともにどの期間をとっても同じような値になりそうです。また、トレンドも除去できているので、定常に近いデータに変換できたといえそうです。
Pythonで実装する
ここまで紹介してきた手順を、Pythonで実装していきます。
使用するデータ
上記と同様に、Microsoftの株価データを使用します。このデータは、Kaggleの以下リンクから取得できます。
https://www.kaggle.com/vijayvvenkitesh/microsoft-stock-time-series-analysis
import pandas as pd
df = pd.read_csv("input/Microsoft_Stock.csv").set_index("Date")
x = pd.to_datetime(df.index).strftime('%Y-%m-%d')
y = df["Open"]

情報としてはその日の始値、終値、最高値などありますが、今回は始値”Open”をY軸にとってグラフ描画していきます。
対数変換、平方根変換
対数変換、平方根変換にはnumpyを用います。
#対数変換
y = np.log(df["Open"])
#平方根変換
y = np.sqrt(df["Open"])
階差をとる
階差をとる場合はdiff()メソッドを用います。このメソッドはPandasにもnumpyにも用意されているため、データフレームにそのまま適用することもできればnumpy配列に適用することもできます。
今回はnumpy配列に適用します。
#対数変換から階差
y = np.log(df["Open"])
y = y.diff()
ちなみにデータフレームに適用する場合は以下の通り
df_diff = df.diff()

先頭のデータは階差を計算できないため欠損値になります。
コード全体
Microsoftの株価データを定常に近いデータに変換してグラフ出力する際のコードは以下の通りです。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv("input/Microsoft_Stock.csv").set_index("Date")
x = pd.to_datetime(df.index).strftime('%Y-%m-%d')
y = df["Open"]
#対数変換
y = np.log(df["Open"])
#階差
y = y.diff()
#x軸ラベルの表示間隔
ticks = 200
plt.xticks(np.arange(0, len(x), ticks), x[::ticks], rotation=60)
plt.plot(x, y)
Pythonでデータサイエンスするなら
Pythonでデータサイエンスをするなら、以下の書籍がおすすめです。Pandas、matplotlib、Numpy、scikit-learnといったデータサイエンスに必要なライブラリを、体系立てて一通り学ぶことができます。
ややお値段高めですが、これ1冊で十分という内容・ボリュームなので、損はしないと思います^^
まとめ
時系列データにおける定常性について触れ、非定常データを定常に近いデータに変換して分析できるようにする手順を紹介しました。
効果的な分析をするためにはその前処理が重要です。今回の例はPythonでも簡単に実装できるので、是非手を動かしながら試してみてください!
とりあえず株価を分析しまくって、一儲けしてきます
世の中そんなに甘くはないぞ、、