
機器學習和深度學習已經在金融機構中找到了自己的位置,因為它們能夠以高精度預測時間序列資料,并且工程師們仍在繼續研究以使模型更好。這篇文章是我使用機器學習來預測股票價格的入門項目。
它基于我的項目
AlphaAI,這是一個堆疊的神經網絡架構,可以預測各個公司的股票價格。該項目是2018年iNTUtion的決賽項目之一。
工作流程
該項目的工作流程基本上是以下步驟:
1.擷取股票價格資料;
2.使用小波變換去噪資料;
3.使用Stacked Autoencoders提取特征;
4.使用特征訓練LSTM;
5.測試預測準确性的模型;
在這篇文章中,我将詳細介紹每個步驟以及為什麼做出某些決定。
1.資料采集
pandas_datareader
是
借助雅虎财經的API,它可以很容易獲得股票價格資料,隻需使用以下指令即可完成:
stock_data = pdr.get_data_yahoo(self.ticker, self.start, self.end)
2.資料去噪
由于股票市場動态的複雜性,股票價格資料通常充滿了可能分散機器學習算法分散趨勢和結構的噪聲。是以,删除一些噪聲是符合我們的訴求,同時也可以保留資料中的趨勢和結構。起初,我想使用傅裡葉變換(不熟悉的人應該
閱讀這篇文章),但我認為小波變換可能是保留資料時間因素的更好選擇,而不是僅産生基于頻率的輸出。
小波變換
小波變換與傅立葉變換密切相關,隻是用于變換的函數是不同的,并且這種變換發生的方式也略有不同。
過程如下:
1.使用小波變換來變換資料;
2.消除超過完全标準偏差的系數(在所有系數中);
3.反變換新系數以獲得去噪資料;
以下是小波變換如何對時間序列資料進行去噪的示例:
如你所見,在去噪版本中不存在初始信号中存在的随機噪聲,這正是我們要檢視的股票價格資料。
這是去噪資料的代碼:
x = np.array(self.stock_data.iloc[i: i + 11, j])
(ca, cd) = pywt.dwt(x, "haar")
cat = pywt.threshold(ca, np.std(ca), mode="soft")
cdt = pywt.threshold(cd, np.std(cd), mode="soft")
tx = pywt.idwt(cat, cdt, "haar")
該庫
pywt
非常适合小波變換,這也極大地減輕了我的負擔。
3.提取特征
在大多數機器學習環境中,提取特征需要專家領域知識,這是我沒有的奢侈品。我或許可以嘗試使用某種形式的技術名額,如平均線或平均收斂差異(MACD)或動量名額,但我覺得盲目地使用它可能不是最優的。
但是,通過使用堆疊自動編碼器或其他機器學習算法(如受限的Boltzmann機器),可以實作自動特征提取。由于編碼的可解釋性與限制Boltzmann機器的機率相比,我選擇使用堆疊自動編碼器。
堆疊式自動編碼器
從本質上講,堆疊式自動編碼器非常适合壓縮資料并再次複制資料。我們感興趣的是壓縮部分,因為它意味着重制資料所需的資訊以某種方式以壓縮形式編碼。這表明這些壓縮資料在某種程度上可能是我們試圖從中提取特征的資料的特征。以下是堆疊自動編碼器的網絡結構:
輸入資料被壓縮成所需的許多神經元,并且網絡被迫使用自動編碼器重建初始資料。這會強制模型提取資料的關鍵元素,我們可以将其解釋為要素。需要注意的一點是,由于沒有輸入輸出對,這個模型實際上屬于無監督學習,但輸入和輸出其實都是相同的。
我們可以使用
keras
建構這樣的模型。
class AutoEncoder:
def __init__(self, encoding_dim):
self.encoding_dim = encoding_dim
def build_train_model(self, input_shape, encoded1_shape, encoded2_shape, decoded1_shape, decoded2_shape):
input_data = Input(shape=(1, input_shape))
encoded1 = Dense(encoded1_shape, activation="relu", activity_regularizer=regularizers.l2(0))(input_data)
encoded2 = Dense(encoded2_shape, activation="relu", activity_regularizer=regularizers.l2(0))(encoded1)
encoded3 = Dense(self.encoding_dim, activation="relu", activity_regularizer=regularizers.l2(0))(encoded2)
decoded1 = Dense(decoded1_shape, activation="relu", activity_regularizer=regularizers.l2(0))(encoded3)
decoded2 = Dense(decoded2_shape, activation="relu", activity_regularizer=regularizers.l2(0))(decoded1)
decoded = Dense(input_shape, activation="sigmoid", activity_regularizer=regularizers.l2(0))(decoded2)
autoencoder = Model(inputs=input_data, outputs=decoded)
encoder = Model(input_data, encoded3)
# Now train the model using data we already preprocessed
autoencoder.compile(loss="mean_squared_error", optimizer="adam")
train = pd.read_csv("preprocessing/rbm_train.csv", index_col=0)
ntrain = np.array(train)
train_data = np.reshape(ntrain, (len(ntrain), 1, input_shape))
# print(train_data)
# autoencoder.summary()
autoencoder.fit(train_data, train_data, epochs=1000)
我使用從2000年到2008年的去噪股票價格資料訓練了自動編碼器。經過1000個epoch的訓練後,RMSE降至0.9左右。然後,我使用該模型将剩餘的股票價格資料編碼為特征。
4. LSTM模型
LSTM模型不需要介紹,因為它在預測時間序列中變得非常普遍和流行。它從細胞狀态的存在中獲得了卓越的預測能力,使其能夠了解和學習資料的長期趨勢。這對我們的股票價格資料尤為重要,下面我将讨論我認為重要的設計選擇的某些方面。
優化器
所使用的優化器類型可以極大地影響算法收斂到最小值的速度。此外,重要的是存在一些随機性概念,以避免陷入局部最小值且未達到全局最小值。這其中有一些很棒的算法,但我選擇使用Adam優化器。Adam優化器成功的結合了另外兩個優化器的優勢:ADAgrad和RMSprop。
ADAgrad優化器基本上對每個參數和每個時間步使用不同的學習速率。ADAgrad背後的問題是:不常見的參數必須具有較大的學習率,而頻繁的參數必須具有較小的學習率。換句話說,ADAgrad的随機梯度下降更新成為:
,其中
。
基于已經為每個參數計算的過去梯度來計算學習速率。是以,
其中G是過去梯度平方和的矩陣,這種優化的問題是随着疊代次數的增加,學習率開始迅速消失。
RMSprop考慮通過僅使用一定數量的先前梯度來固定遞減的學習速率。更新成為
其中
既然我們已經了解了這兩個優化器是如何工作的,那麼我們可以研究一下Adam的工作方式。
自适應矩估計(Adam)是另一種通過考慮過去平方梯度的指數衰減平均值來計算每個參數的自适應學習率的方法。這可以表示為
v和m可以分别被認為是梯度的第一和第二時刻的估計,是以得到自适應矩估計的名稱。當這是第一次使用時,研究人員觀察到存在0的固有偏差,他們通過使用以下估計來反駁這一點:
這導緻我們進入最終的梯度更新規則
這是我使用的優化器,其好處總結如下:
1. 每個參數和每次疊代的學習率都不同;
2. 與ADAgrad一樣,學習并沒有減少;
3. 梯度更新使用權重分布矩陣。
正則化
訓練模型的另一個重要方面是確定權重不會太大并關注一個資料點,或者稱為過度拟合。是以我們應該對大權重設定懲罰(大的程度取決于所使用的正常者的類型)。我選擇使用Tikhonov正則化,可以将其視為以下最小化問題:
函數空間在再生核Hilbert空間(RKHS)中確定了規範的概念存在。這允許我們将規範的概念編碼到我們的正則化器中。
Dropout
一種新的防止過度拟合的方法,具體用在當一些神經元突然不起作用時會發生什麼。這迫使模型不要過度依賴任何神經元組,而是考慮所有這些神經元。dropout已經發現它們可以使神經元更加健壯,進而使它們能夠預測趨勢,而無需關注任何一個神經元。以下是使用dropout的結果:
5.模型實施
上述所有分析都可以在keras及其功能API輕松地實作。這是模型的代碼(檢視整個代碼,檢視我的GitHub:
)
class NeuralNetwork:
def __init__(self, input_shape, stock_or_return):
self.input_shape = input_shape
self.stock_or_return = stock_or_return
def make_train_model(self):
input_data = kl.Input(shape=(1, self.input_shape))
lstm = kl.LSTM(5, input_shape=(1, self.input_shape), return_sequences=True, activity_regularizer=regularizers.l2(0.003),
recurrent_regularizer=regularizers.l2(0), dropout=0.2, recurrent_dropout=0.2)(input_data)
perc = kl.Dense(5, activation="sigmoid", activity_regularizer=regularizers.l2(0.005))(lstm)
lstm2 = kl.LSTM(2, activity_regularizer=regularizers.l2(0.01), recurrent_regularizer=regularizers.l2(0.001),
dropout=0.2, recurrent_dropout=0.2)(perc)
out = kl.Dense(1, activation="sigmoid", activity_regularizer=regularizers.l2(0.001))(lstm2)
model = Model(input_data, out)
model.compile(optimizer="adam", loss="mean_squared_error", metrics=["mse"])
# load data
train = np.reshape(np.array(pd.read_csv("features/autoencoded_train_data.csv", index_col=0)),
(len(np.array(pd.read_csv("features/autoencoded_train_data.csv"))), 1, self.input_shape))
train_y = np.array(pd.read_csv("features/autoencoded_train_y.csv", index_col=0))
# train_stock = np.array(pd.read_csv("train_stock.csv"))
# train model
model.fit(train, train_y, epochs=2000)
結果
這些是我對各公司的預測結果。
對于雪佛龍來說,MSE是2.11
對于埃克森美孚,MSE為0.0945
很明顯,使用這種神經網絡架構的結果令人印象深刻,并且如果實施到政策中可以是有利可圖的。
線上學習
除了從曆史資料中學習模型之外,我還想讓模型實時學習,甚至從預測中學習。是以,我已經使它成為一個學習和預測的線上模型。換句話說,它可以學習曆史資料,預測明天的價格,另外當實際價格已知時,它也會學習使用它。是以模型總是在改進。
除了使用實際價格來改善之外,我還考慮制作一個二級模型,該模型使用關于公司的新聞和Twitter的情緒值。我将首先概述如何擷取這些資料。
Twitter資料
除了股票價格資料,我還想嘗試一些自然語言處理。是以,我嘗試深入研究使用來自Twitter和新聞的情緒資料來改進股票預測。
第一個鬥争就是免費擷取推文,因為擷取整個實時資料的Twitter API已經被禁止。但是,我找到了一個允許我在過去10天内擷取推文的API,然後我可以實作某種形式的NLP來從推文中提取情緒資料。這不是最佳的,但對我的線上學習模型仍然有用。
新聞資料
與Twitter類似,擷取新聞資料非常困難。我嘗試分析彭博文章的網址,但實作從2000年手動報廢網站幾乎是不可能的。是以,我選擇了具有相當強大的抓取模型的Aylien
API。
這些新聞文章被删除的條件是他們隻包括股票和财經新聞,過濾到前150個Alexa網站,并且使用指數權重移動平均線平均情緒分數,以考慮最近的新聞而不是舊的新聞。
線上模型
鑒于我的情緒分數,我使用額外的神經網絡層來更正我的預測誤差。但是,在本文釋出時,結果不可用,因為生成一個資料點需要一天的時間。
結論
神經網絡非常善于預測時間序列資料,當與情感資料結合時,可以真正建立一個實用的模型。雖然這裡的結果令人印象深刻,但我仍然想方設法改進它,也許實際上可以從中制定完整的交易政策。目前,我正在研究使用強化學習來開發一個使用預測模型結果的交易代理。
本文由
阿裡雲雲栖社群組織翻譯。
文章原标題《using-machine-learning-to-predict-stock-prices》
作者:
Vivek Palaniappan譯者:虎說八道,審校:。
文章為簡譯,更為詳細的内容,請檢視
原文