RNN實戰:股票預測2

【方向】發表於2017-12-18

       完整的工作程式碼可在github.com/lilianweng/stock-rnn找到

       RNN實戰part1:股市預測

       在第2部分的教程中,將繼續探討股票預測的話題,在第一部分我增添了一個迴圈神經網路(RNN),並賦予它應對多個股票價格預測的能力。為了區分與不同價格序列相關聯的模式,我用股票符號嵌入向量作為輸入的一部分。

資料集

       在搜尋過程中,我找到了用來查詢雅虎!金融API的。如果雅虎沒有關閉獲取歷史資料的API,那麼這個庫是有用的。在本文中,我選擇了谷歌財經的一個連結,其中提供了一些可以被下載股票歷史價格資訊的免費資料資源。

獲取資料的程式碼可以寫成如下簡單形式:

1

2

3

4

5

6

7

8

importurllib2

fromdatetimeimport datetime

BASE_URL =“https://www.google.com/finance/historical?”

“output=csv&q={0}&startdate=Jan+1%2C+1980&enddate={1}”

symbol_url = BASE_URL.format(

    urllib2.quote(`GOOG`), # Replace with any stock you are interested.

    urllib2.quote(datetime.now().strftime(“%b+%d,+%Y”), `+`)

)


       當獲取內容時,記得新增try-catch語句塊,以防連結失敗或者提供的股票程式碼失效。

1

2

3

4

5

6

try:

    f = urllib2.urlopen(symbol_url)

withopen(“GOOG.csv”, `w`) as fin:

print>> fin, f.read()

except urllib2.HTTPError:

print“Fetching Failed: {}”.format(symbol_url)

    獲取完整的資料採集實現程式碼請點這裡

模型構建

       該模型預期用來學習不同股票的價格序列。由於不同的底層模式,我要明確地告訴模型它正在處理哪隻股票。嵌入(Embedding)比one-hot編碼更受歡迎,原因是:

1.給出的訓練集包含N個股票,one-hot編碼將引入N個(或N-1個)額外的稀有特徵維度。一旦每個股票程式碼被對映到一個小得多的長度為k的對映向量,k<<N,那麼結果就是採用一個更多的壓縮形式和更小的資料集。

2.因為對映向量是用來學習的變數,所以類似的股票可以與類似的對映相關聯,並且可以幫助預測其它的股票,比如“GOOG”和“GOOGL”,之後將在下圖中可以看到。

在迴圈神經網路中,取一個時間點t處,輸入向量包括input_size(標記為w)第一批股票每日價格值 (pi,tw,pi,tw+1,…,pi,(t+1)w1)。股票程式碼被唯一的嵌入到一個長度向量embedding_size(標記為k)(ei,0,ei,1,…,ei,k)。如下圖所示,價格向量與對映向量關聯在一起,然後傳送到長短期記憶網路(LSTM)單元。

       另一種選擇是將嵌入向量與長短期記憶網路(LSTM)單元相關聯,並且在輸出層學習新的權重W和偏差b。然而,在這種方式下,LSTM單元就只能得出一個股票的價格而無法得出其它的價格了,並且它的能力將受到很大程度的限制。

rnn_with_embedding.png

圖.具有股票符號對映的RNN(股票價格預測迴圈神經網路)模型的架構。

RNNConfig中新增了兩個新的配置環境變數:

·embedding_size 控制每個嵌入向量的大小;

·stock_symbol_size指資料集中單股的數量。

這兩個環境變數共同定義了嵌入矩陣的大小,以滿足模型必須學習embedding_size×stock_symbol_size結果的格外變數,來與Part1的模型進行比較。

1

2

3

4

classRNNConfig():

# … old ones

   embedding_size =8

   stock_symbol_size =100

定義圖形

