voorspelling van de aandelenkoersen met behulp van Machine Learning en Deep Learning-technieken (met Python-codes)

Inleiding

voorspellen hoe de aandelenmarkt zal presteren is een van de moeilijkste dingen om te doen. Er zijn zoveel factoren betrokken bij de voorspelling – fysieke factoren Versus physhologisch, rationeel en irrationeel gedrag, enz. Al deze aspecten samen maken aandelenkoersen volatiel en zeer moeilijk te voorspellen met een hoge mate van nauwkeurigheid.

kunnen we machine learning gebruiken als een game changer in dit domein? Met behulp van functies zoals de laatste aankondigingen over een organisatie, hun driemaandelijkse omzet resultaten, enz. machine learning-technieken hebben het potentieel om patronen en inzichten te ontrafelen die we eerder niet zagen, en deze kunnen worden gebruikt om feilloos nauwkeurige voorspellingen te doen.

stock price prediction, LSTM, machine learning

In dit artikel zullen we werken met historische gegevens over de aandelenkoersen van een beursgenoteerde onderneming. We zullen een mix van machine learning algoritmen implementeren om de toekomstige aandelenkoers van dit bedrijf te voorspellen, te beginnen met eenvoudige algoritmen zoals middeling en lineaire regressie, en dan verder gaan met geavanceerde technieken zoals Auto ARIMA en LSTM.

het kernidee achter dit artikel is om te laten zien hoe deze algoritmen worden geïmplementeerd. Ik zal kort de techniek beschrijven en relevante links geven om de concepten op te frissen als en wanneer dat nodig is. In het geval dat je een nieuwkomer bent in de wereld van de tijdreeksen, stel ik voor eerst de volgende artikelen door te nemen:

  • een uitgebreide beginnersgids voor het maken van een Tijdreeksvoorspelling
  • een complete Tutorial over Tijdreeksmodellering
  • gratis cursus: Tijdreeksvoorspelling met behulp van Python

Project om Tijdreeksvoorspelling

tijdreeksvoorspelling & modellering speelt een belangrijke rol in gegevensanalyse. Tijdreeksanalyse is een gespecialiseerde tak van statistiek die op grote schaal wordt gebruikt op gebieden zoals Econometrie & operationeel onderzoek.

tijdreeksen worden veel gebruikt in analytics & data science. Dit is speciaal ontworpen tijdreeks probleem voor u en de uitdaging is om het verkeer te voorspellen.

Practice Now

bent u een beginner op zoek naar een plek om uw data science-reis te beginnen? Het presenteren van een uitgebreide cursus, vol kennis en data science learning, speciaal samengesteld voor u! Deze cursus omvat alles van basisprincipes van Machine Learning tot geavanceerde concepten van ML, Deep Learning en Time series.

  • Gecertificeerd AI & ML Blackbelt+ Programma

Inhoudsopgave

    1. Inzicht in de probleemstelling
    2. Voortschrijdend Gemiddelde
    3. Lineaire Regressie
    4. k-Nearest Neighbors
    5. Auto-ARIMA
    6. Profeet
    7. Lange met het Korte Termijn Geheugen (LSTM)

Inzicht in de probleemstelling

We duiken in de uitvoering van een deel van dit artikel binnenkort, maar eerst is het belangrijk om vast te stellen wat we mikken op te lossen. Globaal, beursanalyse is verdeeld in twee delen – fundamentele analyse en technische analyse.

  • fundamentele analyse omvat het analyseren van de toekomstige winstgevendheid van de onderneming op basis van haar huidige bedrijfsklimaat en financiële prestaties.
  • de technische analyse omvat daarentegen het lezen van de grafieken en het gebruik van statistische cijfers om de trends op de aandelenmarkt te identificeren.

zoals u misschien al geraden hebt, zal onze focus liggen op het gedeelte technische analyse. We zullen een dataset van Quandl gebruiken (U kunt Historische gegevens voor verschillende voorraden hier vinden) en voor dit specifieke project heb ik de gegevens voor ‘Tata Global Beverages’gebruikt. Tijd om te duiken!

opmerking: hier is de dataset die ik gebruikte voor de code: Download

we zullen eerst de dataset laden en de doelvariabele voor het probleem definiëren:

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

er zijn meerdere variabelen in de dataset – date, open, high, low, last, close, total_trade_quantity, en turnover.

  • de kolommen Open en sluiten geven de begin-en eindkoers weer waartegen het aandeel op een bepaalde dag wordt verhandeld.
  • hoog, laag en laatste vertegenwoordigen het maximum, minimum en laatste koers van het aandeel voor de dag.
  • totale Handelshoeveelheid is het aantal aandelen dat op de dag is gekocht of verkocht en de omzet (Lacs) is de omzet van de betreffende onderneming op een bepaalde datum.

