Prédiction du Cours des actions à l’aide de Techniques d’Apprentissage Automatique et d’Apprentissage Profond (avec des codes Python)

Introduction

Prédire les performances du marché boursier est l’une des choses les plus difficiles à faire. Il y a tellement de facteurs impliqués dans la prédiction – facteurs physiques vs comportement physhologique, rationnel et irrationnel, etc. Tous ces aspects se combinent pour rendre les cours des actions volatils et très difficiles à prévoir avec un haut degré de précision.

Pouvons-nous utiliser l’apprentissage automatique comme un changeur de jeu dans ce domaine? En utilisant des fonctionnalités telles que les dernières annonces concernant une organisation, leurs résultats trimestriels, etc., les techniques d’apprentissage automatique ont le potentiel de déterrer des modèles et des idées que nous n’avions pas vus auparavant, et celles-ci peuvent être utilisées pour faire des prédictions infaillibles.

 prévision du cours des actions, LSTM, apprentissage automatique

Dans cet article, nous allons travailler avec des données historiques sur les cours des actions d’une société cotée en bourse. Nous allons implémenter un mélange d’algorithmes d’apprentissage automatique pour prédire le cours futur de l’action de cette société, en commençant par des algorithmes simples comme la moyenne et la régression linéaire, puis passer à des techniques avancées comme Auto ARIMA et LSTM.

L’idée centrale derrière cet article est de montrer comment ces algorithmes sont implémentés. Je décrirai brièvement la technique et fournirai des liens pertinents pour approfondir les concepts au besoin. Si vous êtes un nouveau venu dans le monde des séries chronologiques, je suggère de passer d’abord par les articles suivants:

  • Un guide complet du débutant pour créer une Prévision de Séries Chronologiques
  • Un Tutoriel Complet sur la Modélisation de Séries Chronologiques
  • Cours gratuit: Prévision de Séries Chronologiques en utilisant Python

Projet de mise en pratique de la prévision des séries chronologiques

Prévision des séries chronologiques & la modélisation joue un rôle important dans l’analyse des données. L’analyse des séries chronologiques est une branche spécialisée de la statistique largement utilisée dans des domaines tels que l’économétrie & La recherche opérationnelle.

Les séries chronologiques sont largement utilisées en analyse & science des données. Il s’agit d’un problème de série chronologique spécialement conçu pour vous et le défi consiste à prévoir le trafic.

Pratiquez maintenant

Êtes-vous un débutant à la recherche d’un endroit pour commencer votre voyage en science des données? Présenter un cours complet, plein de connaissances et d’apprentissage de la science des données, organisé juste pour vous! Ce cours couvre tout, des bases de l’apprentissage automatique aux concepts avancés de ML, d’apprentissage en profondeur et de séries chronologiques.

  • AI certifié & ML Ceinture noire + Programme

Table des matières

    1. Comprendre l’énoncé du problème
    2. Moyenne mobile
    3. Régression linéaire
    4. k – Voisins les plus proches
    5. ARIMA automatique
    6. Prophète
    7. Mémoire à long terme à court terme (LSTM)

Comprendre l’énoncé du problème

Nous nous plongerons bientôt dans la partie mise en œuvre de cet article, mais il est d’abord important d’établir ce que nous visons à résoudre. De manière générale, l’analyse boursière est divisée en deux parties: L’Analyse fondamentale et l’Analyse technique.

  • L’analyse fondamentale consiste à analyser la rentabilité future de l’entreprise sur la base de son environnement commercial actuel et de sa performance financière.
  • L’analyse technique, en revanche, comprend la lecture des graphiques et l’utilisation de chiffres statistiques pour identifier les tendances du marché boursier.

Comme vous l’avez peut-être deviné, nous nous concentrerons sur la partie analyse technique. Nous utiliserons un ensemble de données de Quandl (vous pouvez trouver des données historiques pour divers stocks ici) et pour ce projet particulier, j’ai utilisé les données pour ‘Tata Global Beverages’. Il est temps de plonger!

Remarque: Voici l’ensemble de données que j’ai utilisé pour le code: Télécharger

