Przewidywanie cen akcji przy użyciu uczenia maszynowego i technik uczenia głębokiego (z kodami Pythona)

wprowadzenie

przewidywanie wyników na giełdzie jest jedną z najtrudniejszych rzeczy do zrobienia. W przewidywaniu bierze udział tak wiele czynników-czynniki fizyczne kontra zachowania fiszologiczne, racjonalne, irracjonalne itp. Wszystkie te aspekty sprawiają, że ceny akcji są zmienne i bardzo trudne do przewidzenia z dużą dokładnością.

Czy możemy wykorzystać uczenie maszynowe jako przełom w tej dziedzinie? Korzystanie z funkcji, takich jak najnowsze ogłoszenia o organizacji, ich kwartalne wyniki przychodów itp., techniki uczenia maszynowego mają potencjał do odkrywania wzorców i spostrzeżeń, których wcześniej nie widzieliśmy, a te mogą być wykorzystane do bezbłędnie dokładnych prognoz.

przewidywanie cen akcji, LSTM, uczenie maszynowe

w tym artykule będziemy pracować z danymi historycznymi dotyczącymi cen akcji spółki notowanej na giełdzie. Wdrożymy kombinację algorytmów uczenia maszynowego, aby przewidzieć przyszłą cenę akcji tej firmy, zaczynając od prostych algorytmów, takich jak uśrednianie i regresja liniowa, a następnie przejdziemy do zaawansowanych technik, takich jak Auto ARIMA i LSTM.

główną ideą tego artykułu jest pokazanie, w jaki sposób algorytmy te są implementowane. Krótko opiszę technikę i podam odpowiednie linki, aby odświeżyć koncepcje w razie potrzeby. Jeśli jesteś nowicjuszem w świecie serii czasu, proponuję najpierw przejrzeć następujące artykuły:

  • kompleksowy przewodnik dla początkujących do tworzenia prognozy szeregów czasowych
  • kompletny samouczek na temat modelowania szeregów czasowych
  • darmowy kurs: Prognozowanie szeregów czasowych za pomocą Pythona

projekt do praktyki prognozowania szeregów czasowych

prognozowanie szeregów czasowych & modelowanie odgrywa ważną rolę w analizie danych. Analiza szeregów czasowych to wyspecjalizowana gałąź statystyki szeroko stosowana w takich dziedzinach jak Ekonometria & Badania operacyjne.

Szeregi czasowe są szeroko stosowane w analityce & Data science. Jest to specjalnie zaprojektowany problem szeregów czasowych dla Ciebie, a wyzwaniem jest prognozowanie ruchu.

Ćwicz teraz

jesteś początkującym i szukasz miejsca na rozpoczęcie przygody z danymi? Prezentujemy kompleksowy kurs, pełen wiedzy i Nauki o danych, przygotowany specjalnie dla Ciebie! Ten kurs obejmuje wszystko, od podstaw uczenia maszynowego po zaawansowane koncepcje ML, głębokie uczenie i Szeregi czasowe.

  • certyfikat AI & ML Blackbelt + Program

spis treści

    1. zrozumienie problemu
    2. średnia ruchoma
    3. regresja liniowa
    4. K-najbliżsi sąsiedzi
    5. Auto ARIMA
    6. Prorok
    7. pamięć długo-krótkotrwała (LSTM)

zrozumienie problemu

wkrótce zajmiemy się częścią implementacji tego artykułu, ale najpierw ważne jest ustalenie, co zamierzamy rozwiązać. Ogólnie rzecz biorąc, analiza giełdowa dzieli się na dwie części – analizę fundamentalną i analizę techniczną.

  • Analiza fundamentalna polega na analizie przyszłej rentowności firmy na podstawie jej obecnego otoczenia biznesowego i wyników finansowych.
  • Analiza Techniczna, z drugiej strony, obejmuje czytanie wykresów i wykorzystanie danych statystycznych do identyfikacji trendów na giełdzie.

jak można się domyślić, skupimy się na części analizy technicznej. Będziemy korzystać z zestawu danych z Quandl (dane historyczne dla różnych zapasów można znaleźć tutaj) i dla tego konkretnego projektu, użyłem danych dla „Tata Global Beverages”. Czas zanurkować!

Uwaga: oto zestaw danych, których użyłem do kodu: Pobierz

najpierw załadujemy zestaw danych i zdefiniujemy zmienną docelową dla problemu:

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

w zbiorze danych znajduje się wiele zmiennych – date, open, high, low, last, close, total_trade_quantity i turnover.

  • kolumny otwierające i zamykające reprezentują początkową i końcową cenę, po której akcje są przedmiotem obrotu w danym dniu.
  • wysoka, niska i Ostatnia oznaczają maksymalną, minimalną i ostatnią cenę akcji na dany dzień.
  • całkowita ilość transakcji to liczba akcji kupionych lub sprzedanych w danym dniu, a obroty (Lac) to obroty danej spółki w danym dniu.

