以下の内容はhttps://pydocument.hatenablog.com/entry/2023/04/03/230137より取得しました。


PythonとStatsmodelsを用いた時系列データ解析:株価予測を例に解説

この記事では、PythonとStatsmodelsライブラリを用いて時系列データ解析を行う方法を、株価予測を例に解説します。

時系列データ解析とは

時系列データ解析は、時間経過とともに観測されるデータ(例:株価、気象データ、IoTセンサーデータ)の変動パターンを分析し、将来の値動きを予測する手法です。 経済、気象、マーケティングなど、多くの分野で活用されています。

[PR]

click.linksynergy.com

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']]

時系列データの前処理については、下記で詳しく解説しています。

pydocument.hatenablog.com

時系列データの可視化

データの前処理が終わったら、まずはデータの全体像を把握するために可視化を行います。

# 終値の推移をプロット
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)のグラフを見て推定するか、情報量基準(AICBICなど)を使って自動的に選択します。

# 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が最も小さいパラメータの組み合わせを最適なパラメータとします。AICresults.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 iconのサイトを紹介します。ぜひ活用ください。

[PR]

click.linksynergy.com

click.linksynergy.com

click.linksynergy.com

click.linksynergy.com

click.linksynergy.com

click.linksynergy.com

click.linksynergy.com

関連記事

時系列データの分析については、下記の記事でも解説しています。

pydocument.hatenablog.com

pydocument.hatenablog.com

現場ですぐ使える時系列データ分析 データサイエンティストのための基礎知識 [ 横内大介 ]




以上の内容はhttps://pydocument.hatenablog.com/entry/2023/04/03/230137より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14