(1)如Part1所講的:定義圖形,首先讓我們定義一個名為lstm_graph的tf.Graph()和一組張量(tensors),以同樣的方式儲存輸入資料,inputs,targets和learning_rate。另一個用來定義的佔位符是一個與輸入價格相關的股票程式碼列表。在用標籤編碼(label encoding)之前,這些股票程式碼已經分別被對映成唯一的整數。

1

2

# Mapped to an integer. one label refers to one stock symbol.

    stock_labels = tf.placeholder(tf.int32, [None, 1])

(2)然後我們需要建立一個嵌入矩陣作為一個查詢表,表中包含了所有股票的嵌入向量。矩陣用-1到1之間的隨機數進行初始化,並在訓練資料期間更新。

# Don’t forget: config = RNNConfig()

# Convert the integer labels to numeric embedding vectors.

    embedding_matrix = tf.Variable(

        tf.random_uniform([config.stock_symbol_size, config.embedding_size], -1.0, 1.0)

    )

(3)重複股票標籤num_steps的次數以在訓練期間來匹配RNN(迴圈神經網路)的展開版本和inputs張量的形狀。轉換操作tf.tile獲得一個基礎張量,並通過多次)重複以確定的維度來建立一個新的張量;嚴格的來說就是輸入張量的第i個維度乘以變數multiples[i]的倍數。例如,如果變數stock_labels [[0],[0],[2],[1]],那麼與[1,5]做相關計算,則產生 [[0 0 0 0 0],[0 0 0 0 0]) [2 2 2 2 2],[1 1 1 1 1 1]]。

1

    stacked_stock_labels = tf.tile(stock_labels, multiples=[1, config.num_steps])

(4) 然後根據查詢表embedding_matrix將符號對映到對映向量

1

2

# stock_label_embeds.get_shape() = (?, num_steps, embedding_size).

    stock_label_embeds = tf.nn.embedding_lookup(embedding_matrix, stacked_stock_labels)

 

(5)最後,將價格的值與嵌入向量結合起來。tf.concat的操作沿著維度變數axis與張量列表連線。在這個例子中,我們希望保持批量和步驟的數量不變,但只擴充套件輸入向量的變數input_size的長度以包含對映特徵。

# inputs.get_shape() = (?, num_steps, input_size)

# stock_label_embeds.get_shape() = (?, num_steps, embedding_size)

# inputs_with_embed.get_shape() = (?, num_steps, input_size + embedding_size)

    inputs_with_embed = tf.concat([inputs, stock_label_embeds], axis=2)

其餘程式碼執行動態RNN,提取LSTM單元的最後狀態,並控制輸出層中的權重和偏差,詳情請參閱Part1。

訓練會話

       如果你不知道在TensorFlow中如何執行一個訓練會話,請閱讀Part1:開始訓練會話。

向圖形提供資料之前,股票符號應被轉換成具有獨立標籤編碼的整數。

1

2

3

fromsklearn.preprocessingimportLabelEncoder

label_encoder=LabelEncoder()

label_encoder.fit(list_of_symbols)

對每個個股來說,需要保持訓練/測試分流比不變,90%用於訓練,10%用於測試。

視覺化圖形

       用程式碼定義圖片後,讓我們檢查下Tensorboard 中的視覺化情況以確保元件的構造是正確的。從本質上看,它非常像圖1中的架構圖解。

rnn_with_embedding_tensorboard.png

圖二,以上定義了圖形的Tensorboard視覺化。“train”和“save”兩個模組已經從主圖中刪除了。

       不同於展現圖形結構或者及時跟蹤變數,Tensorboard 也支援對映視覺化。為了將對映值傳送到Tensorboard 中,我們需要增加適當的跟蹤日誌。

(0)在我的對映視覺化中,我想用行業領域來用顏色區分每個股票。後設資料應該儲存在CSV檔案中。此檔案有股票標識和行業領域兩列。CSV檔案有沒有標題不重要,重要的是股票列表順序必須與label_encoder.classes一致。

1

2

3

4

5

6

importcsvembedding_metadata_path=os.path.join(your_log_file_folder,`metadata.csv`)withopen(embedding_metadata_path,`w`)asfout:

