[PYTHON] Prédiction de la moyenne Nikkei avec Pytorch

Je suis un étudiant diplômé étudiant Pytorch récemment.

J'ai commencé à étudier les réseaux de neurones en rêvant de prévisions de cours boursiers et de prévisions de courses de chevaux.

Enfin, il a pris forme, je vais donc l'écrire sous forme de mémorandum. J'espère que cela sera utile pour les débutants comme moi.

Références, articles et livres cités

Présentation du réseau LSTM Ceci est un article sur la structure et le mécanisme du réseau de LSTM.

Je veux commencer avec LSTM avec pytorch ... tu ne veux pas? Il s'agit principalement de savoir comment implémenter LSTM.

Prédiction FX: Prédiction des données de séries temporelles avec le LSTM de PyTorch Cela a été très utile parce que j'ai écrit en détail comment collecter des données, le moulage, le backtesting et l'apprentissage réel.

Modèle de prévision du cours des actions d'apprentissage en profondeur _1 avec une précision de 67% Ce n'est pas FX, je prédisais le cours de l'action, et il correspondait à la prévision du lendemain que je voulais, alors j'y ai fait référence. Ceci est implémenté dans keras, mais je vais l'implémenter dans pytorch.

[Minna no python 4e édition](https://www.amazon.co.jp/%E3%81%BF%E3%82%93%E3%81%AA%E3%81%AEPython-%E7%AC% AC4% E7% 89% 88-% E6% 9F% B4% E7% 94% B0-% E6% B7% B3 / dp / 479738946X / ref = sr_1_1? __Mk_ja_JP =% E3% 82% AB% E3% 82% BF % E3% 82% AB% E3% 83% 8A & mots-clés =% E3% 81% BF% E3% 82% 93% E3% 81% AA% E3% 81% AEpython & qid = 1580280858 & sr = 8-1) C'est le livre que j'ai utilisé pour découvrir l'utilisation de base de python.

Collecte de données

Les données ont été collectées à l'aide d'HYPER SBI, qui peut être téléchargée sur SBI Securities. Dans Deep Learning Stock Price Prediction Model_1 with 67% Precuracy, nous avons appris les cours des actions de 423 sociétés cotées pendant 20 ans. Donc, tout d'abord, j'ai appris s'il fallait remonter le lendemain uniquement avec la moyenne Nikkei. Les données sont pour 20 ans.

Aperçu

Nous avons collecté des données pendant 20 ans et les avons formées séparément pour la formation et le test. La précision du test ~~ a enregistré 62,5%. Cependant, il existe des problèmes tels que la perte ne converge pas et la valeur de f1 calculée à partir de la matrice mixte devient 0 pendant l'apprentissage. ~~

Finalement, il s'est établi à Accuracy 60,5%.

Définition de constante

main.py


import glob
import pandas as pd
import numpy as np
import torch
import torch.nn as nn
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
import torch.nn.functional as F
import torch.optim as optim

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
torch.manual_seed(1)

future_num = 1 #Combien de jours à venir
feature_num = 7 #'Prix ouvert', 'Prix élevé','Bas prix','le dernier prix','Moyenne sur 5 jours','2Moyenne sur 5 jours','7Moyenne sur 5 jours'7 éléments
batch_size = 128

time_steps = 30 #pas de temps lstm
moving_average_num = 30 #Nombre de jours pour prendre une moyenne mobile
n_epocs = 50

lstm_hidden_dim = 16
target_dim = 1

Lire les données

Pour collecter des données, consultez le Site Web officiel du SBI: Foire aux questions et questions-réponses. J'ai sélectionné l'index ici et téléchargé les données moyennes Nikkei pendant 20 ans.

main.py


path = "./data/nikkei_heikin.csv"

model_name = "./models/nikkei.mdl"

#data load
flist = glob.glob(path)
for file in flist:
    df = pd.read_csv(file, header=0, encoding='cp932')
    dt = pd.read_csv(file, header=0, encoding='cp932')


#Données de train,Index à diviser en test
val_idx_from = 3500
test_idx_from = 4000

future_price = df.iloc[future_num:]['le dernier prix'].values
curr_price = df.iloc[:-future_num]['le dernier prix'].values

#future_Traitez le prix par rapport à num jours plus tard comme l'étiquette correcte
y_data_tmp = future_price / curr_price
#Préparez une liste pour l'étiquette de réponse correcte
y_data = np.zeros_like(y_data_tmp)

#Avenir à prévoir_Bonne réponse si le nombre de jours plus tard est supérieur au jour précédent

for i in range(len(y_data_tmp)):
    if y_data_tmp[i] > 1.0:
        y_data[i] = 1

#Se déplacer lorsque le prix est normalisé_average_Étant donné que les données vides sont créées pendant num minutes, cette partie est supprimée.
y_data = y_data[moving_average_num:]

#Normalisation des prix
#Obtenir le nom de la colonne
cols = ['Prix ouvert', 'Prix élevé','Bas prix','le dernier prix','Moyenne sur 5 jours','2Moyenne sur 5 jours','7Moyenne sur 5 jours']
#Je l'ai retiré parce que les données de volume étaient endommagées.

for col in cols:
    dt[col] = df[col].rolling(window=25, min_periods=25).mean()
    df[col] = df[col] / dt[col] - 1
    

X_data = df.iloc[moving_average_num:-future_num][cols].values

#Données fractionnées, converties en Torch Tensor
#Données d'entraînement
X_train = torch.tensor(X_data[:val_idx_from], dtype=torch.float, device=device)
y_train = torch.tensor(y_data[:val_idx_from], dtype=torch.float, device=device)
#Données d'évaluation
X_val   = torch.tensor(X_data[val_idx_from:test_idx_from], dtype=torch.float, device=device)
y_val   = y_data[val_idx_from:test_idx_from]
#Données de test
X_test  = torch.tensor(X_data[test_idx_from:], dtype=torch.float, device=device)
y_test  = y_data[test_idx_from:]

Le nombre initial de données était d'environ 4500. Le nombre de données d'entraînement est de 3500, la validation est de 500 et le reste est constitué de données de test.

Définition du modèle

main.py


class LSTMClassifier(nn.Module):
    def __init__(self, lstm_input_dim, lstm_hidden_dim, target_dim):
        super(LSTMClassifier, self).__init__()
        self.input_dim = lstm_input_dim
        self.hidden_dim = lstm_hidden_dim
        self.lstm = nn.LSTM(input_size=lstm_input_dim, 
                            hidden_size=lstm_hidden_dim,
                            num_layers=1, #default
                            #dropout=0.2,
                            batch_first=True
                            )
        self.dense = nn.Linear(lstm_hidden_dim, target_dim)

    def forward(self, X_input):
        _, lstm_out = self.lstm(X_input)
        #Utilisez uniquement la sortie finale de LSTM.
        linear_out = self.dense(lstm_out[0].view(X_input.size(0), -1))
        return torch.sigmoid(linear_out)

La définition du modèle. J'ai extrait LSTM de la bibliothèque de Pytorch.

main.py


def prepare_data(batch_idx, time_steps, X_data, feature_num, device):
    feats = torch.zeros((len(batch_idx), time_steps, feature_num), dtype=torch.float, device=device)
    for b_i, b_idx in enumerate(batch_idx):
        #Stockez les 30 derniers jours sous forme de données de pas de temps.
        b_slc = slice(b_idx + 1 - time_steps ,b_idx + 1)
        feats[b_i, :, :] = X_data[b_slc, :]

    return feats

La fonction prepare_data joue un rôle de collecte des données à entrer dans LSTM pendant 30 jours chacune.

Apprentissage et évaluation

main.py


#Apprentissage
model = LSTMClassifier(feature_num, lstm_hidden_dim, target_dim).to(device)
loss_function = nn.BCELoss()
optimizer= optim.Adam(model.parameters(), lr=1e-4)


train_size = X_train.size(0)
best_acc_score = 0

for epoch in range(n_epocs):
    #Remplacez au hasard l'index des données du train. Première fois_N'utilisez pas d'étapes.
    perm_idx = np.random.permutation(np.arange(time_steps, train_size))
    for t_i in range(0, len(perm_idx), batch_size):
        batch_idx = perm_idx[t_i:(t_i + batch_size)]
        #Préparation des données de séries chronologiques pour l'entrée LSTM
        feats = prepare_data(batch_idx, time_steps, X_train, feature_num, device)
        y_target = y_train[batch_idx]
        model.zero_grad()
        train_scores = model(feats) # batch size x time steps x feature_num
        loss = loss_function(train_scores, y_target.view(-1, 1))
        loss.backward()
        optimizer.step()

    #Évaluation des données de validation
    print('EPOCH: ', str(epoch), ' loss :', loss.item())
    with torch.no_grad():
        feats_val = prepare_data(np.arange(time_steps, X_val.size(0)), time_steps, X_val, feature_num, device)
        val_scores = model(feats_val)
        tmp_scores = val_scores.view(-1).to('cpu').numpy()
        bi_scores = np.round(tmp_scores)
        acc_score = accuracy_score(y_val[time_steps:], bi_scores)
        roc_score = roc_auc_score(y_val[time_steps:], tmp_scores)
        f1_scores = f1_score(y_val[time_steps:], bi_scores)
        print('Val ACC Score :', acc_score, ' ROC AUC Score :', roc_score, 'f1 Score :', f1_scores)

    #Enregistrer le modèle si la validation est bonne
    if acc_score > best_acc_score:
        best_acc_score = acc_score
        torch.save(model.state_dict(),model_name)
        print('best score updated, Pytorch model was saved!!', )

#Prédisez avec le meilleur modèle.
model.load_state_dict(torch.load(model_name))

with torch.no_grad():
    feats_test = prepare_data(np.arange(time_steps, X_test.size(0)), time_steps, X_test, feature_num, device)
    val_scores = model(feats_test)
    tmp_scores = val_scores.view(-1).to('cpu').numpy()   
    bi_scores = np.round(tmp_scores)
    acc_score = accuracy_score(y_test[time_steps:], bi_scores)
    roc_score = roc_auc_score(y_test[time_steps:], tmp_scores)
    f1_scores = f1_score(y_test[time_steps:], bi_scores)
    print('Test ACC Score :', acc_score, ' ROC AUC Score :', roc_score, 'f1 Score :', f1_scores)

Dans l'apprentissage, la précision, le score ROC et le score f1 sont générés. Les poids sont enregistrés lorsque la précision la plus élevée est mise à jour.

résultat

EPOCH:  0  loss : 0.7389694452285767
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5448111497752646 f1 Score : 0.653295128939828
best score updated, Pytorch model was saved!!
EPOCH:  1  loss : 0.6844338178634644
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5550601710888793 f1 Score : 0.653295128939828
EPOCH:  2  loss : 0.7206816673278809
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5678012179208352 f1 Score : 0.653295128939828
EPOCH:  3  loss : 0.7066923975944519
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5815934464259822 f1 Score : 0.653295128939828
EPOCH:  4  loss : 0.7148252129554749
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.6025717703349283 f1 Score : 0.653295128939828
EPOCH:  5  loss : 0.6946689486503601
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.6224264172828766 f1 Score : 0.653295128939828
EPOCH:  6  loss : 0.7018400430679321
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.639100333478324 f1 Score : 0.653295128939828
EPOCH:  7  loss : 0.7006129026412964
.
.
.
.
EPOCH:  43  loss : 0.7038401961326599
Val ACC Score : 0.5148936170212766  ROC AUC Score : 0.6018921270117442 f1 Score : 0.0
EPOCH:  44  loss : 0.6951379179954529
Val ACC Score : 0.5148936170212766  ROC AUC Score : 0.6018921270117443 f1 Score : 0.0
EPOCH:  45  loss : 0.6788191795349121
Val ACC Score : 0.5148936170212766  ROC AUC Score : 0.6018921270117443 f1 Score : 0.0
EPOCH:  46  loss : 0.6547065377235413
Val ACC Score : 0.5148936170212766  ROC AUC Score : 0.6018558793678411 f1 Score : 0.0
EPOCH:  47  loss : 0.6936472654342651
Val ACC Score : 0.5148936170212766  ROC AUC Score : 0.6016746411483254 f1 Score : 0.0
EPOCH:  48  loss : 0.719009280204773
Val ACC Score : 0.5148936170212766  ROC AUC Score : 0.6016202696824707 f1 Score : 0.0
EPOCH:  49  loss : 0.6854437589645386
Val ACC Score : 0.5148936170212766  ROC AUC Score : 0.6014934029288096 f1 Score : 0.0
Test ACC Score : 0.6252100840336134  ROC AUC Score : 0.6860275646683414 f1 Score : 0.6915629322268327

Postscript

Si vous changez le nombre d'époques de 50 à 500, la perte sera un nombre décent, je vais donc l'afficher.

EPOCH:  0  loss : 0.7389694452285767
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5448111497752646 f1 Score : 0.653295128939828
best score updated, Pytorch model was saved!!
EPOCH:  1  loss : 0.6844338178634644
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5550601710888793 f1 Score : 0.653295128939828
EPOCH:  2  loss : 0.7206816673278809
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5678012179208352 f1 Score : 0.653295128939828
EPOCH:  3  loss : 0.7066923975944519
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.5815934464259822 f1 Score : 0.653295128939828
EPOCH:  4  loss : 0.7148252129554749
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.6025717703349283 f1 Score : 0.653295128939828
EPOCH:  5  loss : 0.6946689486503601
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.6224264172828766 f1 Score : 0.653295128939828
EPOCH:  6  loss : 0.7018400430679321
Val ACC Score : 0.4851063829787234  ROC AUC Score : 0.639100333478324 f1 Score : 0.653295128939828
EPOCH:  7  loss : 0.7006129026412964
.
.
.
.
EPOCH:  493  loss : 0.694491982460022
Val ACC Score : 0.6042553191489362  ROC AUC Score : 0.638157894736842 f1 Score : 0.5079365079365079
EPOCH:  494  loss : 0.6935185194015503
Val ACC Score : 0.6063829787234043  ROC AUC Score : 0.638157894736842 f1 Score : 0.5144356955380578
EPOCH:  495  loss : 0.6262539029121399
Val ACC Score : 0.5957446808510638  ROC AUC Score : 0.6370704654197477 f1 Score : 0.48087431693989063
EPOCH:  496  loss : 0.5570085644721985
Val ACC Score : 0.6085106382978723  ROC AUC Score : 0.6387559808612441 f1 Score : 0.5422885572139303
EPOCH:  497  loss : 0.6102970838546753
Val ACC Score : 0.6  ROC AUC Score : 0.6374691895026823 f1 Score : 0.4973262032085562
EPOCH:  498  loss : 0.6443783640861511
Val ACC Score : 0.6042553191489362  ROC AUC Score : 0.6395534290271132 f1 Score : 0.5633802816901409
EPOCH:  499  loss : 0.663628876209259
Val ACC Score : 0.6085106382978723  ROC AUC Score : 0.6380310279831811 f1 Score : 0.518324607329843
Test ACC Score : 0.6050420168067226  ROC AUC Score : 0.644737139882771 f1 Score : 0.660894660894661

Prise en compte des résultats

~~ Si vous regardez au milieu de l'apprentissage, il arrive souvent que la précision ne soit pas mise à jour. Et le score f1 est égal à 0. Il semble qu'il existe de nombreux problèmes tels que la perte de non convergence. Cependant, en regardant les résultats des données de test, nous avons enregistré une précision de 62,5%. ~~

En augmentant le nombre d'époques, le score ROC et le score f1 sont décents. Cependant, la précision elle-même est devenue 60,5%.

Je souhaite améliorer la précision en augmentant le nombre de données et la quantité de fonctionnalités, et en implémentant le LSTM par moi-même.

La prochaine fois, nous prédirons les actions qui augmenteront de 3%, comme cela a été fait dans Deep Learning Stock Price Forecast Model_1 with 67% Precuracy.

Recommended Posts

Prédiction de la moyenne Nikkei avec Pytorch 2
Prédiction de la moyenne Nikkei avec Pytorch
Prédiction de la moyenne Nikkei avec Pytorch ~ Makuma ~
Prédiction des ondes de Sin (retour) avec Pytorch
4/22 prédiction de l'onde de péché avec keras
Classification multi-étiquette d'images multi-classes avec pytorch
Validation croisée avec PyTorch
À partir de PyTorch
Histoire d'essayer d'utiliser Tensorboard avec Pytorch
Utilisez RTX 3090 avec PyTorch
Installer la diffusion de la torche avec PyTorch 1.7
[PyTorch] Un peu de compréhension de CrossEntropyLoss avec des formules mathématiques
Résumé des problèmes lors de la segmentation sémantique avec Pytorch
Préparation de l'environnement d'exécution de PyTorch avec Docker Novembre 2019
[PyTorch] Classification des images du CIFAR-10
Sauvegardez la sortie de GAN une par une ~ Avec l'implémentation de GAN par PyTorch ~
Essayez Auto Encoder avec Pytorch
Equation de mouvement avec sympy
Essayez d'implémenter XOR avec PyTorch
Implémenter le GPU PyTorch + avec Docker
Traitement parallèle avec Parallel de scikit-learn
Démineur d'apprentissage automatique avec PyTorch
PyTorch avec AWS Lambda [importation Lambda]
Souvenirs de combats avec Selenium
Gratter la moyenne du Nikkei avec le dramaturge-python
Effectuer un fractionnement stratifié avec PyTorch
J'ai créé Word2Vec avec Pytorch
Prédiction de probabilité de données déséquilibrées
Calcul sans erreur avec le big.Float de Golang
Prédiction de séries chronologiques facile avec Prophet
Jugement de vacances, y compris les vacances avec bash
[Tutoriel PyTorch ⑤] Apprentissage de PyTorch avec des exemples (Partie 2)
Résumé de l'implémentation de base par PyTorch
Apprenez avec les réseaux convolutifs PyTorch Graph
Premiers pas avec Python Bases de Python
J'ai essayé d'implémenter DeepPose avec PyTorch
Jeu de vie avec Python! (Le jeu de la vie de Conway)
Automatisation des opérations à distance avec Fabric
Comment augmenter les données avec PyTorch
4ème nuit de boucle avec pour
Principes de base pour toucher MongoDB avec MongoEngine
[Tutoriel PyTorch ⑤] Apprentissage de PyTorch avec des exemples (Partie 1)
Traduction japonaise appropriée de pytorch tensor_tutorial
Implémentation de la méthode Dyxtra par python
Construction de l'environnement pytorch @ python3.8 avec pipenv
Coexistence de Python2 et 3 avec CircleCI (1.0)
Obtenez un rembourrage de réflexion Pytorch avec Tensorflow
Application de graphiques avec des curseurs
Etude de base d'OpenCV avec Python
Une collection de conseils pour accélérer l'apprentissage et le raisonnement avec PyTorch