kolejną ważną rzeczą jest to, że rynek jest zamknięty w weekendy i święta.Zwróć uwagę na powyższą tabelę ponownie, brakuje niektórych wartości dat-2/10/2018, 6/10/2018, 7/10/2018. Z tych dat, 2nd jest świętem narodowym, podczas gdy 6th i 7th jesień w weekend.

obliczenie zysku lub straty jest zwykle określane przez cenę zamknięcia akcji na dany dzień, dlatego uznamy cenę zamknięcia za zmienną docelową. Narysujmy zmienną docelową, aby zrozumieć, jak kształtuje się ona w naszych danych:

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

w nadchodzących sekcjach zbadamy te zmienne i użyjemy różnych technik do przewidywania dziennej ceny zamknięcia akcji.

średnia ruchoma

wprowadzenie

’średnia’ jest łatwo jedną z najczęstszych rzeczy, których używamy w naszym codziennym życiu. Na przykład, obliczanie średnich ocen w celu określenia ogólnej wydajności lub znalezienie średniej temperatury z ostatnich kilku dni, aby uzyskać pojęcie o dzisiejszej temperaturze – to wszystko są rutynowe zadania, które wykonujemy regularnie. Jest to dobry punkt wyjścia do wykorzystania w naszym zbiorze danych do tworzenia prognoz.

przewidywana cena zamknięcia dla każdego dnia będzie średnią z zestawu wcześniej zaobserwowanych wartości. Zamiast używać prostej średniej, będziemy używać techniki średniej ruchomej, która wykorzystuje najnowszy zestaw wartości dla każdej prognozy. Innymi słowy, dla każdego kolejnego kroku przewidywane wartości są brane pod uwagę podczas usuwania najstarszej obserwowanej wartości z zestawu. Oto prosta figura, która pomoże Ci zrozumieć to z większą przejrzystością.

zaimplementujemy tę technikę w naszym zbiorze danych. Pierwszym krokiem jest stworzenie ramki danych, która zawiera tylko kolumny daty i ceny zamknięcia, a następnie podziel ją na zestawy pociągów i walidacji, aby zweryfikować nasze prognozy.

implementacja

samo sprawdzenie RMSE nie pomaga nam w zrozumieniu działania modelu. Wyobraźmy to sobie, aby uzyskać bardziej intuicyjne zrozumienie. Oto wykres przewidywanych wartości wraz z wartościami rzeczywistymi.

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

wnioskowanie

wartość RMSE jest bliska 105, ale wyniki nie są zbyt obiecujące (jak można zebrać z wykresu). Przewidywane wartości mają taki sam zakres, jak wartości obserwowane w zestawie pociągów (początkowo występuje tendencja wzrostowa, a następnie powolny spadek).

w następnej sekcji przyjrzymy się dwóm powszechnie stosowanym technikom uczenia maszynowego – regresji liniowej i kNN i zobaczymy, jak działają na naszych danych giełdowych.

regresja liniowa

wprowadzenie

najbardziej podstawowym algorytmem uczenia maszynowego, który można zaimplementować na tych danych, jest regresja liniowa. Model regresji liniowej zwraca równanie, które określa zależność między zmiennymi niezależnymi a zmienną zależną.

równanie regresji liniowej można zapisać jako:

tutaj, x1, x2,….xn reprezentują zmienne niezależne, podczas gdy współczynniki θ1, θ2, …. θn reprezentuje wagi. Możesz zapoznać się z poniższym artykułem, aby dokładniej zbadać regresję liniową:

  • kompleksowy przewodnik dla początkujących dla regresji liniowej, grzbietowej i Lasso.

dla naszej instrukcji problemu nie mamy zestawu niezależnych zmiennych. Zamiast tego mamy tylko daty. Użyjmy kolumny daty, aby wyodrębnić funkcje takie jak-Dzień, Miesiąc, Rok, pn/pt itp. następnie dopasuj model regresji liniowej.

implementacja

najpierw posortujemy zestaw danych w kolejności rosnącej, a następnie utworzymy osobny zestaw danych, aby każda nowa utworzona funkcja nie miała wpływu na oryginalne dane.

#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

tworzy to takie funkcje jak:

’Rok’, 'Miesiąc’, 'Tydzień’, 'dzień’, 'Dayofweek’, 'Dayofyear’, 'Is_month_end’, 'Is_month_start’, 'Is_quarter_end’, 'Is_quarter_start’, 'Is_year_end’, and 'Is_year_start’.