een ander belangrijk punt om op te merken is dat de markt gesloten is in het weekend en op feestdagen.Let nogmaals op de bovenstaande tabel, enkele datumwaarden ontbreken – 2/10/2018, 6/10/2018, 7/10/2018. Van deze data, 2e is een nationale feestdag, terwijl 6e en 7e vallen in een weekend.

de winst – of verliesberekening wordt meestal bepaald door de slotkoers van een aandeel voor de dag, daarom zullen we de slotkoers beschouwen als de doelvariabele. Laten we de doelvariabele plotten om te begrijpen hoe het zich vormt in onze data:

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

In de volgende secties zullen we deze variabelen verkennen en verschillende technieken gebruiken om de dagelijkse slotkoers van het aandeel te voorspellen.

voortschrijdend gemiddelde

Inleiding

‘gemiddeld’ is gemakkelijk een van de meest voorkomende dingen die we in ons dagelijks leven gebruiken. Bijvoorbeeld, het berekenen van de gemiddelde cijfers om de algehele prestaties te bepalen, of het vinden van de gemiddelde temperatuur van de afgelopen dagen om een idee te krijgen over de temperatuur van vandaag – dit zijn allemaal routinetaken die we doen op een regelmatige basis. Dus dit is een goed startpunt om te gebruiken op onze dataset voor het maken van voorspellingen.

de voorspelde slotkoers voor elke dag is het gemiddelde van een reeks eerder waargenomen waarden. In plaats van het eenvoudige gemiddelde te gebruiken, zullen we de moving average techniek gebruiken die de laatste reeks waarden voor elke voorspelling gebruikt. Met andere woorden, voor elke volgende stap worden de voorspelde waarden in aanmerking genomen terwijl de oudste waargenomen waarde uit de verzameling wordt verwijderd. Hier is een eenvoudig cijfer dat u zal helpen dit met meer duidelijkheid te begrijpen.

we zullen deze techniek implementeren in onze dataset. De eerste stap is om een dataframe dat alleen de datum en sluit prijs kolommen bevat, dan splitsen in trein en validatie sets om onze voorspellingen te verifiëren.

implementatie

het controleren van de RMSE helpt ons niet om te begrijpen hoe het model presteerde. Laten we dit visualiseren om een meer intuïtief begrip te krijgen. Dus hier is een grafiek van de voorspelde waarden samen met de werkelijke waarden.

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

gevolgtrekking

de RMSE-waarde ligt dicht bij 105, maar de resultaten zijn niet erg veelbelovend (zoals u uit de plot kunt opmaken). De voorspelde waarden zijn van hetzelfde bereik als de waargenomen waarden in het treinstel (er is een stijgende trend in eerste instantie en vervolgens een langzame daling).

in de volgende paragraaf zullen we kijken naar twee veelgebruikte machine learning technieken – lineaire regressie en kNN, en zien hoe ze presteren op onze beursgegevens.

lineaire regressie

Inleiding

het meest elementaire algoritme voor machine learning dat op deze gegevens kan worden geïmplementeerd, is lineaire regressie. Het lineaire regressiemodel geeft een vergelijking terug die de relatie tussen de onafhankelijke variabelen en de afhankelijke variabele bepaalt.

de vergelijking voor lineaire regressie kan worden geschreven als:

hier, x1, x2,….xn vertegenwoordigen de onafhankelijke variabelen, terwijl de coëfficiënten θ1, θ2,…. θn staat voor de gewichten. U kunt verwijzen naar het volgende artikel om lineaire regressie in meer detail te bestuderen:

  • een uitgebreide beginnersgids voor lineaire, Ridge en Lasso regressie.

voor onze probleemstelling hebben we geen reeks onafhankelijke variabelen. We hebben alleen de data. Laten we de datumkolom gebruiken om functies zoals – Dag, Maand, Jaar, Ma/Vr enz. en past dan in een lineair regressiemodel.

implementatie

we zullen eerst de dataset in oplopende volgorde sorteren en vervolgens een aparte dataset maken zodat elke nieuwe functie die is aangemaakt geen invloed heeft op de oorspronkelijke gegevens.

#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

dit creëert functies zoals:

“Year”, “Month”, “Week”, “Day”, “Dayofweek”, “Dayofyear”, “Is_month_end”, “Is_month_start”, “Is_quarter_end”, “Is_quarter_start”, “Is_year_end” en “Is_year_start”.

opmerking: Ik heb add_datepart uit de fastai-bibliotheek gebruikt. Als u het niet hebt geïnstalleerd, kunt u gewoon gebruik maken van de opdracht pip install fastai. Anders kunt u deze functie maken met behulp van simple for loops in python. Ik heb hieronder een voorbeeld getoond.