Nous allons d’abord charger l’ensemble de données et définir la variable cible du problème:

#import packagesimport pandas as pdimport numpy as np#to plot within notebookimport matplotlib.pyplot as plt%matplotlib inline#setting figure sizefrom matplotlib.pylab import rcParamsrcParams = 20,10#for normalizing datafrom sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler(feature_range=(0, 1))#read the filedf = pd.read_csv('NSE-TATAGLOBAL(1).csv')#print the headdf.head()

Il existe plusieurs variables dans l’ensemble de données – date, ouverture, haut, bas, dernier, fermeture, total_trade_quantité et chiffre d’affaires.

  • Les colonnes Ouvrir et Fermer représentent le prix de départ et le prix final auquel l’action est négociée un jour donné.
  • Haut, Bas et Dernier représentent le maximum, le minimum et le dernier prix de l’action pour la journée.
  • La quantité totale de transactions est le nombre d’actions achetées ou vendues dans la journée et le chiffre d’affaires (Lacs) est le chiffre d’affaires de la société donnée à une date donnée.

Une autre chose importante à noter est que le marché est fermé le week-end et les jours fériés.Notez à nouveau le tableau ci-dessus, certaines valeurs de date sont manquantes – 2/10/2018, 6/10/2018, 7/10/2018. Parmi ces dates, la 2e est une fête nationale tandis que les 6e et 7e tombent un week-end.

Le calcul du résultat est généralement déterminé par le cours de clôture d’une action pour la journée, nous considérerons donc le cours de clôture comme la variable cible. Tracons la variable cible pour comprendre comment elle se forme dans nos données:

#setting index as datedf = pd.to_datetime(df.Date,format='%Y-%m-%d')df.index = df#plotplt.figure(figsize=(16,8))plt.plot(df, label='Close Price history')

Dans les prochaines sections, nous explorerons ces variables et utiliserons différentes techniques pour prédire le cours de clôture quotidien de l’action.

Moyenne mobile

Introduction

La « moyenne » est facilement l’une des choses les plus courantes que nous utilisons dans notre vie quotidienne. Par exemple, calculer les notes moyennes pour déterminer la performance globale, ou trouver la température moyenne des derniers jours pour avoir une idée de la température d’aujourd’hui – ce sont toutes des tâches de routine que nous effectuons régulièrement. C’est donc un bon point de départ à utiliser sur notre jeu de données pour faire des prédictions.

Le cours de clôture prévu pour chaque jour sera la moyenne d’un ensemble de valeurs précédemment observées. Au lieu d’utiliser la moyenne simple, nous utiliserons la technique de la moyenne mobile qui utilise le dernier ensemble de valeurs pour chaque prédiction. En d’autres termes, pour chaque étape suivante, les valeurs prédites sont prises en considération tout en supprimant de l’ensemble la valeur la plus ancienne observée. Voici un chiffre simple qui vous aidera à comprendre cela avec plus de clarté.

Nous allons implémenter cette technique sur notre jeu de données. La première étape consiste à créer une trame de données contenant uniquement les colonnes Date et Prix de clôture, puis à la diviser en ensembles de train et de validation pour vérifier nos prévisions.

Implémentation

Le simple fait de vérifier le RMSE ne nous aide pas à comprendre la performance du modèle. Visualisons cela pour obtenir une compréhension plus intuitive. Voici donc un graphique des valeurs prédites avec les valeurs réelles.

#plotvalid = 0valid = predsplt.plot(train)plt.plot(valid])

Inférence

La valeur RMSE est proche de 105 mais les résultats ne sont pas très prometteurs (comme vous pouvez le constater sur le graphique). Les valeurs prédites sont de la même plage que les valeurs observées dans le train (il y a une tendance à la hausse au départ, puis une lente diminution).

Dans la section suivante, nous examinerons deux techniques d’apprentissage automatique couramment utilisées – la régression linéaire et le kNN, et verrons comment elles fonctionnent sur nos données boursières.

Régression linéaire

Introduction