Uwaga: użyłem add_datepart z biblioteki fastai. Jeśli nie masz go zainstalowanego, możesz po prostu użyć polecenia pip install fastai. W przeciwnym razie możesz utworzyć te funkcje za pomocą pętli simple for w Pythonie. Poniżej pokazałem przykład.

oprócz tego możemy dodać własny zestaw funkcji, które naszym zdaniem byłyby istotne dla prognoz. Na przykład moja hipoteza jest taka, że pierwsze i ostatnie dni tygodnia mogą potencjalnie wpłynąć na cenę zamknięcia akcji znacznie bardziej niż pozostałe dni. Stworzyłem więc funkcję, która określa, czy dany dzień to Poniedziałek / Piątek, czy wtorek/środa / czwartek. Można to zrobić za pomocą następujących linii kodu:

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

jeśli dzień tygodnia jest równy 0 lub 4, wartość kolumny będzie równa 1, w przeciwnym razie 0. Podobnie, można utworzyć wiele funkcji. Jeśli masz jakieś pomysły na funkcje, które mogą być pomocne w przewidywaniu cen akcji, Podziel się nimi w sekcji komentarzy.

teraz podzielimy dane na zestawy pociągów i walidacji, aby sprawdzić wydajność modelu.

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

wyniki

#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

wartość RMSE jest wyższa niż poprzednia technika, co wyraźnie pokazuje, że regresja liniowa wykonała słabo. Spójrzmy na wykres i zrozumieć, dlaczego regresja liniowa nie zrobił dobrze:

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

wnioskowanie

regresja liniowa jest prostą techniką i dość łatwą do zinterpretowania, ale istnieje kilka oczywistych wad. Jednym z problemów w stosowaniu algorytmów regresji jest to, że model przerasta kolumnę daty i miesiąca. Zamiast brać pod uwagę poprzednie wartości z punktu predykcji, model weźmie pod uwagę wartość z tej samej daty miesiąc temu lub tej samej daty/miesiąc rok temu.

jak widać na powyższym wykresie, w styczniu 2016 r. i styczniu 2017 r. nastąpił spadek ceny akcji. Model przewidział to samo na styczeń 2018 roku. Technika regresji liniowej może wykonywać dobrze dla problemów, takich jak Big Mart sprzedaży gdzie niezależne funkcje są przydatne do określenia wartości docelowej.

k-najbliżsi sąsiedzi

wprowadzenie

innym ciekawym algorytmem ML, którego można tu użyć, jest kNN (K nearest neighbours). Na podstawie zmiennych niezależnych kNN wyszukuje podobieństwo między nowymi i starymi punktami danych. Wyjaśnię to prostym przykładem.

weź pod uwagę wzrost i wiek 11 osób. Na podstawie podanych cech („wiek” i „wzrost”) tabelę można przedstawić w formacie graficznym, jak pokazano poniżej:

aby określić wagę dla ID #11, kNN bierze pod uwagę wagę najbliższych sąsiadów tego ID. Przewiduje się, że waga ID #11 będzie średnią jego sąsiadów. Jeśli na razie weźmiemy pod uwagę trzech sąsiadów (k=3), Waga dla ID # 11 będzie wynosić = (77+72+60)/3 = 69.66 kg.

szczegółowe zrozumienie kNN można znaleźć w następujących artykułach:

  • Wprowadzenie do K-najbliżsi sąsiedzi: Uproszczone

  • praktyczne wprowadzenie do algorytmu K-najbliżsi sąsiedzi regresji

implementacja

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

przy użyciu tego samego pociągu i zestawu walidacji z ostatniej sekcji:

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

wyniki

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

nie ma dużej różnicy w wartości RMSE, ale wykres dla przewidywanych i rzeczywistych wartości powinien zapewnić bardziej jasne zrozumienie.

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

wnioskowanie

wartość RMSE jest prawie podobna do modelu regresji liniowej, a wykres pokazuje ten sam wzór. Podobnie jak regresja liniowa, kNN zidentyfikował również spadek w styczniu 2018, ponieważ był to wzór w ostatnich latach. Możemy śmiało powiedzieć, że algorytmy regresji nie sprawdziły się dobrze w tym zbiorze danych.

spójrzmy na niektóre techniki prognozowania szeregów czasowych, aby dowiedzieć się, jak działają w obliczu tego wyzwania dotyczącego prognozowania cen akcji.

Auto ARIMA

wprowadzenie

ARIMA jest bardzo popularną statystyczną metodą prognozowania szeregów czasowych. Modele ARIMA uwzględniają przeszłe wartości, aby przewidzieć przyszłe wartości. Istnieją trzy ważne parametry w ARIMA:

  • p (przeszłe wartości używane do prognozowania następnej wartości)
  • q (błędy przeszłości prognozy używane do przewidywania przyszłych wartości)
  • d (kolejność różnic)