afgezien van dit, kunnen we onze eigen set van functies toevoegen waarvan we denken dat ze relevant zijn voor de voorspellingen. Bijvoorbeeld, mijn hypothese is dat de eerste en laatste dagen van de week zou kunnen invloed hebben op de slotkoers van de voorraad veel meer dan de andere dagen. Dus ik heb een functie die identificeert of een bepaalde dag is maandag/vrijdag of dinsdag/woensdag/donderdag. Dit kan worden gedaan met behulp van de volgende regels code:

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

als de dag van de week gelijk is aan 0 of 4, is de kolomwaarde 1, Anders 0. Op dezelfde manier kunt u meerdere functies maken. Als u een aantal ideeën voor functies die nuttig kunnen zijn bij het voorspellen van de koers van de aandelen, deel dan in de commentaar sectie.

we zullen de gegevens nu splitsen in trein-en validatiesets om de prestaties van het model te controleren.

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

resultaten

#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

de RMSE waarde is hoger dan de vorige techniek, waaruit duidelijk blijkt dat lineaire regressie slecht heeft gepresteerd. Laten we eens kijken naar de plot en begrijpen waarom lineaire regressie niet goed heeft gedaan:

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

lineaire regressie is een eenvoudige techniek en vrij gemakkelijk te interpreteren, maar er zijn een paar duidelijke nadelen. Een probleem bij het gebruik van regressiealgoritmen is dat het model overloopt naar de kolom datum en maand. In plaats van rekening te houden met de vorige waarden van het punt van voorspelling, zal het model rekening houden met de waarde van dezelfde datum een maand geleden, of dezelfde datum/maand een jaar geleden.

zoals Uit bovenstaande grafiek blijkt, was er voor januari 2016 en januari 2017 een daling van de aandelenkoers. Het model heeft hetzelfde voorspeld voor januari 2018. Een lineaire regressie techniek kan goed presteren voor problemen zoals Big Mart sales waar de onafhankelijke functies zijn nuttig voor het bepalen van de streefwaarde.

k-Dichtstbijzijnde buren

Inleiding

een ander interessant ML-algoritme dat men hier kan gebruiken is kNN (K dichtstbijzijnde buren). Op basis van de onafhankelijke variabelen vindt kNN de overeenkomst tussen nieuwe datapunten en oude datapunten. Laat me dit uitleggen met een eenvoudig voorbeeld.

Houd rekening met de lengte en leeftijd van 11 personen. Op basis van bepaalde kenmerken (‘leeftijd’ en ‘hoogte’) kan de tabel worden weergegeven in een grafisch formaat zoals hieronder weergegeven:

om het gewicht voor ID #11 te bepalen, houdt kNN rekening met het gewicht van de dichtstbijzijnde buren van dit ID. Het gewicht van ID # 11 is naar verwachting het gemiddelde van zijn buren. Als we drie buren (k=3) voor nu, het gewicht voor ID # 11 zou zijn = (77+72+60)/3 = 69.66 kg.

voor een gedetailleerd begrip van de kNN, kunt u verwijzen naar de volgende artikelen:

  • Inleiding tot k-Dichtstbijzijnde buren: Vereenvoudigd

  • Een Praktische Inleiding tot het K-Nearest Neighbors Algoritme voor Regressie

Uitvoering

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

Met dezelfde trein en validatie set van de laatste sectie:

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

Resultaten

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

Er is niet een groot verschil in de RMSE-waarde, maar een plot voor de voorspelde en werkelijke waarden moeten zorgen voor een meer helder inzicht.

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

gevolgtrekking

de RMSE-waarde is bijna gelijk aan het lineaire regressiemodel en de plot toont hetzelfde patroon. Net als lineaire regressie identificeerde kNN ook een daling in januari 2018, omdat dat het patroon is voor de afgelopen jaren. We kunnen gerust zeggen dat regressiealgoritmen niet goed hebben gepresteerd op deze dataset.

laten we verder gaan en kijken naar enkele tijdreeksvoorspellingstechnieken om uit te vinden hoe ze presteren wanneer ze worden geconfronteerd met deze uitdaging voor de voorspelling van aandelenkoersen.

Auto ARIMA

Inleiding

ARIMA is een zeer populaire statistische methode voor het voorspellen van tijdreeksen. ARIMA modellen houden rekening met de waarden uit het verleden om de toekomstige waarden te voorspellen. Er zijn drie belangrijke parameters in ARIMA:

  • p (waarden uit het verleden gebruikt voor het voorspellen van de volgende waarde)
  • q (fouten uit het verleden gebruikt voor het voorspellen van de toekomstige waarden)
  • d (volgorde van verschilbepaling)