L’algorithme d’apprentissage automatique le plus basique pouvant être implémenté sur ces données est la régression linéaire. Le modèle de régression linéaire renvoie une équation qui détermine la relation entre les variables indépendantes et la variable dépendante.

L’équation de la régression linéaire peut s’écrire comme suit:

Ici, x1, x2,….xn représentent les variables indépendantes tandis que les coefficients θ1, θ2, θ θn représentent les poids. Vous pouvez vous référer à l’article suivant pour étudier la régression linéaire plus en détail:

  • Un guide complet pour les débutants pour la régression linéaire, Ridge et Lasso.

Pour notre énoncé de problème, nous n’avons pas d’ensemble de variables indépendantes. Nous n’avons que les dates à la place. Utilisons la colonne date pour extraire des fonctionnalités telles que – jour, mois, année, lundi / vendredi, etc. et puis ajustez un modèle de régression linéaire.

Implémentation

Nous allons d’abord trier l’ensemble de données par ordre croissant, puis créer un ensemble de données séparé afin que toute nouvelle fonctionnalité créée n’affecte pas les données d’origine.

#setting index as date valuesdf = pd.to_datetime(df.Date,format='%Y-%m-%d')df.index = df#sortingdata = df.sort_index(ascending=True, axis=0)#creating a separate datasetnew_data = pd.DataFrame(index=range(0,len(df)),columns=)for i in range(0,len(data)): new_data = data new_data = data
#create featuresfrom fastai.structured import add_datepartadd_datepart(new_data, 'Date')new_data.drop('Elapsed', axis=1, inplace=True) #elapsed will be the time stamp

Cela crée des fonctionnalités telles que:

‘Année’, ‘Mois’, ‘Semaine’, ‘Jour’, ‘Dayofweek’, ‘Dayofyear’, ‘Is_month_end’, ‘Is_month_start’, ‘Is_quarter_end’, ‘Is_quarter_start’, ‘Is_year_end’ et ‘Is_year_start’.

Remarque: J’ai utilisé add_datepart de la bibliothèque fastai. Si vous ne l’avez pas installé, vous pouvez simplement utiliser la commande pip install fastai. Sinon, vous pouvez créer ces fonctionnalités en utilisant de simples boucles for en python. J’ai montré un exemple ci-dessous.

En dehors de cela, nous pouvons ajouter notre propre ensemble de fonctionnalités qui, selon nous, seraient pertinentes pour les prédictions. Par exemple, mon hypothèse est que les premier et dernier jours de la semaine pourraient potentiellement affecter le cours de clôture de l’action beaucoup plus que les autres jours. J’ai donc créé une fonctionnalité qui identifie si un jour donné est Lundi / Vendredi ou Mardi / Mercredi / jeudi. Cela peut être fait en utilisant les lignes de code suivantes:

new_data = 0for i in range(0,len(new_data)): if (new_data == 0 or new_data == 4): new_data = 1 else: new_data = 0

Si le jour de la semaine est égal à 0 ou 4, la valeur de la colonne sera 1, sinon 0. De même, vous pouvez créer plusieurs fonctionnalités. Si vous avez des idées de fonctionnalités qui peuvent être utiles pour prédire le cours de l’action, veuillez les partager dans la section commentaire.

Nous allons maintenant diviser les données en ensembles de train et de validation pour vérifier les performances du modèle.

#split into train and validationtrain = new_datavalid = new_datax_train = train.drop('Close', axis=1)y_train = trainx_valid = valid.drop('Close', axis=1)y_valid = valid#implement linear regressionfrom sklearn.linear_model import LinearRegressionmodel = LinearRegression()model.fit(x_train,y_train)

Résultats

#make predictions and find the rmsepreds = model.predict(x_valid)rms=np.sqrt(np.mean(np.power((np.array(y_valid)-np.array(preds)),2)))rms
121.16291596523156

La valeur RMSE est plus élevée que la technique précédente, ce qui montre clairement que la régression linéaire a mal fonctionné. Regardons l’intrigue et comprenons pourquoi la régression linéaire n’a pas bien fonctionné:

