Previsione dei prezzi delle azioni Utilizzando tecniche di apprendimento automatico e Deep Learning (con codici Python)

Introduzione

Prevedere come il mercato azionario si esibirà è una delle cose più difficili da fare. Ci sono così tanti fattori coinvolti nella previsione-fattori fisici vs. comportamento fitologico, razionale e irrazionale, ecc. Tutti questi aspetti si combinano per rendere i prezzi delle azioni volatili e molto difficili da prevedere con un alto grado di precisione.

Possiamo usare l’apprendimento automatico come un punto di svolta in questo settore? Utilizzo di funzionalità come gli ultimi annunci su un’organizzazione, i risultati trimestrali delle entrate, ecc., le tecniche di apprendimento automatico hanno il potenziale per dissotterrare modelli e intuizioni che non abbiamo visto prima, e questi possono essere usati per fare previsioni infallibilmente accurate.

previsione del prezzo delle azioni, LSTM, machine learning

In questo articolo, lavoreremo con i dati storici sui prezzi delle azioni di una società quotata in borsa. Implementeremo un mix di algoritmi di apprendimento automatico per prevedere il futuro prezzo delle azioni di questa azienda, a partire da semplici algoritmi come la media e la regressione lineare, per poi passare a tecniche avanzate come Auto ARIMA e LSTM.

L’idea alla base di questo articolo è quello di mostrare come questi algoritmi sono implementati. Descriverò brevemente la tecnica e fornirò collegamenti pertinenti per rispolverare i concetti come e quando necessario. Nel caso in cui sei un nuovo arrivato al mondo delle serie temporali, suggerisco di passare attraverso i seguenti articoli prima:

  • Una guida completa per principianti per creare un Time Series Forecast
  • Un Tutorial Completo su Serie temporali di Modellazione
  • Corso Gratuito: Serie temporale di Previsione utilizzo di Python

Progetto per la Pratica di Previsione Serie

Tempo di previsione Serie & modellazione svolge un ruolo importante nell’analisi dei dati. L’analisi delle serie temporali è una branca specializzata delle statistiche ampiamente utilizzata in campi come Econometria & Ricerca operativa.

Le serie temporali sono ampiamente utilizzate nell’analisi & scienza dei dati. Questo è specificamente progettato problema serie temporale per voi e la sfida è quella di prevedere il traffico.

Pratica ora

Sei un principiante alla ricerca di un posto per iniziare il vostro viaggio scienza dei dati? Presentando un corso completo, pieno di conoscenze e di apprendimento della scienza dei dati, curato solo per te! Questo corso copre tutto, dalle basi dell’apprendimento automatico ai concetti avanzati di ML, Deep Learning e Time series.

  • Certificata AI & ML Blackbelt+ Programma

Sommario

    1. La comprensione del Problema Economico
    2. Media mobile
    3. Regressione Lineare
    4. k-Nearest Neighbors
    5. Auto ARIMA
    6. Profeta
    7. Lungo la Memoria a Breve Termine (LSTM)

la Comprensione del Problema Economico

Ci immergeremo in attuazione parte di questo articolo, presto, ma prima è importante stabilire che cosa stiamo puntando a risolvere. In generale, l’analisi del mercato azionario è divisa in due parti: Analisi fondamentale e analisi tecnica.

  • L’analisi fondamentale comporta l’analisi della redditività futura della società sulla base del suo attuale ambiente di business e delle prestazioni finanziarie.
  • L’analisi tecnica, d’altra parte, include la lettura dei grafici e l’utilizzo di dati statistici per identificare le tendenze del mercato azionario.

Come avrete intuito, il nostro focus sarà sulla parte di analisi tecnica. Useremo un set di dati da Quandl (puoi trovare i dati storici per vari stock qui) e per questo particolare progetto, ho usato i dati per “Tata Global Beverages”. È ora di tuffarsi!

Nota: Ecco il set di dati che ho usato per il codice: Download

Prima caricheremo il set di dati e definiremo la variabile di destinazione per il problema:

#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()

Ci sono più variabili nel set di dati: data, open, high, low, last, close, total_trade_quantity e turnover.

  • Le colonne Apri e Chiudi rappresentano il prezzo iniziale e finale al quale il titolo viene scambiato in un determinato giorno.
  • Alto, Basso e Ultimo rappresentano il prezzo massimo, minimo e ultimo dell’azione per il giorno.
  • La quantità commerciale totale è il numero di azioni acquistate o vendute nel corso della giornata e il fatturato (Lacs) è il fatturato della particolare società in una determinata data.

