Pythonでfbprophetを用いて、株価予測をしてみた③(特徴量の追加編)

機械学習

はじめに

前回、パラメータのチューニングを実施することで、AIモデルの予測精度を向上させることができました。

より精度を向上させるため、株価に影響を与える可能性のある数値を特徴量に取り込むことで、AIモデルの予測精度をより向上できないか。

前回までの特徴量は、「終値」のみです。
AIモデルを構築する際、特徴量にどのようなデータを追加すると予測精度を向上できるのかを調べたところ、「自己回帰データ」と「外部データ」を見つけました。

  • 自己回帰データとは
    先週の終値、昨年同時期の終値など、自己の過去データのこと。
  • 外部データとは
    政治イベント、消費者物価指数、自然災害、円ドル為替、ダウ平均、NASDAQ総合、日経平均、などの外的なデータのこと。

自己回帰の方法については、shift関数やrolling関数を用いて実施します。手順については次回に整理します。今回は、下記の情報をPythonで取得する方法を整理しました。

  • 円ドル為替
  • ダウ平均
  • NASDAQ総合
  • 日経平均

特徴量に追加する情報を取得する

Pythonで円ドル為替、ダウ平均、NASDAQ総合、日経平均を取得する方法は、pandas-datareaderを使用することで可能です。データの取得先はいくつかあります。今回はyahoo financeから取得します。

作成したコードの概要

  • 1~14行目:ライブラリを読み込む
  • 16~18行目:取得開始日と終了日を設定する
  • 20~30行目:円ドル為替、日経平均、NASDAQ総合、ダウ平均を取得してCSVに保存する
  • 36~58行目:取得したデータをグラフで表示する

コード

# Webから情報を取得するためのライブラリを読み込む
import pandas_datareader.data as web

# 時刻を扱うためのライブラリを読み込む
import datetime

# グラフを描画するためのライブラリを読み込む
import matplotlib.pyplot as plt

# グラフで日本語を扱うためのライブラリを読み込む
import japanize_matplotlib

# データフレームを扱うためのライブラリを読み込む
import pandas as pd

# 取得開始日と取得終了日を設定する
start = datetime.date(2015, 1, 1)
end = datetime.date(2020, 12, 31)

# 円ドル為替の時系列データを取得してCSVに保存する
JPY_USD = web.DataReader('JPY=X', 'yahoo', start, end)
JPY_USD.to_csv('./JPY_USD.csv')

# 日経平均株価を取得してCSVに保存する
# ^(チルダ)を付け忘れないこと
N225 = web.DataReader('^N225', 'yahoo', start, end)
N225.to_csv('./N225.csv')

# NASDAQ総合を取得してCSVに保存する
# ^(チルダ)を付け忘れないこと
IXIC = web.DataReader('^IXIC', 'yahoo', start, end)
IXIC.to_csv('./IXIC.csv')

# ダウ平均を取得してCSVに保存する
# ^(チルダ)を付け忘れないこと
DJI = web.DataReader('^DJI', 'yahoo', start, end)
DJI.to_csv('./DJI.csv')

# 取得したデータから終値を抽出する
X1 = JPY_USD['Close']
X2 = N225['Close']
X3 = IXIC['Close']
X4 = DJI['Close']

# 抽出した終値でグラフを作成する
fig = plt.figure()
axes = fig.subplots(2, 2)

axes[0, 0].plot(X1, color='g')
axes[0, 1].plot(X2, color='b')
axes[1, 0].plot(X3, color='k')
axes[1, 1].plot(X4, color='m')

# タイトルを設定する
axes[0, 0].set_title('円ドル為替')
axes[0, 1].set_title('日経平均(N225)')
axes[1, 0].set_title('NASDAQ総合(IXIC)')
axes[1, 1].set_title('ダウ平均(DJI)')

# グラフを表示する
plt.show()

実行結果

コードを作成したフォルダと同じ場所に、取得したデータをCSVファイルで保存します。最後に取得したデータをグラフで表示します。

注意点

yahoo financeからデータを取得した場合、一部のデータが欠損している場合があります。AIモデルを作成する際に使用するアルゴリズムによっては、事前にfillnaメソッドやdropnaメソッドで置き換え、除外を行っておく必要があります。