#plotvalid = 0valid = predsvalid.index = new_data.indextrain.index = new_data.indexplt.plot(train)plt.plot(valid])

Inférence

La régression linéaire est une technique simple et assez facile à interpréter, mais il y a quelques inconvénients évidents. Un problème dans l’utilisation des algorithmes de régression est que le modèle est trop ajusté à la colonne date et mois. Au lieu de prendre en compte les valeurs précédentes du point de prédiction, le modèle considérera la valeur de la même date il y a un mois, ou de la même date / mois il y a un an.

Comme on le voit sur le graphique ci-dessus, pour janvier 2016 et janvier 2017, il y a eu une baisse du cours de l’action. Le modèle a prédit la même chose pour janvier 2018. Une technique de régression linéaire peut bien fonctionner pour des problèmes tels que les ventes dans les grands magasins où les fonctionnalités indépendantes sont utiles pour déterminer la valeur cible.

k – Voisins les plus proches

Introduction

Un autre algorithme ML intéressant que l’on peut utiliser ici est kNN (k voisins les plus proches). Sur la base des variables indépendantes, kNN trouve la similitude entre les nouveaux points de données et les anciens points de données. Permettez-moi d’expliquer cela avec un exemple simple.

Considérez la taille et l’âge de 11 personnes. Sur la base de caractéristiques données (« Âge » et « Taille »), le tableau peut être représenté sous un format graphique comme indiqué ci-dessous:

Pour déterminer le poids de l’ID #11, kNN considère le poids des voisins les plus proches de cet ID. Le poids de l’ID #11 devrait être la moyenne de ses voisins. Si nous considérons trois voisins (k = 3) pour l’instant, le poids de l’ID #11 serait = (77+72+60)/3 = 69.66 kg.

Pour une compréhension détaillée de kNN, vous pouvez vous référer aux articles suivants:

  • Introduction à k – Voisins les plus proches: Simplifié

  • Une Introduction pratique à l’Algorithme des K – Voisins les plus proches pour la régression

Implémentation

#importing librariesfrom sklearn import neighborsfrom sklearn.model_selection import GridSearchCVfrom sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler(feature_range=(0, 1))

Utilisant le même train et le même ensemble de validation de la dernière section:

#scaling datax_train_scaled = scaler.fit_transform(x_train)x_train = pd.DataFrame(x_train_scaled)x_valid_scaled = scaler.fit_transform(x_valid)x_valid = pd.DataFrame(x_valid_scaled)#using gridsearch to find the best parameterparams = {'n_neighbors':}knn = neighbors.KNeighborsRegressor()model = GridSearchCV(knn, params, cv=5)#fit the model and make predictionsmodel.fit(x_train,y_train)preds = model.predict(x_valid)

Résultats

#rmserms=np.sqrt(np.mean(np.power((np.array(y_valid)-np.array(preds)),2)))rms
115.17086550026721

Il n’y a pas une énorme différence dans la valeur RMSE, mais un tracé pour les valeurs prédites et réelles devrait fournir une compréhension plus claire.

#plotvalid = 0valid = predsplt.plot(valid])plt.plot(train)

Inférence

La valeur RMSE est presque similaire au modèle de régression linéaire et le graphique montre le même modèle. Comme la régression linéaire, kNN a également identifié une baisse en janvier 2018, car c’est la tendance des dernières années. Nous pouvons affirmer sans risque que les algorithmes de régression n’ont pas bien fonctionné sur cet ensemble de données.

Allons de l’avant et examinons certaines techniques de prévision de séries chronologiques pour savoir comment elles fonctionnent face à ce défi de prévision des cours boursiers.

Auto ARIMA

Introduction

ARIMA est une méthode statistique très populaire pour la prévision des séries chronologiques. Les modèles ARIMA prennent en compte les valeurs passées pour prédire les valeurs futures. Il y a trois paramètres importants dans ARIMA:

  • p (valeurs passées utilisées pour prévoir la valeur suivante)
  • q (erreurs de prévision passées utilisées pour prédire les valeurs futures)
  • d (ordre de différenciation)

