株価予測(その2)

実行例は「saka.mokumoku」の「Google Colabotry」環境に保存してある

「アップル」の株価を「回帰問題」を使って予測する
  (その2)は行番号20〜43行までを解説する

#
#   1.データの読み込み
#
import pandas as pd
import numpy  as np
import matplotlib.pyplot as plt
import seaborn as sns
#
%matplotlib inline
#
#   2.株価データの取得
#
!pip install pandas_datareader
#
import pandas_datareader.data as dr
#
stock = dr.DataReader('AAPL',"stooq")
print(stock.head())
#
#   3.翌日の高値のフィールドを追加
#
stock['Next_High'] = stock['High'].shift(1)
print(stock.head())
#
print(stock.isnull().sum())
#
stock = stock.dropna()
print(stock.head())
print(stock.shape)
#
#   4.検証、目的変数と説明変数に分割する
#
data_columns = ['Open','High','Low','Close','Volume']
#
test_rows = 500
#
target = stock['Next_High']
data = stock[data_columns]
#
target_train = target[test_rows:]
target_test = target[:test_rows]
data_train = data[test_rows:]
data_test = data[:test_rows]
#
print(data.shape)
print(target.shape)
print(data_train.shape)
print(target_train.shape)
print(data_test.shape)
print(target_test.shape)
#
#   5.線形回帰を使って予測する
#
from sklearn.linear_model import LinearRegression
#
model = LinearRegression()
#
model.fit(data_train,target_train)
#
target_predict = model.predict(data_test)
#
result = pd.DataFrame(target_test)
#
result['predict'] = target_predict
#
sns.lineplot(data=result)
#
sns.lineplot(data=result[:30])

以下はサンプルコードと解説

3.翌日の高値のフィールドを追加

#
stock['Next_High'] = stock['High'].shift(1)
print(stock.head())

 翌日の高値のフィールド(列)を追加する
   前日に翌日の高値を予測したとするフィールドを用意する

 以下のように修正される
   翌日高値(Next_High)に翌日の高値(High)がセットされる

               Open     High       Low   Close      Volume  Next_High
Date                                                                 
2024-05-01  169.580  172.705  169.1100  169.30  50383147.0        NaN
2024-04-30  173.330  174.990  170.0000  170.33  65934776.0    172.705
2024-04-29  173.370  176.030  173.1000  173.50  68169419.0    174.990
2024-04-26  169.880  171.340  169.1800  169.30  44838354.0    176.030
2024-04-25  169.525  170.610  168.1511  169.89  50558329.0    171.340
#
print(stock.isnull().sum())

 欠損値を確認するために中身を出力する
   以下のように表示される

Open         0
High         0
Low          0
Close        0
Volume       0
Next_High    1
dtype: int64

 ”符号あり64ビット整数型”のフィールドで”Next_High”に1個だけ欠損値がある

#
stock = stock.dropna()
print(stock.head())

  欠損値のデータを削除し、整形する
   以下のように表示される、日付が1日ずれた形になる

               Open    High       Low   Close      Volume  Next_High
Date                                                                
2024-04-30  173.330  174.99  170.0000  170.33  65934776.0    172.705
2024-04-29  173.370  176.03  173.1000  173.50  68169419.0    174.990
2024-04-26  169.880  171.34  169.1800  169.30  44838354.0    176.030
2024-04-25  169.525  170.61  168.1511  169.89  50558329.0    171.340
2024-04-24  166.540  169.30  166.2100  169.02  48251835.0    170.610
#
print(stock.shape)

 全体の構造を確認する
   以下のように表示される、1256件で6列のデータ

(1256, 6)

4.検証、目的変数と説明変数に分割する

#
data_columns = ['Open','High','Low','Close','Volume']
#
test_rows = 500
#
target = stock['Next_High']
data = stock[data_columns]
#
target_train = target[test_rows:]
target_test = target[:test_rows]
data_train = data[test_rows:]
data_test = data[:test_rows]

 学習データと検証データとに分ける
   目的変数(target)・・・結果
     翌日高値のデータ1256件、1列
   説明変数(data)・・・原因
     前日までのデータ1256件、5列

   目的変数(target)
     target_train・・・501件目〜1256件目、1列
     target_test・・・先頭〜500件目、1列
   説明変数(data)
     data_train・・・501件目〜1256件目、5列
     data_test ・・・先頭〜500件目、5列

#
print(data.shape)
print(target.shape)
print(data_train.shape)
print(target_train.shape)
print(data_test.shape)
print(target_test.shape)

 分割後のデータ構成を確認する

(1256, 5)
(1256,)
(756, 5)
(756,)
(500, 5)
(500,)

5.線形回帰を使って予測する

#
from sklearn.linear_model import LinearRegression
#
model = LinearRegression()
#
model.fit(data_train,target_train)

 線形回帰を使って機械学習を行う
   ライブラリ「scikit-learn」を呼び出す
   機械学習を行う
     data_train(説明変数、学習用)と
     target_train(目的変数、学習用)を使う

#
target_predict = model.predict(data_test)

 学習したら検証データを使って株価を予測する

#
result = pd.DataFrame(target_test)
#
result['predict'] = target_predict

 検証データの目的変数でデータフレーム作成
   予測結果をとしてデータフレームに追加する

#
sns.lineplot(data=result)
#
sns.lineplot(data=result[:30])

 グラフで可視化する
   通常のグラフと拡大版(30日分)を表示する

実行結果
拡大版

  

6.総括

 全体的にpredict(予測値)はNext-High(翌日高値)の後追いとなる
   前日の株価で翌日の株価を予測しているので、これで正解

 説明変数の選択の結果によって、目的変数は左右されるという
   当たり前の結果となる