[sktime] 株価予測AIを作るまで:その② 単回帰分析

2021年12月7日火曜日

Artificial Intelligence

一つ一つ順を追っていきながら機械学習を使った株価予測モデルを作っていきます。
本記事では、Sktimeを使って株価データから単回帰分析を行ってみます。

アイキャッチ

概要

以下の記事で、時系列データに特化した機械学習ライブラリSktimeの導入、及び、yahoo_finance_api2を用いた日本株データ取得を行いました。

本記事では、その続きとして単回帰分析を行っていきたいと思います。

単回帰分析とは

数多の解説記事が存在するため詳細な説明は省きますが、一言でいえば1 つの入力変数から 1 つの出力変数を予測することです。

今回は、株価の過去の終値を入力に将来の終値を予測してみます。
なお本記事で紹介するソースコードはこちらのGithubに全て載せています

免責事項
本記事は、機械学習、AIの学習を目的としており、投資を薦めるものではありません。
本記事の内容を基に投資を行って生じる、いかなる損失も本記事は一切の責任を負いません。

なお、このデモはPythonで実装しています。
Pythonの実装に不安がある方、Pythonを使った機械学習について詳しく勉強したい方は、以下の書籍やオンライン講座などがおすすめです。

データの前処理

今回は初歩としてyahoo_finance_api2から取得した株価データからtimestampとclose(取引日時と終値)のみを抽出します。

必要なモジュールをインポートします。

# file: stock_simple_regression.ipynb

import sys
import os
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError
import pandas as pd
import numpy as np
import pickle

from sktime.utils.plotting import plot_series
from sktime.forecasting.model_selection import temporal_train_test_split
from sktime.forecasting.base import ForecastingHorizon

from sktime.forecasting.theta import ThetaForecaster
from sktime.performance_metrics.forecasting import mean_absolute_percentage_error

次に、yahoo_finance_api2から取得したデータを整形する関数を定義します。
処理概要はDataFrameに格納し、timestampをUTC時間に変換しています。

def data_shaping(symbol_data):
    '''
    yahoo_finance_api2のdataをDataFrameに整形
    '''
    
    # DataFrameに初期化
    df_symbol_data = pd.DataFrame(symbol_data)

    # UNIX時間をUTC時間に変換
    df_symbol_data.timestamp = pd.to_datetime(df_symbol_data.timestamp, unit='ms')
    
    return df_symbol_data

任天堂の株価を5年分取得します。

my_share = share.Share('7974.T') # 東京証券の証券コード指定:任天堂

symbol_data = None

try:
    # 5年分を1日間隔で取得
    symbol_data = my_share.get_historical(share.PERIOD_TYPE_YEAR,
    5,
    share.FREQUENCY_TYPE_DAY,
    1)
except YahooFinanceError as e:
    print(e.message)
    sys.exit(1)

# Dataframeに整形
df_symbol_data = data_shaping(symbol_data)

df_symbol_data
任天堂の株価データ

DataFrameから今回の単回帰分析に使用するtimestampとcloseを抽出します。
またtimestampをPeriodIndexに変更します。

# 取引日と終値のみのSeriesを生成
target = df_symbol_data['close']
index = df_symbol_data['timestamp']
target.index = pd.PeriodIndex(index, freq="D")

target
任天堂株価の単回帰分析用データ

ここまでの前処理結果をグラフで表示します。 from sktime.utils.plotting import plot_seriesを使用すると簡単に表示できます。

# 棒グラフにプロット
plot_series(target)
単回帰分析用データの棒グラフ

最後に、このデータを学習データとテストデータに分割します。今回は、対象データの5%をテストデータとして利用します。

# targetの5%をtestデータに分割
y_train, y_test = temporal_train_test_split( target,test_size=int(len(target) * 0.05) )
# グラフ化
plot_series(y_train, y_test, labels=["y_train", "y_test"])
単回帰分析用データの棒グラフ分割後

青色で表されている箇所が学習データ、オレンジで表されている箇所がテストデータです。
可視化が楽にできると理解しやすく非常に助かります。

モデルのトレーニング

今回はシータ法を用いてモデルをトレーニングしてみます。
シータ法は、ドリフト付きの単純指数平滑化を用いた手法です。詳細はこちらの書籍などが最も詳細に記載していそうですが、 日本語版の書籍が欲しいですね。

それではモデルを構築し、学習させてみます。

# ThetaForecasterモデル
# 季節性の考慮なし
model_name = './models/stock_close_simple_regression_theta.pkl'

if os.path.exists(model_name):
    print("Already exists model", model_name)
    with open(model_name, 'rb') as f:
        forecaster = pickle.load(f)
else:
	# ThetaForecasterモデル定義
    forecaster = ThetaForecaster()
    # トレーニング
    forecaster.fit(y_train)
    # save model
    with open(model_name,'wb') as f:
        pickle.dump(forecaster,f)
    print("save model", model_name)

stock_close_simple_regression_theta.pklが出力されました。
環境にもよりますが、学習自体は1分もたたずに終了しました。

予測(Forecast)

トレーニングによって作成したモデルを使ってテストデータ期間の終値を予測してみたいと思います。
まず、予測期間を示すForecastingHorizonを定義します。

# forecasting horizon
fh = ForecastingHorizon(
    y_test.index, is_relative=False
)
fh
予測期間の定義

予測していきます。

# 予測
y_pred = forecaster.predict(fh)
# 予測結果のグラフ化
plot_series(y_train.tail(100), y_test, y_pred, labels=["y_train", "y_test", "y_pred"])
予測結果

予測結果は上図のようになりました。直近10日ほどの上昇傾向は予測できていますが、以降の予測は全く予測できていませんね。
学習データの日付から離れれば離れるほど予測精度が悪くなっているようです。
精度向上のためには、他の説明変数などを追加する必要がありそうです。

モデルの評価

最後に生成したモデルの評価を行います。
今回はMAPE(平均絶対パーセント誤差)を用います。ざっくりというと誤差の割合であるため算出結果は少ないほど精度が高いことを示しています。

# 精度検証: MAPE(平均絶対パーセント誤差)
mean_absolute_percentage_error(y_test, y_pred)

出力結果は0.07561995411730185となりました。

まとめ

本記事では、SktimeのThetaForecasterを使用して株価の終値を単回帰分析を実施してみました。
筆者自身勉強中の身であるためご指摘事項等あれば、コメント頂けると幸いです。
また今後は重回帰分析や特徴量エンジニアリングに取り組みたいと思います。

AIで副業ならココから!

まずは無料会員登録

プロフィール

メーカーで研究開発を行う現役エンジニア
組み込み機器開発や機会学習モデル開発に従事しています

本ブログでは最新AI技術を中心にソースコード付きでご紹介します


Twitter

カテゴリ

このブログを検索

ブログ アーカイブ

TeDokology