Parameterafstemming voor ARIMA kost veel tijd. Zo zullen we auto ARIMA gebruiken die automatisch de beste combinatie van (p,q,d) selecteert die de minste fout biedt. Om meer te lezen over hoe auto ARIMA werkt, zie dit artikel:

  • Bouw High Performance Tijdreeksmodellen met behulp van Auto ARIMA

implementatie

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

resultaten

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)

gevolgtrekking

zoals we eerder zagen, gebruikt een auto ARIMA-model gegevens uit het verleden om het patroon in de tijdreeks te begrijpen. Met behulp van deze waarden, het model vastgelegd een stijgende trend in de serie. Hoewel de voorspellingen met behulp van deze techniek zijn veel beter dan die van de eerder geïmplementeerde machine learning modellen, deze voorspellingen zijn nog steeds niet dicht bij de echte waarden.

zoals blijkt uit het plot, heeft het model een trend in de serie vastgelegd, maar richt het zich niet op het seizoengedeelte. In de volgende sectie zullen we een tijdreeksmodel implementeren dat zowel de trend als de seizoensgebondenheid van een reeks in aanmerking neemt.

Prophet

Inleiding

er zijn een aantal tijdreekstechnieken die kunnen worden geà mplementeerd op de voorraadvoorspellingsdataset, maar de meeste van deze technieken vereisen veel gegevensvoorbereiding voordat het model wordt toegepast. Prophet, ontworpen en pionier door Facebook, is een tijdreeksvoorspellingbibliotheek die geen gegevensvoorverwerking vereist en is uiterst eenvoudig te implementeren. De invoer voor Prophet is een dataframe met twee kolommen: datum en doel (ds en y).Prophet probeert de seizoensgebonden gegevens uit het verleden vast te leggen en werkt goed wanneer de dataset groot is. Hier is een interessant artikel dat profeet op een eenvoudige en intuïtieve manier uitlegt:

  • genereer snelle en nauwkeurige Tijdreeksvoorspellingen met behulp van Facebook ‘ s Prophet.

uitvoering

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

resultaten

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

gevolgtrekking

Prophet (zoals de meeste tijdreeksvoorspellingstechnieken) probeert de trend en seizoensgebondenheid vast te leggen op basis van gegevens uit het verleden. Dit model presteert meestal goed op tijdreeksdatasets, maar voldoet in dit geval niet aan zijn reputatie.

het blijkt dat de aandelenkoersen geen specifieke trend of seizoensgebondenheid vertonen. Het hangt sterk af van wat er op dit moment op de markt gebeurt en dus van de prijzen die stijgen en dalen. Vandaar dat voorspellingstechnieken zoals ARIMA, SARIMA en Prophet geen goede resultaten zouden laten zien voor dit specifieke probleem.

laten we een andere geavanceerde techniek proberen – Long Short Term Memory (LSTM).

Long Short Term Memory (LSTM)

Inleiding

LSTM ‘ s worden veel gebruikt voor sequentievoorspellingsproblemen en zijn zeer effectief gebleken. De reden dat ze zo goed werken is omdat LSTM in staat is om belangrijke informatie uit het verleden op te slaan en de informatie te vergeten die dat niet is. LSTM heeft drie poorten:

  • de invoerpoort: De input gate voegt informatie toe aan de cel staat
  • De vergeet-gate: Het verwijdert de gegevens die niet langer nodig zijn de door het model
  • De output poort: Output Poort op LSTM selecteert de informatie die moet worden weergegeven als output

Voor een meer gedetailleerd inzicht van LSTM en de architectuur, kan je via het onderstaande artikel:

  • Inleiding tot de Lange met het Korte Termijn Geheugen

Voor nu, laat ons implementeren LSTM als een black box en het controleren van de prestaties op onze specifieke gegevens.

Uitvoering

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

Resultaten

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

Gevolgtrekking

Wow! Het LSTM-model kan worden afgestemd op verschillende parameters, zoals het wijzigen van het aantal LSTM-lagen, het toevoegen van uitvalwaarde of het verhogen van het aantal tijdperken. Maar zijn de voorspellingen van LSTM voldoende om te bepalen of de aandelenkoers zal stijgen of dalen? Zeker niet!

zoals ik aan het begin van het artikel al zei, wordt de aandelenkoers beïnvloed door het nieuws over het bedrijf en andere factoren zoals de demonetisering of fusie/splitsing van de bedrijven. Er zijn ook bepaalde immateriële factoren die vaak op voorhand niet te voorspellen zijn.

End Notes

tijdreeksvoorspelling is een zeer intrigerend veld om mee te werken, zoals ik me realiseerde tijdens het schrijven van deze artikelen. Er is een perceptie in de Gemeenschap dat het een complex veld is, en hoewel er een korrel van waarheid in zit, is het niet zo moeilijk als je eenmaal de basistechnieken onder de knie hebt.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.