Un’altra cosa importante da notare è che il mercato è chiuso nei fine settimana e nei giorni festivi.Nota di nuovo la tabella sopra, mancano alcuni valori di data-2/10/2018, 6/10/2018, 7/10/2018. Di queste date, 2nd è una festa nazionale mentre 6th e 7th cadono in un fine settimana.

Il calcolo dell’utile o della perdita è solitamente determinato dal prezzo di chiusura di un titolo per il giorno, quindi considereremo il prezzo di chiusura come variabile target. Tracciamo la variabile di destinazione per capire come si sta delineando nei nostri dati:

#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')

Nelle prossime sezioni, esploreremo queste variabili e useremo diverse tecniche per prevedere il prezzo di chiusura giornaliero del titolo.

Media mobile

Introduzione

‘Media’ è facilmente una delle cose più comuni che usiamo nella nostra vita quotidiana. Ad esempio, calcolando i segni medi per determinare le prestazioni complessive o trovando la temperatura media degli ultimi giorni per avere un’idea della temperatura di oggi – tutti questi sono compiti di routine che facciamo regolarmente. Quindi questo è un buon punto di partenza da utilizzare sul nostro set di dati per fare previsioni.

Il prezzo di chiusura previsto per ogni giorno sarà la media di un insieme di valori precedentemente osservati. Invece di usare la media semplice, useremo la tecnica della media mobile che utilizza l’ultimo set di valori per ogni previsione. In altre parole, per ogni passaggio successivo, i valori previsti vengono presi in considerazione durante la rimozione del valore osservato più vecchio dal set. Ecco una figura semplice che ti aiuterà a capirlo con più chiarezza.

Implementeremo questa tecnica sul nostro set di dati. Il primo passo è creare un dataframe che contenga solo le colonne Data e Prezzo di chiusura, quindi dividerlo in train e validation set per verificare le nostre previsioni.

Implementazione

Il solo controllo dell’RMSE non ci aiuta a capire come si è comportato il modello. Visualizziamo questo per ottenere una comprensione più intuitiva. Quindi ecco una trama dei valori previsti insieme ai valori effettivi.

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

Inferenza

Il valore RMSE è vicino a 105 ma i risultati non sono molto promettenti (come puoi raccogliere dalla trama). I valori previsti sono dello stesso intervallo dei valori osservati nel set di treni (inizialmente c’è una tendenza crescente e poi una lenta diminuzione).

Nella prossima sezione, vedremo due tecniche di apprendimento automatico comunemente usate – Regressione lineare e kNN, e vedere come si comportano sui nostri dati di mercato azionario.

Regressione lineare

Introduzione

L’algoritmo di apprendimento automatico di base che può essere implementato su questi dati è la regressione lineare. Il modello di regressione lineare restituisce un’equazione che determina la relazione tra le variabili indipendenti e la variabile dipendente.

L’equazione per la regressione lineare può essere scritta come:

Qui, x1, x2,….xn rappresentano le variabili indipendenti mentre i coefficienti θ1, θ2,…. θn rappresentano i pesi. È possibile fare riferimento al seguente articolo per studiare la regressione lineare in modo più dettagliato:

  • Una guida completa per principianti per lineare, cresta e Lazo regressione.

Per la nostra dichiarazione problema, non abbiamo un insieme di variabili indipendenti. Abbiamo solo le date, invece. Usiamo la colonna data per estrarre caratteristiche come-giorno, mese, anno, lun/ven ecc. e poi montare un modello di regressione lineare.

Implementazione

Prima ordineremo il set di dati in ordine crescente e quindi creeremo un set di dati separato in modo che qualsiasi nuova funzionalità creata non influenzi i dati originali.

#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

Questo crea caratteristiche come:

‘Anno’, ‘Mese’, ‘Settimana’, ‘Giorno’, ‘Dayofweek’, ‘Dayofyear’, ‘Is_month_end’, ‘Is_month_start’, ‘Is_quarter_end’, ‘Is_quarter_start’, ‘Is_year_end’, e ‘Is_year_start’.

Nota: ho usato add_datepart dalla libreria fastai. Se non lo avete installato, si può semplicemente utilizzare il comando pip install fastai. In caso contrario, è possibile creare queste funzionalità utilizzando semplici cicli for in python. Ho mostrato un esempio qui sotto.

