株価データの可視化・テクニカル分析・株価変動予測


Yahooファイナンスより株価をダウンロードし、Sarimaモデル、LSTMモデルで予測してみました。

## 実行環境
Google colab
Mac 

## 参考URL
データ取得
https://note.com/koshikake0124/n/naa843d214eed

SARIMAX
https://note.com/note_kotakota/n/n9f6d7e53c68c

## ステップ
１　データ取得　Yahoo!ファイナンスより　
２　データの前処理　欠損値の処理　正規化 時系列データの成形　
３　時系列データ解析　Sarimaモデル
４　時系列データ解析　LSTM　モデルの評価　RSME　
５　結果の可視化　未来データの予測
６　まとめ　考察

# １　データ取得　Yahoo!ファイナンスより　

```python:１　データ取得　Yahoo!ファイナンスより　

import yfinance as yf
from sklearn.preprocessing import MinMaxScaler

# data = yf.download("1379.T", period="10y")
# data = yf.download("1379.T", start='2018-01-01', end='2024-05-20')
df = yf.download("6758.T", start='2018-01-01', end='2024-05-20', interval='1mo')
```

銘柄コードの後に.Tを入れる決まり。
10年間の期間を指定し、開始と終わりを記入しダウンロード。そのデータを１か月ごとにまとめたものをdfに代入。

# 2データの前処理　欠損値の処理　正規化
```
#欠損データ処理 
df.dropna(inplace=True)

df=df[["Close"]]
```
空欄があるときは削除をする。
終値のみを取り出す処理。

# ３ 時系列データ解析　Sarimaモデル

## SARIMAモデル
SARIMA（Seasonal Autoregressive Integrated Moving Average）モデルは、時系列データの予測や分析に使用される統計モデルです。SARIMAモデルは、ARIMAモデル（Autoregressive Integrated Moving Average）に季節性（Seasonality）の要素を追加したものです。
SARIMAモデルは主に以下の要素で構成されます：

```python:３　時系列データ解析　Sarimaモデル
import warnings
import itertools
import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
%matplotlib inline


# orderの最適化関数
def selectparameter(DATA, s):
    p = d = q = range(0, 2)
    pdq = list(itertools.product(p, d, q))
    seasonal_pdq = [(x[0], x[1], x[2], s) for x in list(itertools.product(p, d, q))]
    parameters = []
    BICs = np.array([])
    for param in pdq:
        for param_seasonal in seasonal_pdq:
            try:
                mod = sm.tsa.statespace.SARIMAX(DATA,
                                                order=param,
                                                seasonal_order=param_seasonal)
                results = mod.fit()
                parameters.append([param, param_seasonal, results.bic])
                BICs = np.append(BICs, results.bic)
            except:
                continue
    return parameters[np.argmin(BICs)]

# SARIMAモデルを用いて時系列解析
# 周期は月ごとのデータであることも考慮してs=12となります
# orderはselectparameter関数の0インデックス, seasonal_orderは1インデックスに格納されています
best_params = selectparameter(df, 12)
SARIMA_model = sm.tsa.statespace.SARIMAX(df, order=best_params[0],
                                             seasonal_order=best_params[1],
                                             enforce_stationarity=False, enforce_invertibility=False).fit()
```

##  SARIMAモデルの評価
```python:SARIMAモデルの評価
# 予測
# predに予測期間での予測値を代入
pred = SARIMA_model.predict('2018-01-01', '2028-05-20')
```

```python:予測
# グラフを可視化
plt.plot(df, label='Actual value', color="blue")
plt.plot(pred, label='prediction value', color="red")

plt.legend()
plt.show()
```
## 結果
![Sarimamモデル結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795128/95b200a2-2282-5454-1ef8-3c4905986434.png)

# 4時系列データ解析　LSTM　モデルの評価　RSME　