Le réglage des paramètres pour ARIMA prend beaucoup de temps. Nous utiliserons donc auto ARIMA qui sélectionne automatiquement la meilleure combinaison de (p, q, d) qui fournit le moins d’erreur. Pour en savoir plus sur le fonctionnement d’auto ARIMA, reportez-vous à cet article:

  • Construire des Modèles de Séries Chronologiques Haute Performance en utilisant Auto ARIMA

Implémentation

from pyramid.arima import auto_arimadata = df.sort_index(ascending=True, axis=0)train = datavalid = datatraining = trainvalidation = validmodel = auto_arima(training, start_p=1, start_q=1,max_p=3, max_q=3, m=12,start_P=0, seasonal=True,d=1, D=1, trace=True,error_action='ignore',suppress_warnings=True)model.fit(training)forecast = model.predict(n_periods=248)forecast = pd.DataFrame(forecast,index = valid.index,columns=)

Résultats

rms=np.sqrt(np.mean(np.power((np.array(valid)-np.array(forecast)),2)))rms
44.954584993246954
#plotplt.plot(train)plt.plot(valid)plt.plot(forecast)

Inférence

Comme nous l’avons vu précédemment, un modèle ARIMA automatique utilise des données passées pour comprendre le modèle dans la série chronologique. En utilisant ces valeurs, le modèle a capturé une tendance à la hausse dans la série. Bien que les prédictions utilisant cette technique soient bien meilleures que celles des modèles d’apprentissage automatique précédemment implémentés, ces prédictions ne sont toujours pas proches des valeurs réelles.

Comme il ressort de l’intrigue, le modèle a capturé une tendance de la série, mais ne se concentre pas sur la partie saisonnière. Dans la section suivante, nous mettrons en œuvre un modèle de série chronologique qui tient compte à la fois de la tendance et de la saisonnalité d’une série.

Prophet

Introduction

Il existe un certain nombre de techniques de séries chronologiques qui peuvent être implémentées sur l’ensemble de données de prédiction de stock, mais la plupart de ces techniques nécessitent beaucoup de prétraitement des données avant d’ajuster le modèle. Prophet, conçu et lancé par Facebook, est une bibliothèque de prévisions de séries chronologiques qui ne nécessite aucun prétraitement des données et est extrêmement simple à mettre en œuvre. L’entrée pour Prophet est une trame de données avec deux colonnes: date et cible (ds et y).

Prophet essaie de capturer la saisonnalité dans les données passées et fonctionne bien lorsque l’ensemble de données est volumineux. Voici un article intéressant qui explique le prophète d’une manière simple et intuitive:

  • Générez des prévisions de Séries Chronologiques rapides et Précises à l’aide du Prophète de Facebook.

Implémentation

#importing prophetfrom fbprophet import Prophet#creating dataframenew_data = pd.DataFrame(index=range(0,len(df)),columns=)for i in range(0,len(data)): new_data = data new_data = datanew_data = pd.to_datetime(new_data.Date,format='%Y-%m-%d')new_data.index = new_data#preparing datanew_data.rename(columns={'Close': 'y', 'Date': 'ds'}, inplace=True)#train and validationtrain = new_datavalid = new_data#fit the modelmodel = Prophet()model.fit(train)#predictionsclose_prices = model.make_future_dataframe(periods=len(valid))forecast = model.predict(close_prices)

Résultats

#rmseforecast_valid = forecastrms=np.sqrt(np.mean(np.power((np.array(valid)-np.array(forecast_valid)),2)))rms
57.494461930575149
#plotvalid = 0valid = forecast_valid.valuesplt.plot(train)plt.plot(valid])

Inférence

Prophet (comme la plupart des techniques de prévision des séries chronologiques) tente de capturer la tendance et la saisonnalité à partir de données passées. Ce modèle fonctionne généralement bien sur les ensembles de données de séries chronologiques, mais ne respecte pas sa réputation dans ce cas.

Il s’avère que les cours des actions n’ont pas de tendance ou de saisonnalité particulière. Cela dépend fortement de ce qui se passe actuellement sur le marché et donc de la hausse et de la baisse des prix. Par conséquent, les techniques de prévision comme ARIMA, SARIMA et Prophet ne donneraient pas de bons résultats pour ce problème particulier.

