時系列データを分析する際、データの「定常性」が分析の精度を大きく左右します。
この記事では、「定常性」の概要を解説し、非定常データを定常データに近づけるための前処理手法と、Pandasを用いた実装方法を紹介します。
定常とは
時系列データにおける定常とは、以下の条件を満たすデータの性質を指します。
- どの期間のデータを取り出しても、平均が一定範囲に収まる
- どの期間のデータを取り出しても、分散が一定範囲に収まる
- 規則的な周期性がない
次のグラフは、Microsoftの株価データです。

このグラフからは、以下の特徴が読み取れます。
- 上昇トレンドが見られ、平均が一定ではない
- 株価が上昇するにつれ、そのばらつき(分散)が大きくなっている
このことから、この時系列データは定常ではないといえます。定常でないデータは非定常データと呼ばれます。
多くの時系列分析手法(ARIMAモデルなど)は、データが定常であることを前提としています。そのため、分析に先立ち、非定常データを定常に近いデータに変換する前処理が必要になります。
非定常データを定常データに近づける方法
階差をとる
非定常データを定常に近づける代表的な手法が「階差」をとる方法です。階差とは、ある時点のデータとその1つ前の時点のデータとの差分のことです。
階差をとることで、トレンド成分を除去し、平均をある程度一定にすることができます。
上記株価データの階差をとったグラフは以下のようになります。

上昇トレンドはなくなり、平均は一定になりました。階差をとる処理は必要に応じて複数回実施することもあります。1回だけ差分をとった場合を「一回差分」、2回階差計算を繰り返した場合を「二回差分」と呼びます。
ただし、この結果を見ると期間によってばらつき(分散)に差が残っていることがわかります。
対数変換・平方根変換
分散を安定化させるためには、元データに対数変換または平方根変換を適用する方法が有効です。
元データを対数変換したグラフが以下です。

株価が上昇しても、ばらつきがある程度一定に保たれています。このデータに対してさらに階差をとった結果が以下です。

平均・分散ともにどの期間をとってもほぼ一定の値になっており、トレンドも除去されています。対数変換 → 階差の組み合わせにより、定常に近いデータへの変換が実現できたといえます。
Pythonで実装する
ここまで紹介した手順を、PandasおよびNumPyを使って実装します。
Pandasバージョン
本記事は、Pandas 2.2.3の情報を基に執筆しています。
import pandas as pd
print(pd.__version__)
>>
2.2.3使用するデータ
上記と同様に、Microsoftの株価データを使用します。このデータは、以下のKaggleリンクから取得できます。
Microsoft Stock Time Series Analysis – Kaggle
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()メソッドを使用します。diff()はPandasのSeriesおよびDataFrameに用意されているため、データフレームに直接適用することも、Series単体に適用することもできます。
# 対数変換してから階差をとる
y = np.log(df["Open"])
y = y.diff()データフレーム全体に適用する場合は以下のように記述します。
df_diff = df.diff()
注意: 先頭行は前のデータが存在しないため、階差を計算できず欠損値(NaN)になります。
コード全体
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)まとめ
今回は、時系列データにおける定常性の概念と、非定常データを定常データに変換する手法を紹介しました。
- 定常データとは、平均・分散が時間によらず一定で、周期性のないデータのこと
- 階差(diff)をとることで、トレンド成分を除去できる
- 対数変換・平方根変換を組み合わせることで、分散の安定化も実現できる
- Pandasの
diff()メソッドを使えば、数行のコードで階差を計算できる
効果的な時系列分析を行うためには、このような前処理が不可欠です。Pandasではdiff()メソッドにより非常に簡単に実装できるため、ぜひ実際にコードを動かして試してみてください。