csv_writer=csv.writer(fout)

# write the content into the csv file.

# for example, csv_writer.writerows([“GOOG”, “information_technology”])

(1)在訓練的tf.Session變數中首先設定摘要作者。

1

2

3

4

fromtensorflow.contrib.tensorboard.pluginsimportprojectorwithtf.Session(graph=lstm_graph)assess:

summary_writer=tf.summary.FileWriter(your_log_file_folder)

summary_writer.add_graph(sess.graph)

(2)將圖lstm_graph中定義的張量embedding_matrix新增到projector配置變數中,並附上後設資料CSV的檔案路徑。

1

2

3

4

5

6

projector_config=projector.ProjectorConfig()

# You can add multiple embeddings. Here we add only one.

added_embedding=projector_config.embeddings.add()

added_embedding.tensor_name=embedding_matrix.name

# Link this tensor to its metadata file.

added_embedding.metadata_path=embedding_metadata_path

(3)這行程式碼是在your_log_file_folder資料夾下新建了檔案projector_config.pbtxt。TensorBoard 將在啟動時讀取該檔案。

1

projector.visualize_embeddings(summary_writer,projector_config)

結果集

該模型對標準普爾500指數中市值最大的前100只股票資料進行訓練。

使用了以下配置:

input_size=10

num_steps=30

lstm_size=256

num_layers=1,

keep_prob=0.8

batch_size = 200

init_learning_rate = 0.05

learning_rate_decay = 0.99

init_epoch = 5

max_epoch = 500

embedding_size = 8

stock_symbol_size = 100

價格預測

       作為對預測質量的簡要概述,圖三繪製了對“KO”, “AAPL”, “GOOG” 和 “NFLX”這些測試資料的預測結果。總體趨勢在實際價格和預測值之間相匹配。考慮預測任務是如何設計的,該模型依賴所有的歷史資料測試點來預測接下來5(input_size)天的資料。引數input_size比較小的時候,模型完全不需要擔心長期的增長曲線。但是一旦我們增大了input_size,預測就會困難多了。

圖3.顯示了在測試資料集中KO,AAPL,GOOG和NFLX的真實和預測股票價格。

嵌入視覺化

       Tensorboard支援的非常好的一種常見的技術是t-SNE(Maaten和Hinton, 2008),用以在嵌入空間來視覺化叢集。t-SNE是“t-分佈隨機鄰域嵌入演算法”的縮寫,它是隨機相鄰嵌入演算法 (Hinton and Roweis, 2002)的一種演變,但是成本函式修改後更易於優化了。

1、類似於SNE,t-SNE首先將資料點之間的高維歐氏距離轉換為表示相似性的條件概率。

2、t-SNE在低維空間的資料點上定義了類似的概率分佈,依照地圖上的點的位置,它最小化了兩種分佈之間的kullback-leibler divergence

在t-SNE視覺化中檢視這一講,瞭解如何調整引數,困惑度和訓練效率(ε)。

embedding_clusters.png

圖四,用t-SNE實現股票對映的視覺化,不同顏色的標籤代表著不同行業領域的股票。

在嵌入空間中,我們可以通過檢驗對映向量之間的相似程度來度量兩種股票之間的相似性。例如,GOOG在訓練對映中與GOOGL基本類似(見圖5)。

embedding_clusters_2.png

圖五,當我們在Tensorboard的對映表中搜尋“GOOG”時,其他類似的股票會隨著相似度的下降顏色從暗到亮變得突出。

本教程中的完整程式碼請點選github.com/lilianweng/stock-rnn.

本文由北郵@愛可可-愛生活 老師推薦,阿里云云棲社群組織翻譯。

文章原標題《Predict Stock Prices Using RNN: Part 2》

作者:Lilian Weng

譯者:奧特曼,審校:袁虎。

文章為簡譯,更為詳細的內容,請檢視原文


相關文章