使用機器學習來預測股票價格

摘要: 用機器學習來把股價走勢安排的明明白白!git

機器學習和深度學習已經在金融機構中找到了本身的位置,由於它們可以以高精度預測時間序列數據,而且工程師們仍在繼續研究以使模型更好。這篇文章是我使用機器學習來預測股票價格的入門項目。github

它基於個人項目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:AlphaAI

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網站,而且使用指數加權移動平均線平均情緒分數,以考慮最近的新聞而不是舊的新聞。

在線模型

鑑於個人情緒分數,我使用額外的神經網絡層來更正個人預測偏差。可是,在本文發佈時,結果不可用,由於生成一個數據點須要一天的時間。

結論

神經網絡很是善於預測時間序列數據,當與情感數據結合時,能夠真正創建一個實用的模型。雖然這裏的結果使人印象深入,但我仍然千方百計改進它,也許實際上能夠從中制定完整的交易策略。目前,我正在研究使用強化學習來開發一個使用預測模型結果的交易代理。

原文連接

相關文章
相關標籤/搜索