この記事では、PythonとStatsmodelsライブラリを用いて時系列データ解析を行う方法を、株価予測を例に解説します。
- 時系列データ解析とは
- Statsmodelsとは
- 環境構築
- 株価データの取得
- データの前処理
- 時系列データの可視化
- 単純移動平均(SMA)による分析
- ARIMAモデルによる予測
- よくあるエラーと対処法
- まとめ
時系列データ解析とは
時系列データ解析は、時間経過とともに観測されるデータ(例:株価、気象データ、IoTセンサーデータ)の変動パターンを分析し、将来の値動きを予測する手法です。 経済、気象、マーケティングなど、多くの分野で活用されています。
[PR]
Statsmodelsとは
Statsmodelsは、Pythonの統計解析ライブラリの一つで、特に時系列解析に強みを持っています。 自己回帰モデル(AR)、移動平均モデル(MA)、自己回帰移動平均モデル(ARMA)、自己回帰和分移動平均モデル(ARIMA)など、様々な時系列モデルを扱うことができます。
環境構築
まず、必要なライブラリをインストールします。
pip install pandas numpy matplotlib statsmodels yfinance
必要なライブラリと、その役割は以下の表のとおりです。
| ライブラリ | 役割 |
|---|---|
| pandas | データ操作と分析のためのライブラリ。 |
| numpy | 数値計算を効率的に行うためのライブラリ。 |
| matplotlib | データの可視化を行うためのライブラリ。 |
| statsmodels | 統計モデルの推定、検定、予測を行うためのライブラリ。 |
| yfinance | Yahoo Financeから株価データを取得するためのライブラリ。 |
コードの先頭でこれらのライブラリをインポートします。
import pandas as pd import numpy as np import matplotlib.pyplot as plt import statsmodels.api as sm import yfinance as yf
株価データの取得
今回は、例としてGoogle(GOOG)の株価データをYahoo Financeから取得し、解析を行います。
yfinance ライブラリを使用すると、簡単にデータをダウンロードできます。
# データの取得期間を設定 start_date = "2020-03-01" end_date = "2023-11-01" # Yahoo Financeからデータを取得 data = yf.download("GOOG", start=start_date, end=end_date) # データの最初の5行を表示 print(data.head())
yf.download関数で、ティッカーシンボル(ここでは"GOOG")、開始日、終了日を指定してデータを取得します。
取得したデータはpandasのDataFrame形式で格納され、.head()でデータの最初の5行を確認できます。
データの前処理
取得したデータを確認し、時系列解析に適した形に前処理を行います。
前処理1: 日付の確認とインデックス設定
時系列データでは、日付がインデックスになっていると扱いやすくなります。
# 'Date'列が存在しない、DatetimeIndexが設定されていることを確認 print(data.index)
yfinanceで取得した場合、日付がインデックスに設定されているため、data.indexで確認します。
前処理2: 欠損値の確認
欠損値があると、後の解析でエラーの原因となるため、確認と処理が必要です。
# 欠損値の数を確認 print(data.isnull().sum())
.isnull().sum()で各列の欠損値の数を確認します。欠損値がある場合は、適切な方法(例えば、前後の値で補間するなど)で処理します。今回のデータでは欠損値はないことが前提です。
前処理3: 終値の抽出
今回は終値('Close')のデータを使って解析を行うため、終値の列だけを抽出します。
# 終値の列を抽出 df = data[['Close']]
時系列データの前処理については、下記で詳しく解説しています。
時系列データの可視化
データの前処理が終わったら、まずはデータの全体像を把握するために可視化を行います。
# 終値の推移をプロット plt.figure(figsize=(10, 6)) plt.plot(df['Close']) plt.title('Google Stock Price (Close)') plt.xlabel('Date') plt.ylabel('Price') plt.grid(True) plt.show()
plt.plot()で時系列データをプロットし、plt.title()、plt.xlabel()、plt.ylabel()でグラフのタイトルと軸ラベルを設定します。
plt.grid(True)でグリッド線を表示し、plt.show()でグラフを表示します。
単純移動平均(SMA)による分析
時系列データの基本的な分析手法として、単純移動平均(SMA)があります。 SMAは、一定期間のデータの平均値を計算することで、データの平滑化を行い、トレンドを把握しやすくします。
# 20日間の単純移動平均を計算 sma_20 = df['Close'].rolling(window=20).mean() # SMAを元のデータと合わせてプロット plt.figure(figsize=(10, 6)) plt.plot(df['Close'], label='Close') plt.plot(sma_20, label='SMA (20 days)') plt.title('Google Stock Price with SMA') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.grid(True) plt.show()
df['Close'].rolling(window=20).mean()で、終値の20日間単純移動平均を計算します。
windowパラメータで平均を取る期間を指定します。
計算結果を元のデータと合わせてプロットすることで、株価の変動が平滑化され、長期的なトレンドが見やすくなります。
ARIMAモデルによる予測
より高度な時系列解析手法として、ARIMAモデルがあります。ARIMAモデルは、自己回帰(AR)、和分(I)、移動平均(MA)の3つの要素を組み合わせたモデルで、多くの時系列データに適用できます。
STEP1: ARIMAモデルのパラメータの確認
ARIMAモデルは、(p, d, q)の3つのパラメータを持ちます。これらのパラメータは、モデルの挙動を決定する重要な要素です。
| パラメータ | 意味 | 説明 |
|---|---|---|
| p | 自己回帰(AR)の次数 | 現在の値が過去の p 個の値に依存することを示します。つまり、過去 p 個の値を使って現在の値を予測します。 |
| d | 差分(I)の次数 | データの定常性を確保するために必要な差分の回数を示します。非定常な時系列データを定常なデータに変換するために差分を取ります。 |
| q | 移動平均(MA)の次数 | 過去の q 個の予測誤差(残差)に依存することを示します。つまり、過去 q 個の誤差を使って現在の値を予測します。 |
これらのパラメータは通常、0以上の整数値を取ります。
STEP2: パラメータの推定
最適なパラメータ(p, d, q)は、データによって異なります。一般的には、自己相関関数(ACF)と偏自己相関関数(PACF)のグラフを見て推定するか、情報量基準(AIC、BICなど)を使って自動的に選択します。
# ACFとPACFのプロット fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8)) sm.graphics.tsa.plot_acf(df['Close'], lags=40, ax=ax1) # ACF sm.graphics.tsa.plot_pacf(df['Close'], lags=40, ax=ax2) # PACF plt.show() # 情報量基準(AIC)によるパラメータ探索 p = d = q = range(0, 3) # パラメータの範囲を設定(今回は0から2まで) pdq = [(x, y, z) for x in p for y in d for z in q] best_aic = float("inf") best_param = None for param in pdq: try: model = sm.tsa.ARIMA(df['Close'], order=param) results = model.fit() if results.aic < best_aic: best_aic = results.aic best_param = param except Exception as e: #エラーが出たらスキップ continue print(f"Best ARIMA parameters: {best_param} with AIC: {best_aic}")
sm.graphics.tsa.plot_acf()とsm.graphics.tsa.plot_pacf()でACFとPACFのグラフをプロットします。 lagsパラメータで、どれくらい過去の値まで考慮するかを指定します。
情報量基準による探索では、range()でパラメータの範囲を指定し、すべての組み合わせを試します。sm.tsa.ARIMA()でARIMAモデルを作成し、model.fit()でモデルをデータに適合させます。AICが最も小さいパラメータの組み合わせを最適なパラメータとします。AICはresults.aicで取得できます。
STEP3: ARIMAモデルの構築と予測
# 最適なパラメータでARIMAモデルを構築 model = sm.tsa.ARIMA(df['Close'], order=best_param) results = model.fit() # 将来の株価を予測 # 例:予測期間を30日とする forecast_steps = 30 forecast = results.get_forecast(steps=forecast_steps) # 予測結果の信頼区間を取得 forecast_ci = forecast.conf_int()
results.get_forecast(steps=forecast_steps)で将来の値を予測します。stepsで予測する期間を指定します。forecast.conf_int()は予測の信頼区間を取得します。
STEP4: 予測結果の可視化
# 予測結果をプロット plt.figure(figsize=(12, 6)) plt.plot(df['Close'], label='Actual') plt.plot(forecast.predicted_mean, label='Forecast', color='red') plt.fill_between(forecast_ci.index, forecast_ci.iloc[:, 0], forecast_ci.iloc[:, 1], color='pink', alpha=0.3) plt.title('Google Stock Price Forecast with ARIMA') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.grid(True) plt.show()
forecast.predicted_meanで予測値を取得し、実測値と合わせてプロットします。plt.fill_between()で信頼区間を塗りつぶします。
よくあるエラーと対処法
ValueError: Non-stationary starting autoregressive parameters...
ARIMAモデルのパラメータが不適切で、モデルが定常性を満たさない場合に発生します。
ValueErrorに対しては、AR、I、MAのパラメータを見直す必要があります。データの形式
データが時系列形式(日付がインデックス)でない場合にエラーが発生することがあります。
pd.to_datetime()で日付をdatetime型に変換し、set_index()でインデックスに設定します。 また、データに欠損値がないかも確認しましょう。ValueError: maxlag should be < nobs
自己相関関数(ACF)や偏自己相関関数(PACF)を計算する際に、
lagsパラメータが大きすぎると発生します。lagsはデータの長さ-1より小さく設定。"operands could not be broadcast together with shapes" ValueError、または LinAlgError
SARIMAXモデルを使用する際、外的変数(exog)の形状が不適切な場合や、データの数値的な問題で発生します。外的変数を使用する場合は、その形状(特に時間軸の長さ)が目的変数と一致しているか確認します。また、データのスケールが大きすぎる、または小さすぎる場合は、データを正規化することを検討します。周期性に関するエラー (ValueError: Input contains NaN, infinity or a value too large...)
データに明確な周期性があるにも関わらず、ARIMAモデルでその周期性を考慮していない場合に発生します。この場合、季節性ARIMA (SARIMA) モデルや、
SARIMAXモデルを検討します。具体的には、sm.tsa.statespace.SARIMAXを使用し、seasonal_orderパラメータで周期性を指定します (例:seasonal_order=(1, 1, 1, 12)で年間の周期性を考慮)。
まとめ
この記事では、PythonとStatsmodelsを使った時系列データ解析の基本的な手順を、株価予測を例に解説しました。時系列データ解析は、適切にモデルとパラメータを選択し、適切に評価することで、さまざまな分野で活用できる強力な手法です。
最後にPythonの学習に利用できるUdemy
のサイトを紹介します。ぜひ活用ください。
[PR]
関連記事
時系列データの分析については、下記の記事でも解説しています。