Oltre a questo, possiamo aggiungere il nostro set di funzionalità che riteniamo rilevanti per le previsioni. Ad esempio, la mia ipotesi è che il primo e l’ultimo giorno della settimana potrebbero potenzialmente influenzare il prezzo di chiusura del titolo molto più degli altri giorni. Quindi ho creato una funzione che identifica se un dato giorno è lunedì / venerdì o martedì / mercoledì / giovedì. Questo può essere fatto usando le seguenti righe di codice:

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

Se il giorno della settimana è uguale a 0 o 4, il valore della colonna sarà 1, altrimenti 0. Allo stesso modo, è possibile creare più funzioni. Se avete alcune idee per le caratteristiche che possono essere utili nella previsione prezzo delle azioni, si prega di condividere nella sezione commenti.

Ora divideremo i dati in set di treni e validazione per verificare le prestazioni del modello.

#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)

Risultati

#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

Il valore RMSE è superiore alla tecnica precedente, che mostra chiaramente che la regressione lineare ha funzionato male. Diamo un’occhiata alla trama e capiamo perché la regressione lineare non ha funzionato bene:

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

Inferenza

La regressione lineare è una tecnica semplice e abbastanza facile da interpretare, ma ci sono alcuni evidenti svantaggi. Un problema nell’utilizzo degli algoritmi di regressione è che il modello si adatta troppo alla colonna data e mese. Invece di prendere in considerazione i valori precedenti dal punto di previsione, il modello considererà il valore dalla stessa data di un mese fa o dalla stessa data/mese di un anno fa.

Come si vede dalla trama sopra, per gennaio 2016 e gennaio 2017, c’è stato un calo del prezzo delle azioni. Il modello ha previsto lo stesso per gennaio 2018. Una tecnica di regressione lineare può funzionare bene per problemi come le vendite di Big Mart in cui le caratteristiche indipendenti sono utili per determinare il valore target.

k-Neighbours

Introduzione

Un altro interessante algoritmo ML che si può usare qui è kNN (k neighbours). In base alle variabili indipendenti, kNN trova la somiglianza tra nuovi punti dati e vecchi punti dati. Lasciatemi spiegare questo con un semplice esempio.

Considera l’altezza e l’età per 11 persone. Sulla base di determinate caratteristiche (“Età” e “Altezza”), la tabella può essere rappresentata in un formato grafico come mostrato di seguito:

Per determinare il peso per ID #11, kNN considera il peso dei vicini più vicini di questo ID. Si prevede che il peso di ID #11 sia la media dei suoi vicini. Se consideriamo tre vicini (k = 3) per ora, il peso per ID#11 sarebbe = (77+72+60)/3 = 69.66 kg.

Per una comprensione dettagliata di kNN, è possibile fare riferimento ai seguenti articoli:

  • Introduzione a k-Vicini più vicini: Semplificata

  • Un’Introduzione Pratica alla K-Nearest Neighbors Algoritmo di Regressione

Attuazione

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

Utilizzando lo stesso treno e convalida la precedente sezione:

#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)

Risultati

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

non C’è una grande differenza nel valore di RMSE, ma una trama per i valori stimati ed effettivi dovrebbero fornire una più chiara comprensione.

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

Inferenza

Il valore RMSE è quasi simile al modello di regressione lineare e la trama mostra lo stesso modello. Come la regressione lineare, kNN ha anche identificato un calo a gennaio 2018 poiché questo è stato il modello degli ultimi anni. Possiamo tranquillamente dire che gli algoritmi di regressione non hanno funzionato bene su questo set di dati.

Andiamo avanti e guardare alcune tecniche di previsione serie temporali per scoprire come si comportano di fronte a questa sfida di previsione dei prezzi delle azioni.

Auto ARIMA

Introduzione

ARIMA è un metodo statistico molto popolare per la previsione di serie temporali. I modelli ARIMA tengono conto dei valori passati per prevedere i valori futuri. Ci sono tre parametri importanti in ARIMA:

  • p (valori passati utilizzati per prevedere il valore successivo)
  • q (errori di previsione passati utilizzati per prevedere i valori futuri)
  • d (ordine di differenza)