strojenie parametrów dla ARIMA pochłania dużo czasu. Tak więc użyjemy auto ARIMA, który automatycznie wybiera najlepszą kombinację (P, q, d), która zapewnia najmniejszy błąd. Aby dowiedzieć się więcej o tym, jak działa auto ARIMA, zapoznaj się z tym artykułem:

  • Zbuduj wysokowydajne modele serii czasowych za pomocą Auto ARIMA

wdrożenie

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

wyniki

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)

wnioskowanie

jak widzieliśmy wcześniej, model auto ARIMA wykorzystuje dane przeszłe do zrozumienia wzorca w szeregach czasowych. Korzystając z tych wartości, model uchwycił rosnący trend w serii. Chociaż prognozy wykorzystujące tę technikę są znacznie lepsze niż we wcześniej wdrożonych modelach uczenia maszynowego, prognozy te nadal nie są zbliżone do rzeczywistych wartości.

jak wynika z fabuły, model uchwycił trend w serii, ale nie koncentruje się na części sezonowej. W następnej sekcji zaimplementujemy model szeregów czasowych, który uwzględnia zarówno trend, jak i sezonowość szeregu.

Prophet

wprowadzenie

istnieje wiele technik szeregów czasowych, które mogą być zaimplementowane w zestawie danych predykcyjnych, ale większość z tych technik wymaga dużo wstępnego przetwarzania danych przed dopasowaniem modelu. Prophet, zaprojektowany i pionierski przez Facebooka, jest biblioteką prognozowania szeregów czasowych, która nie wymaga wstępnego przetwarzania danych i jest niezwykle prosta do wdrożenia. Wejście dla Prophet to ramka danych z dwiema kolumnami: date i target (ds i y).

Prophet stara się uchwycić sezonowość danych z przeszłości i działa dobrze, gdy zbiór danych jest duży. Oto ciekawy artykuł, który wyjaśnia Proroka w prosty i intuicyjny sposób:

  • Generuj szybkie i dokładne prognozy szeregów czasowych za pomocą Proroka Facebooka.

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

wyniki

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

wnioskowanie

Prophet (jak większość technik prognozowania szeregów czasowych) próbuje uchwycić trend i sezonowość na podstawie danych z przeszłości. Ten model zwykle dobrze sprawdza się w zestawach danych szeregów czasowych, ale w tym przypadku nie spełnia swojej reputacji.

jak się okazuje, ceny akcji nie mają określonego trendu ani sezonowości. W dużym stopniu zależy to od tego, co obecnie dzieje się na rynku, a co za tym idzie, ceny rosną i spadają. Stąd techniki prognozowania, takie jak ARIMA, SARIMA i Prophet, nie dałyby dobrych rezultatów dla tego konkretnego problemu.

spróbujmy innej zaawansowanej techniki-pamięci długotrwałej (LSTM).

Long Short Term Memory (LSTM)

wprowadzenie

pamięci LSTM są szeroko stosowane do problemów z prognozowaniem sekwencji i okazały się niezwykle skuteczne. Powodem, dla którego działają tak dobrze, jest to, że LSTM jest w stanie przechowywać ważne informacje z przeszłości i zapominać o tych, które nie są. LSTM posiada trzy bramy:

  • brama wejściowa: Bramka wejściowa dodaje informacje do stanu komórki
  • bramka forget: usuwa informacje, które nie są już wymagane przez model
  • bramka wyjściowa: bramka wyjściowa w LSTM wybiera informacje, które mają być wyświetlane jako wyjście

aby dowiedzieć się więcej o LSTM i jego architekturze, zapoznaj się z poniższym artykułem:

  • Wprowadzenie do pamięci długo – krótkotrwałej

na razie zaimplementujmy LSTM jako czarną skrzynkę i sprawdźmy jego wydajność na naszych danych.

Realizacja

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

Wyniki

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

Wnioskowanie

Wow! Model LSTM może być dostrojony do różnych parametrów, takich jak zmiana liczby warstw LSTM, dodanie wartości dropout lub zwiększenie liczby epok. Ale czy prognozy LSTM są wystarczające, aby określić, czy cena akcji wzrośnie, Czy spadnie? Na pewno nie!

jak wspomniałem na początku artykułu, na cenę akcji wpływają wiadomości o firmie i inne czynniki, takie jak demonetyzacja lub fuzja/podział spółek. Istnieją również pewne czynniki niematerialne, które często mogą być niemożliwe do przewidzenia z góry.

Uwagi końcowe

prognozowanie szeregów czasowych jest bardzo intrygującą dziedziną pracy, jak zdałem sobie sprawę podczas pisania tych artykułów. W społeczności panuje przekonanie, że jest to złożona dziedzina i chociaż jest w niej ziarno prawdy, nie jest to takie trudne, gdy opanujesz podstawowe techniki.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.