LSTM（Long Short-Term Memory）は、再帰型ニューラルネットワーク（RNN）の一種で、長期と短期の記憶を効果的に扱うことができる特殊な構造のニューラルネットワークです。LSTMは時系列データやテキストデータなど、連続した系列データを扱う際に主に使用されます。

```python:4　時系列データ解析　LSTM
#必要なライブラリをインポート
from sklearn.preprocessing import MinMaxScaler

#　Closeコラムのみ抽出
data = df.filter(["Close"])
dataset = data.values

#　データの正規化
scaler = MinMaxScaler(feature_range=(0,1))
scaled_data = scaler.fit_transform(dataset)
scaled_data

# データを訓練データと検証データに分割し、7割を訓練用に設定
training_data_len = int(np.ceil(len(dataset) * 0.7))
training_data_len

train_data = scaled_data[0: int(training_data_len), :]
train_data.shape

#訓練データの取得
x_train = []
y_train = []
for i in range(3, len(train_data)):
    x_train.append(train_data[i-3:i,0])
    y_train.append(train_data[i,0])

# 訓練データのreshape
x_train, y_train = np.array(x_train), np.array(y_train)
x_train = np.reshape(x_train,(x_train.shape[0], x_train.shape[1], 1))
x_train.shape

# kerasから必要なライブラリを導入
from keras.models import Sequential
from keras.layers import Dense, LSTM

#LSTMモデル構築
model = Sequential()
model.add(LSTM(128,return_sequences = True, input_shape=(x_train.shape[1], 1)))
model.add(LSTM(64, return_sequences = False))
model.add(Dense(25))
model.add(Dense(1))
model.compile(optimizer='adam',loss='mean_squared_error')

#訓練用モデル構築
model.fit(x_train, y_train, batch_size = 1, epochs =1)

# 検証用データの取得とデータ変換
test_data = scaled_data[training_data_len - 3: , :]
x_test = []
for i in range(3, len(test_data)):
   x_test.append(test_data[i-3:i,0])
y_test = dataset[training_data_len:, :]

x_test = np.array(x_test)
x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1],1))
```

##  LSTMの評価
```python:LSTMの評価
# 予測値の算出
predictions = model.predict(x_test)
predictions = scaler.inverse_transform(predictions)
```

## RSME

RMSE（Root Mean Squared Error）とは、回帰問題においてモデルの予測精度を評価するための指標の一つです。具体的には、実際の値と予測値の間の差の二乗平均平方根を計算したものです。
RMSEを計算する手順は以下の通りです：
1. 各データポイントでの予測値と実測値の差を計算します。
2. それぞれの差を二乗して、その合計を求めます。
3. その合計をデータの個数（サンプル数）で割り、平均を計算します。
4. その平均の平方根をとったものがRMSEとなります。
RMSEは、予測値が実際の値とどれだけズレているかを示す指標であり、値が小さいほど予測精度が高いことを表します。一般的に、RMSEが小さいほどモデルの予測精度が高いと評価されます。

```python:４　時系列データ解析　RSME　
# RMSEを利用して予測精度を確認
from sklearn.metrics import mean_squared_error
test_score = np.sqrt(mean_squared_error(y_test,predictions))
print('Test Score: %.2f RMSE' % (test_score))

train = data[: training_data_len]
valid = data[training_data_len:]
valid['Predictions'] = predictions
```

```python:予測
# グラフを可視化
plt.figure(figsize = (16,6))
plt.grid()
plt.title('<Kobayashi Pharmaceutical> LSTM Model')
plt.xlabel('Date', fontsize =18)
plt.ylabel('Close Price', fontsize =18)
plt.plot(train['Close'],color="g")
plt.plot(valid[['Close','Predictions']])
plt.legend(['Train','Real','Prediction'], loc='upper right')
plt.show()
```
## 結果
![LSTM結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795128/aeadf21c-364a-6389-9cb3-73d87cb2f716.png)

## ６　まとめ　考察
一通りのSARIMAモデル、LSTMを用いた株価予測ができた。他の分析方法での比較や、データの調整もしてみたいと思った。