取得した情報の組み合わせパターンを抽出する

取得した全てのデータを特徴量に追加しても、精度が向上するとは限りません。また、組み合わせによって精度が変わるかもしれません。下記のように取得した全てのデータの組み合わせを探索するコードを作成してみました。

作成したコードの概要

  • 1~5行目:ライブラリを読み込む
  • 7~11行目:組み合わせ対象のリストと組み合わせ結果を保存するリストを用意する
  • 13~19行目:全ての組み合わせパターンを抽出して結果を表示する
  • 22~46行目:抽出した組み合わせの結果を1と0に変換する関数を作成する
  • 48~63行目:1と0に変換する関数を呼び出し、その結果を表示する

コード

# イテレータで全ての組み合わせリストを作成するためのライブラリを読み込む
import itertools

# データフレームを扱うためのライブラリを読み込む
import pandas as pd

# 組み合わせ対象をリストで定義する
lst = ['JPYUSD_f', 'DJI_f', 'IXIC_f', 'N225_f']

# 組み合わせた結果を保存するリストを用意する
result = []

# 全ての組み合わせを作成し、resultに結合する
for n in range(1, len(lst)+1):
    for conb in itertools.combinations(lst, n):
        result.append(list(conb))

# 全ての組み合わせを表示する
print(result)


# 全ての組み合わせリストの要素を1と0に変換する関数を作成する
def convert_onezero(result_lst):
    # 各変数の初期値を0に設定する
    JPYUSD_f = 0
    DJI_f = 0
    IXIC_f = 0
    N225_f = 0

    # result_lstから1行ごとにデータを読み込んで、
    # そのデータの中に、組み合わせ対象が含まれていたら、1を代入する
    for i in range(len(result_lst)):
        if 'JPYUSD_f' in result_lst[i]:
            JPYUSD_f = 1

        if 'DJI_f' in result_lst[i]:
            DJI_f = 1

        if 'IXIC_f' in result_lst[i]:
            IXIC_f = 1

        if 'N225_f' in result_lst[i]:
            N225_f = 1

    lst_tmp = [JPYUSD_f, DJI_f, IXIC_f, N225_f]
    return lst_tmp

# 1と0に変換した結果を代入するデータフレームを用意する
df_result = pd.DataFrame(columns=lst)

# 1と0に変換し、df_resultに結合する
for l in result:
    # 1と0に変換する
    flag = convert_onezero(l)

    # 変換した結果をリストからデータフレームに変換する
    flag = pd.Series(flag, index=lst)

    # df_resultに変換した結果を結合する
    df_result = df_result.append(flag, ignore_index=True)

# 変換した結果を表示する
print(df_result)

実行結果

19行目のprintでitertoolsを用いた全てのパターンを抽出した結果を標準出力します。

[['JPYUSD_f'],
 ['DJI_f'],
 ['IXIC_f'],
 ['N225_f'],
 ['JPYUSD_f', 'DJI_f'],
 ['JPYUSD_f', 'IXIC_f'],
 ['JPYUSD_f', 'N225_f'],
 ['DJI_f', 'IXIC_f'],
 ['DJI_f', 'N225_f'],
 ['IXIC_f', 'N225_f'],
 ['JPYUSD_f', 'DJI_f', 'IXIC_f'],
 ['JPYUSD_f', 'DJI_f', 'N225_f'],
 ['JPYUSD_f', 'IXIC_f', 'N225_f'],
 ['DJI_f', 'IXIC_f', 'N225_f'],
 ['JPYUSD_f', 'DJI_f', 'IXIC_f', 'N225_f']]

63行目のprintで1と0に変換した結果を標準出力します。

   JPYUSD_f DJI_f IXIC_f N225_f
0         1     0      0      0
1         0     1      0      0
2         0     0      1      0
3         0     0      0      1
4         1     1      0      0
5         1     0      1      0
6         1     0      0      1
7         0     1      1      0
8         0     1      0      1
9         0     0      1      1
10        1     1      1      0
11        1     1      0      1
12        1     0      1      1
13        0     1      1      1
14        1     1      1      1

今後の検証について

自己回帰データと取得したデータを含めた特徴量を作成し、AIモデルの作成を行ってみます。

コメント

タイトルとURLをコピーしました