Allons de l’avant et essayons une autre technique avancée – La mémoire à court terme à long terme (LSTM).

Mémoire à long terme (LSTM)

Introduction

Les LSTM sont largement utilisées pour les problèmes de prédiction de séquences et se sont révélées extrêmement efficaces. La raison pour laquelle ils fonctionnent si bien est que LSTM est capable de stocker des informations passées qui sont importantes et d’oublier les informations qui ne l’sont pas. LSTM a trois portes:

  • La porte d’entrée: La porte d’entrée ajoute des informations à l’état de la cellule
  • La porte d’oubli : Elle supprime les informations qui ne sont plus requises par le modèle
  • La porte de sortie : La porte de sortie à LSTM sélectionne les informations à afficher en sortie

Pour une compréhension plus détaillée de LSTM et de son architecture, vous pouvez consulter l’article ci-dessous:

  • Introduction à la Mémoire à Long Terme

Pour l’instant, implémentons LSTM sous forme de boîte noire et vérifions ses performances sur nos données particulières.

Implémentation

#importing required librariesfrom sklearn.preprocessing import MinMaxScalerfrom keras.models import Sequentialfrom keras.layers import Dense, Dropout, LSTM#creating dataframedata = df.sort_index(ascending=True, axis=0)new_data = pd.DataFrame(index=range(0,len(df)),columns=)for i in range(0,len(data)): new_data = data new_data = data#setting indexnew_data.index = new_data.Datenew_data.drop('Date', axis=1, inplace=True)#creating train and test setsdataset = new_data.valuestrain = datasetvalid = dataset#converting dataset into x_train and y_trainscaler = MinMaxScaler(feature_range=(0, 1))scaled_data = scaler.fit_transform(dataset)x_train, y_train = , for i in range(60,len(train)): x_train.append(scaled_data) y_train.append(scaled_data)x_train, y_train = np.array(x_train), np.array(y_train)x_train = np.reshape(x_train, (x_train.shape,x_train.shape,1))# create and fit the LSTM networkmodel = Sequential()model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape,1)))model.add(LSTM(units=50))model.add(Dense(1))model.compile(loss='mean_squared_error', optimizer='adam')model.fit(x_train, y_train, epochs=1, batch_size=1, verbose=2)#predicting 246 values, using past 60 from the train datainputs = new_data.valuesinputs = inputs.reshape(-1,1)inputs = scaler.transform(inputs)X_test = for i in range(60,inputs.shape): X_test.append(inputs)X_test = np.array(X_test)X_test = np.reshape(X_test, (X_test.shape,X_test.shape,1))closing_price = model.predict(X_test)closing_price = scaler.inverse_transform(closing_price)

Résultats

rms=np.sqrt(np.mean(np.power((valid-closing_price),2)))rms
11.772259608962642
#for plottingtrain = new_datavalid = new_datavalid = closing_priceplt.plot(train)plt.plot(valid])

Inférence

Wow! Le modèle LSTM peut être réglé pour différents paramètres tels que la modification du nombre de couches LSTM, l’ajout d’une valeur d’abandon ou l’augmentation du nombre d’époques. Mais les prédictions de LSTM sont-elles suffisantes pour déterminer si le cours de l’action augmentera ou diminuera? Certainement pas!

Comme je l’ai mentionné au début de l’article, le cours de l’action est affecté par l’actualité de l’entreprise et d’autres facteurs tels que la démonétisation ou la fusion / scission des sociétés. Il existe également certains facteurs intangibles qui peuvent souvent être impossibles à prévoir à l’avance.

Notes de fin

La prévision des séries chronologiques est un domaine très intrigant avec lequel travailler, comme je l’ai réalisé pendant que j’écrivais ces articles. Il y a une perception dans la communauté que c’est un domaine complexe, et bien qu’il y ait un grain de vérité là-dedans, ce n’est pas si difficile une fois que vous maîtrisez les techniques de base.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.