ITや趣味など気軽に投稿しています。

【Pandas】データの差分(階差)を計算して時系列データを分析する

時系列データを分析する際、データの「定常性」が分析の精度を分けます。

今回は、「定常性」について概要を解説し、定常でないデータを定常データにするための前処理実装を、Pandasを用いて紹介します。

今回は時系列データ分析における前処理だな。

定常とは

時系列における定常とは、ざっくり言うと

  • どの期間のデータを取り出しても、平均が一定範囲に収まる
  • どの期間のデータを取り出しても、分散が一定範囲に収まる
  • 規則的な周期性がない

ようなものを指します。

次のグラフは、Microsoftの株価です。

Microsoftの株価グラフ

このグラフから、データは定常といえるだろうか?

右肩上がりですね。業績はいいみたいですが、、

  • 上昇トレンドが見られ、平均が一定ではない
  • 株価が上昇するにつれ、そのばらつき(分散)が大きくなっている

このことから、この時系列データは定常ではないといえます。定常でないデータは非定常データと呼ばれます。

データ分析を行う際には、このような非定常データを定常に近いデータに変換していく必要があります。

非定常データを定常データに近づける方法

階差をとる

非定常データを定常に近いデータに近づける方法として「階差」をとるという方法があります。階差とは、あるデータとその1つ前のデータの差分のことです。階差をとることで、トレンドを除去し、平均をある程度一定にすることができます。

上記株価データの階差をとったグラフは以下のようになります。

Microsoftの株価の階差グラフ

上昇トレンドはなくなり、平均は一定になりました。階差をとる処理は、場合によって複数回実施することもあります。今回は一度だけ差分をとったので「一回差分」、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"]
dfの中身

情報としてはその日の始値、終値、最高値などありますが、今回は始値”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()
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でも簡単に実装できるので、是非手を動かしながら試してみてください!

とりあえず株価を分析しまくって、一儲けしてきます

世の中そんなに甘くはないぞ、、