La sintonizzazione dei parametri per ARIMA consuma molto tempo. Quindi useremo auto ARIMA che seleziona automaticamente la migliore combinazione di (p, q, d) che fornisce il minimo errore. Per saperne di più su come funziona auto ARIMA, fare riferimento a questo articolo:

  • Crea modelli di serie temporali ad alte prestazioni utilizzando Auto ARIMA

Implementazione

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=)

Risultati

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)

Inferenza

Come abbiamo visto in precedenza, un modello auto ARIMA utilizza dati passati per comprendere il modello nelle serie temporali. Utilizzando questi valori, il modello ha catturato una tendenza crescente nella serie. Sebbene le previsioni che utilizzano questa tecnica siano molto migliori di quelle dei modelli di apprendimento automatico precedentemente implementati, queste previsioni non sono ancora vicine ai valori reali.

Come è evidente dalla trama, il modello ha catturato una tendenza nella serie, ma non si concentra sulla parte stagionale. Nella prossima sezione, implementeremo un modello di serie temporali che tiene conto sia della tendenza che della stagionalità di una serie.

Prophet

Introduzione

Esistono numerose tecniche di serie temporali che possono essere implementate sul set di dati di previsione dello stock, ma la maggior parte di queste tecniche richiede un sacco di pre-elaborazione dei dati prima di adattare il modello. Prophet, progettato e sperimentato da Facebook, è una libreria di previsione di serie temporali che non richiede alcuna pre-elaborazione dei dati ed è estremamente semplice da implementare. L’input per Prophet è un dataframe con due colonne: data e target (ds e y).

Prophet cerca di catturare la stagionalità nei dati passati e funziona bene quando il set di dati è grande. Ecco un interessante articolo che spiega Profeta in modo semplice e intuitivo:

  • Generare previsioni serie temporali rapidi e precisi utilizzando Profeta di Facebook.

Implementazione

#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)

Risultati

#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])

Inferenza

Prophet (come la maggior parte delle tecniche di previsione delle serie temporali) cerca di catturare l’andamento e la stagionalità dai dati passati. Questo modello di solito si comporta bene su set di dati di serie temporali, ma non riesce a vivere fino alla sua reputazione in questo caso.

A quanto pare, i prezzi delle azioni non hanno una particolare tendenza o stagionalità. Dipende molto da ciò che sta attualmente accadendo sul mercato e quindi i prezzi salgono e scendono. Quindi le tecniche di previsione come ARIMA, SARIMA e Prophet non mostrerebbero buoni risultati per questo particolare problema.

Andiamo avanti e provare un’altra tecnica avanzata – Long Short Term Memory (LSTM).

Long Short Term Memory (LSTM)

Introduzione

Gli LSTM sono ampiamente utilizzati per problemi di previsione delle sequenze e si sono dimostrati estremamente efficaci. Il motivo per cui funzionano così bene è perché LSTM è in grado di memorizzare le informazioni passate che sono importanti e dimenticare le informazioni che non lo sono. LSTM ha tre porte:

  • Il cancello di ingresso: La porta di ingresso aggiunge informazioni alla cella di stato
  • dimenticare gate: rimuove le informazioni che non è più richiesto dal modello
  • Il cancello di uscita: Uscita a LSTM seleziona le informazioni da visualizzare come uscita

Per una comprensione più dettagliata di LSTM e per la sua architettura, si può passare attraverso l’articolo qui di seguito:

  • Introduzione alla Lunga Memoria a Breve Termine

Per ora, cerchiamo di implementare LSTM come una scatola nera e controllare le prestazioni dei nostri dati.

Implementazione

#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)

Risultati

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])

Inferenza

Wow! Il modello LSTM può essere sintonizzato per vari parametri come la modifica del numero di livelli LSTM, l’aggiunta del valore di dropout o l’aumento del numero di epoche. Ma le previsioni di LSTM sono sufficienti per identificare se il prezzo delle azioni aumenterà o diminuirà? Certamente no!

Come ho detto all’inizio dell’articolo, il prezzo delle azioni è influenzato dalle notizie sulla società e da altri fattori come la demonetizzazione o la fusione/scissione delle società. Ci sono anche alcuni fattori intangibili che spesso possono essere impossibili da prevedere in anticipo.

Note finali

La previsione delle serie temporali è un campo molto intrigante con cui lavorare, come ho capito durante il mio tempo a scrivere questi articoli. C’è una percezione nella comunità che si tratta di un campo complesso, e mentre c’è un granello di verità in là, non è così difficile una volta che si ottiene il blocco delle tecniche di base.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.