1. 程式人生 > >自創資料集,用TensorFlow預測股票教程 !(附程式碼)

自創資料集,用TensorFlow預測股票教程 !(附程式碼)

640?wx_fmt=png&wxfrom=5&wx_lazy=1

來源:機器之心

本文長度為4498字,建議閱讀8分鐘

本文非常適合初學者瞭解如何使用TensorFlow構建基本的神經網路。

STATWORX 團隊近日從 Google Finance API 中精選出了 S&P 500 資料,該資料集包含 S&P 500 的指數和股價資訊。有了這些資料,他們就希望能利用深度學習模型和 500 支成分股價預測 S&P 500 指數。STATWORX 團隊的資料集十分新穎,但只是利用四個隱藏層的全連線網路實現預測,讀者也可以下載該資料嘗試更加優秀的迴圈神經網路。

本文非常適合初學者瞭解如何使用 TensorFlow 構建基本的神經網路,它全面展示了構建一個 TensorFlow 模型所涉及的概念與模組。本文所使用的資料集可以直接下載,所以有一定基礎的讀者也可以嘗試使用更強的迴圈神經網路處理這一類時序資料。

資料集地址:http://files.statworx.com/sp500.zip

匯入和預處理資料

STATWORX 團隊從伺服器爬取股票資料,並將它們儲存為 csv 格式的檔案。該資料集包含 n=41266 分鐘的記錄,範圍從 2017 年的 4 月到 8 月的 500 支股票和 S&P 500 指數,股票和股指的範圍分佈十分廣。

  1. # Import data

  2. data = pd.read_csv('data_stocks.csv')

  3. # Dimensions of dataset

  4. n = data.shape[0]

  5. p = data.shape[1]

該資料集已經經過了清理與預處理,即損失的股票和股指都通過 LOCF'ed 處理(下一個觀測資料複製前面的),所以該資料集沒有任何缺損值。

我們可以使用 pyplot.plot('SP500') 語句繪出 S&P 時序資料。

640?wx_fmt=png

S&P 500 股指時序繪圖

  • 預備訓練和測試資料

該資料集需要被分割為訓練和測試資料,訓練資料包含總資料集 80% 的記錄。該資料集並不需要擾亂而只需要序列地進行切片。訓練資料可以從 2017 年 4 月選取到 2017 年 7 月底,而測試資料再選取剩下到 2017 年 8 月的資料。

  1. # Training and test data

  2. train_start = 0

  3. train_end = int(np.floor(0.8*n))

  4. test_start = train_end + 1

  5. test_end = n

  6. data_train = data[np.arange(train_start, train_end), :]

  7. data_test = data[np.arange(test_start, test_end), :]

時序交叉驗證有很多不同的方式,例如有或沒有再擬合(refitting)而執行滾動式預測、或者如時序 bootstrap 重取樣等更加詳細的策略等。後者涉及時間序列週期性分解的重複樣本,以便模擬與原時間序列相同週期性模式的樣本,但這並不不是簡單的複製他們的值。

  • 資料標準化

大多數神經網路架構都需要標準化資料,因為 tanh 和 sigmoid 等大多數神經元的啟用函式都定義在 [-1, 1] 或 [0, 1] 區間內。目前線性修正單元 ReLU 啟用函式是最常用的,但它的值域有下界無上界。不過無論如何我們都應該重新縮放輸入和目標值的範圍,這對於我們使用梯度下降演算法也很有幫助。縮放取值可以使用 sklearn 的 MinMaxScaler 輕鬆地實現。

  1. # Scale data

  2. from sklearn.preprocessing import MinMaxScaler

  3. scaler = MinMaxScaler()

  4. scaler.fit(data_train)

  5. scaler.transform(data_train)

  6. scaler.transform(data_test)

  7. # Build X and y

  8. X_train = data_train[:, 1:]

  9. y_train = data_train[:, 0]

  10. X_test = data_test[:, 1:]

  11. y_test = data_test[:, 0]pycharm

注意,我們必須謹慎地確定什麼時候該縮放哪一部分資料。比較常見的錯誤就是在拆分測試和訓練資料集之前縮放整個資料集。因為我們在執行縮放時會涉及到計算統計資料,例如一個變數的最大和最小值。但在現實世界中我們並沒有來自未來的觀測資訊,所以必須對訓練資料按比例進行統計計算,並將統計結果應用於測試資料中。不然的話我們就使用了未來的時序預測資訊,這常常令預測度量偏向於正向。

TensorFlow 簡介

TensorFlow 是一個十分優秀的框架,目前是深度學習和神經網路方面使用者最多的框架。它基於 C++的底層後端,但通常通過 Python 進行控制。TensorFlow 利用強大的靜態圖表徵我們需要設計的演算法與運算。這種方法允許使用者指定運算為圖中的結點,並以張量的形式傳輸資料而實現高效的演算法設計。由於神經網路實際上是資料和數學運算的計算圖,所以 TensorFlow 能很好地支援神經網路和深度學習。

總的來說,TensorFlow 是一種採用資料流圖(data flow graphs),用於數值計算的開源軟體庫。其中 Tensor 代表傳遞的資料為張量(多維陣列),Flow 代表使用計算圖進行運算。資料流圖用「結點」(nodes)和「邊」(edges)組成的有向圖來描述數學運算。「結點」一般用來表示施加的數學操作,但也可以表示資料輸入的起點和輸出的終點,或者是讀取/寫入持久變數(persistent variable)的終點。邊表示結點之間的輸入/輸出關係。這些資料邊可以傳送維度可動態調整的多維資料陣列,即張量(tensor)。

640?wx_fmt=png

執行加法的簡單計算圖

在上圖中,兩個零維張量(標量)將執行相加任務,這兩個張量儲存在兩個變數 a 和 b 中。這兩個值流過圖形在到達正方形結點時被執行相加任務,相加的結果被儲存在變數 c 中。實際上,a、b 和 c 可以被看作佔位符,任何輸入到 a 和 b 的值都將會相加到 c。這正是 TensorFlow 的基本原理,使用者可以通過佔位符和變數定義模型的抽象表示,然後再用實際的資料填充佔位符以產生實際的運算,下面的程式碼實現了上圖簡單的計算圖:

  1. # Import TensorFlow

  2. import tensorflow as tf

  3. # Define a and b as placeholders

  4. a = tf.placeholder(dtype=tf.int8)

  5. b = tf.placeholder(dtype=tf.int8)

  6. # Define the addition

  7. c = tf.add(a, b)

  8. # Initialize the graph

  9. graph = tf.Session()

  10. # Run the graph

  11. graph.run(c, feed_dict{a: 5, b: 4})

如上在匯入 TensorFlow 庫後,使用 tf.placeholder() 定義兩個佔位符來預儲存張量 a 和 b。隨後定義運算後就能執行運算圖得出結果。

  • 佔位符

正如前面所提到的,神經網路的初始源自佔位符。所以現在我們先要定義兩個佔位符以擬合模型,X 包含神經網路的輸入(所有 S&P 500 在時間 T=t 的股票價格),Y 包含神經網路的輸出(S&P 500 在時間 T=t+1 的指數值)。

因此輸入資料佔位符的維度可定義為 [None, n_stocks],輸出佔位符的維度為 [None],它們分別代表二維張量和一維張量。理解輸入和輸出張量的維度對於構建整個神經網路十分重要。

  1. # Placeholder

  2. X = tf.placeholder(dtype=tf.float32, shape=[None, n_stocks])

  3. Y = tf.placeholder(dtype=tf.float32, shape=[None])

以上程式碼中的 None 指代我們暫時不知道每個批量傳遞到神經網路的數量,所以使用 None 可以保持靈活性。我們後面會定義控制每次訓練時使用的批量大小 batch_size。

  • 變數

除了佔位符,變數是 TensorFlow 表徵資料和運算的另一個重要元素。雖然佔位符在計算圖內通常用於儲存輸入和輸出資料,但變數在計算圖內部是非常靈活的容器,它可以在執行中進行修改與傳遞。神經網路的權重和偏置項一般都使用變數定義,以便在訓練中可以方便地進行調整,變數需要進行初始化,後文將詳細解釋這一點。

該模型由四個隱藏層組成,第一層包含 1024 個神經元,然後後面三層依次以 2 的倍數減少,即 512、256 和 128 個神經元。後面的層級的神經元依次減少就壓縮了前面層級中抽取的特徵。當然,我們還能使用其它神經網路架構和神經元配置以更好地處理資料,例如卷積神經網路架構適合處理影象資料、迴圈神經網路適合處理時序資料,但本文只是為入門者簡要地介紹如何使用全連線網路處理時序資料,所以那些複雜的架構本文並不會討論。

  1. # Model architecture parameters

  2. n_stocks = 500

  3. n_neurons_1 = 1024

  4. n_neurons_2 = 512

  5. n_neurons_3 = 256

  6. n_neurons_4 = 128

  7. n_target = 1

  8. # Layer 1: Variables for hidden weights and biases

  9. W_hidden_1 = tf.Variable(weight_initializer([n_stocks, n_neurons_1]))

  10. bias_hidden_1 = tf.Variable(bias_initializer([n_neurons_1]))

  11. # Layer 2: Variables for hidden weights and biases

  12. W_hidden_2 = tf.Variable(weight_initializer([n_neurons_1, n_neurons_2]))

  13. bias_hidden_2 = tf.Variable(bias_initializer([n_neurons_2]))

  14. # Layer 3: Variables for hidden weights and biases

  15. W_hidden_3 = tf.Variable(weight_initializer([n_neurons_2, n_neurons_3]))

  16. bias_hidden_3 = tf.Variable(bias_initializer([n_neurons_3]))

  17. # Layer 4: Variables for hidden weights and biases

  18. W_hidden_4 = tf.Variable(weight_initializer([n_neurons_3, n_neurons_4]))

  19. bias_hidden_4 = tf.Variable(bias_initializer([n_neurons_4]))

  20. # Output layer: Variables for output weights and biases

  21. W_out = tf.Variable(weight_initializer([n_neurons_4, n_target]))

  22. bias_out = tf.Variable(bias_initializer([n_target]))

理解輸入層、隱藏層和輸出層之間變數的維度變換對於理解整個網路是十分重要的。作為多層感知機的一個經驗性法則,後面層級的第一個維度對應於前面層級權重變數的第二個維度。這可能聽起來比較複雜,但實際上只是將每一層的輸出作為輸入傳遞給下一層。偏置項的維度等於當前層級權重的第二個維度,也等於該層中的神經元數量。

設計神經網路的架構

在定義完神經網路所需要的權重矩陣與偏置項向量後,我們需要指定神經網路的拓撲結構或網路架構。因此佔位符(資料)和變數(權重和偏置項)需要組合成一個連續的矩陣乘法系統。

此外,網路隱藏層中的每一個神經元還需要有啟用函式進行非線性轉換。啟用函式是網路體系結構非常重要的組成部分,因為它們將非線性引入了系統。目前有非常多的啟用函式,其中最常見的就是線性修正單元 ReLU 啟用函式,本模型也將使用該啟用函式。

  1. # Hidden layer

  2. hidden_1 = tf.nn.relu(tf.add(tf.matmul(X, W_hidden_1), bias_hidden_1))

  3. hidden_2 = tf.nn.relu(tf.add(tf.matmul(hidden_1, W_hidden_2), bias_hidden_2))

  4. hidden_3 = tf.nn.relu(tf.add(tf.matmul(hidden_2, W_hidden_3), bias_hidden_3))

  5. hidden_4 = tf.nn.relu(tf.add(tf.matmul(hidden_3, W_hidden_4), bias_hidden_4))

  6. # Output layer (must be transposed)

  7. out = tf.transpose(tf.add(tf.matmul(hidden_4, W_out), bias_out))

下圖將展示本文構建的神經網路架構,該模型主要由三個構建塊組成,即輸入層、隱藏層和輸出層。這種架構被稱為前饋網路或全連線網路,前饋表示輸入的批量資料只會從左向右流動,其它如迴圈神經網路等架構也允許資料向後流動。

640?wx_fmt=png

前饋網路的核心架構

  • 損失函式

該網路的損失函式主要是用於生成網路預測與實際觀察到的訓練目標之間的偏差值。對迴歸問題而言,均方誤差(MSE)函式最為常用。MSE 計算預測值與目標值之間的平均平方誤差。

  1. # Cost function

  2. mse = tf.reduce_mean(tf.squared_difference(out, Y))

然而,MSE 的特性在常見的優化問題上很有優勢。

  • 優化器

優化器處理的是訓練過程中用於適應網路權重和偏差變數的必要計算。這些計算呼叫梯度計算結果,指示訓練過程中,權重和偏差需要改變的方向,從而最小化網路的代價函式。穩定、快速的優化器的開發,一直是神經網路和深度學習領域的重要研究。

  1. # Optimizer

  2. opt = tf.train.AdamOptimizer().minimize(mse)

以上是用到了 Adam 優化器,是目前深度學習中的預設優化器。Adam 表示適應性矩估計,可被當作 AdaGrad 和 RMSProp 這兩個優化器的結合。

  • 初始化器

初始化器被用於在訓練之前初始化網路的變數。因為神經網路是使用數值優化技術訓練的,優化問題的起點是找到好的解決方案的重點。TensorFlow 中有不同的初始化器,每個都有不同的初始化方法。在這篇文章中,我使用的是 tf.variance_scaling_initializer(),是一種預設的初始化策略。

  1. # Initializers

  2. sigma =

  3. weight_initializer = tf.variance_scaling_initializer(mode="fan_avg", distribution="uniform", scale=sigma)

  4. bias_initializer = tf.zeros_initializer()

注意,用 TensorFlow 的計算圖可以對不同的變數定義多個初始化函式。然而,在大多數情況下,一個統一的初始化函式就夠了。

擬合神經網路

完成對網路的佔位符、變數、初始化器、代價函式和優化器的定義之後,就可以開始訓練模型了,通常會使用小批量訓練方法。在小批量訓練過程中,會從訓練資料隨機提取數量為 n=batch_size 的資料樣本饋送到網路中。訓練資料集將分成 n/batch_size 個批量按順序饋送到網路中。此時佔位符 X 和 Y 開始起作用,它們儲存輸入資料和目標資料,並在網路中分別表示成輸入和目標。

X 的一個批量資料會在網路中向前流動直到到達輸出層。在輸出層,TensorFlow 將會比較當前批量的模型預測和實際觀察目標 Y。然後,TensorFlow 會進行優化,使用選擇的學習方案更新網路的引數。更新完權重和偏差之後,下一個批量被取樣並重復以上過程。這個過程將一直進行,直到所有的批量都被饋送到網路中去,即完成了一個 epoch。

當訓練達到了 epoch 的最大值或其它的使用者自定義的停止標準的時候,網路的訓練就會停止。

  1. # Run initializer

  2. net.run(tf.global_variables_initializer())

  3. # Setup interactive plot

  4. plt.ion()

  5. fig = plt.figure()

  6. ax1 = fig.add_subplot(111)

  7. line1, = ax1.plot(y_test)

  8. line2, = ax1.plot(y_test*0.5)

  9. plt.show()

  10. # Number of epochs and batch size

  11. epochs = 10

  12. batch_size = 256for e in range(epochs):

  13. # Shuffle training data

  14. shuffle_indices = np.random.permutation(np.arange(len(y_train)))

  15. X_train = X_train[shuffle_indices]

  16. y_train = y_train[shuffle_indices]

  17. # Minibatch training

  18. for i in range(0, len(y_train) // batch_size):

  19. start = i * batch_size

  20. batch_x = X_train[start:start + batch_size]

  21. batch_y = y_train[start:start + batch_size]

  22. # Run optimizer with batch

  23. net.run(opt, feed_dict={X: batch_x, Y: batch_y})

  24. # Show progress

  25. if np.mod(i, 5) == 0:

  26. # Prediction

  27. pred = net.run(out, feed_dict={X: X_test})

  28. line2.set_ydata(pred)

  29. plt.title('Epoch ' + str(e) + ', Batch ' + str(i))

  30. file_name = 'img/epoch_' + str(e) + '_batch_' + str(i) + '.jpg'

  31. plt.savefig(file_name)

  32. plt.pause(0.01)

在訓練過程中,我們在測試集(沒有被網路學習過的資料)上評估了網路的預測能力,每訓練 5 個 batch 進行一次,並展示結果。此外,這些影象將被匯出到磁碟並組合成一個訓練過程的視訊動畫。模型能迅速學習到測試資料中的時間序列的位置和形狀,並在經過幾個 epoch 的訓練之後生成準確的預測。太棒了!

可以看到,網路迅速地適應了時間序列的基本形狀,並能繼續學習資料的更精細的模式。這歸功於 Adam 學習方案,它能在模型訓練過程中降低學習率,以避免錯過最小值。經過 10 個 epoch 之後,我們完美地擬合了測試資料!最後的測試 MSE 等於 0.00078,這非常低,因為目標被縮放過。測試集的預測的平均百分誤差率等於 5.31%,這是很不錯的結果。

640?wx_fmt=png

預測和實際 S&P 價格的散點圖(已縮放)

請注意其實還有很多種方法能進一步優化這個結果:層和神經元的設計、不同的初始化和啟用方案的選擇、引入神經元的 dropout 層、早期停止法的應用,等等。此外,其它不同型別的深度學習模型,比如迴圈神經網路也許能在這個任務中達到更好的結果。不過,這在我們的討論範圍之外。

結論和展望

TensorFlow 的釋出是深度學習研究的里程碑事件,其高度的靈活性和強大的效能使研究者能開發所有種類的複雜神經網路架構以及其它機器學習演算法。然而,相比使用高階 API 如 Keras 或 MxNet,靈活性的代價是更長的建模時間。儘管如此,我相信 TensorFlow 將繼續發展,併成為神經網路和和深度學習開發的研究和實際應用的現實標準。我們很多客戶都已經在使用 TensorFlow,或正在開發應用 TensorFlow 模型的專案。我們的 STATWORX 的資料科學顧問(https://www.statworx.com/de/data-science/)基本都是用 TensorFlow 研究課開發深度學習以及神經網路。

谷歌未來針對 TensorFlow 的計劃會是什麼呢?至少在我看來,TensorFlow 缺少一個簡潔的圖形使用者介面,用於在 TensorFlow 後端設計和開發神經網路架構。也許這就是谷歌未來的一個目標:)

編輯:文婧

640?wx_fmt=jpeg

相關推薦

資料TensorFlow預測股票教程 !程式碼

來源:機器之心 本文長度為4498字,建議閱讀8分鐘 本文非常適合初學者瞭解如何使用TensorFlow構建基本的神經網路。 STATWORX 團隊近日從 Google Finance API

教你TensorFlow實現神經網路程式碼

來源:雲棲社群 作者:Pavel Surmenok 本文長度為2600字,建議閱讀5分鐘 本文幫助你理解神經網路的應用,並使用TensorFlow解決現實生活中的問題。 如果你一直關注資料科學

沒有基礎小編帶你python畫機器貓程式碼

小編帶你玩python 沒有基礎小編帶你,用python畫機器貓。只需要python3和小編的程式碼即可。python3小編送,程式碼文章有,現在就差個你了。 執行不了的找小編,小編包教會你。 重要的事情說三遍: python3小編送,程式碼文章有。 python3小編送,程式碼文章有。 python

半邊資料結構與網格細分演算法Loop subdivision程式碼

網格細分的原理其實並不難理解,它的難點主要在於如何實現。在看過無數有原理無程式碼的部落格後,終於決定寫一寫我的實現方法,並附上程式碼供大家參考。c++寫的可能比較笨拙,望見諒。 1.半邊資料結構 很好理解,就是把網格的每一條邊分成兩個半邊,半邊是有方向的同一條邊的兩個半邊方向相反。並且一條邊

VS連線SQL Server資料庫增刪改查詳細教程C#程式碼

工具: 1.Visual Studio (我使用的是vs2013) 2.SQL Server  (我使用的是sql server2008) 操作: 1.開啟SQL Server,開啟後會看到資料庫的初始連結介面。(如下圖) 2.複製上圖中的“伺服器名稱”,然後點

Tensorflow框架下Faster-RCNN實踐——Faster-RCNN所需資料製作程式碼

最近剛實現了在Ubuntu16.04、Tensorfllow1.0下 Faster R-CNN 從資料製作到訓練再到利用生成的模型檢測的測試圖片的全過程,現在將具體的過程記錄在部落格,方便遇到困惑或者需要的朋友檢視。 製作資料集 利用Fast

基於tensorflow 批量修改自己的圖片資料 程式碼

       現在網上有很多關於Deeplearning的教程,不過這些教程的資料集都是已經做好的,並且格式名字什麼的都已經整理好了。特別是很多入門的教程都是Mnist 的資料集,這都已經非常的完善了。不過對於想自己製作資料集的小白來說,如何將自己收集的圖片批量轉換為自己需要

教你TensorFlow編碼器模型生成手寫數字程式碼

來源:機器之心 本文長度為1876字,建議閱讀4分鐘 本文介紹瞭如何使用 TensorFlow 實現變分自編碼器(VAE)模型,並通過簡單的手寫數字生成案例一步步引導讀者實現這一強大的生成模

基於PTB資料實現RNN-LSTM迴圈神經網路智慧填詞

本篇直入主題,做一篇學習的記錄,在學習RNN的時候,跟著教程敲了一個案例 分為處理方法檔案,神經網路模型檔案,訓練方法檔案,測試檔案 所有的操作和重要內容都在程式碼中作了詳細的註釋 一、目標神經網路模型   二、資料集 PT

從小數學就不及格的我竟然極座標系表白了我的女神!程式碼

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~ 本文由郭詩雅發表於雲+社群專欄 在數學中,極座標系(英語:Polar coordinate system)是一個二維座標系統。該座標系統中任意位置可由一個夾角和一段相對原點—極點的距離來表示。在兩點間的關

keras面向小資料的影象分類VGG-16基礎上fine-tune實現程式碼

參考譯文地址:http://keras-cn.readthedocs.io/en/latest/blog/image_classification_using_very_little_data/ 本文作者:Francois Chollet 概述 在本文中,將使用VGG-16模型提供一種面向小資料集(幾百

吳恩達機器學習課程:完全Python完成可以的!程式碼

  新智元報道 來源:Reddit、GitHub編輯:肖琴【導讀】完全用Python完成吳恩達的

手把手教你R實現標記化程式碼、學習資料、語料庫

作者:Rachael Tatman翻譯:樑傅淇本文長度為1600字,建議閱讀4分鐘標記化是自然語

VC++6.0下基於MFC框架利用CInternetSession和CHttpFile獲取網頁資料程式碼

例:從網站http://qq.ip138.com/weather/guangdong/GuangZhou.htm獲取近三天的日期、天氣、溫度、風向,程式碼如下: //新增標頭檔案 #include <afxinet.h> //獲取網路資料 void CSensorSysDlg:

獨家 | 手把手教你Python進行Web抓取程式碼

作為一名資料科學家,我在工作中所做的第一件事就是網路資料採集。使用程式碼從網站收集資料,當時對我來說是一個完全陌生的概念,但它是最合理、最容易獲取的資料來源之一。經過幾次嘗試,網路抓取已經成為我的第二天性,也是我幾乎每天使用的技能之一。 在本教程中,我將介紹一個簡單的例子,說明如何抓取一個網站,

資料探勘領域十大經典演算法之—CART演算法程式碼

簡介 CART與C4.5類似,是決策樹演算法的一種。此外,常見的決策樹演算法還有ID3,這三者的不同之處在於特徵的劃分: ID3:特徵劃分基於資訊增益 C4.5:特徵劃分基於資訊增益比 CART:特徵劃分基於基尼指數 基本思想 CART假設決策樹是二叉樹,

獨家 | 手把手教你Python建立簡單的神經網路程式碼

作者:Michael J.Garbade 翻譯:陳之炎 校對:丁楠雅 本文共2000字,建議閱讀9分鐘。本文將為你演示如何建立一個神經網路,帶你深入瞭解神經網路的工作方式。 瞭解神經網路工作方式的最佳途徑莫過於親自建立一個神經網路,本文將演示如何做到這一點。

Python處理非平穩時間序列程式碼

原文地址:https://blog.csdn.net/tmb8z9vdm66wh68vx1/article/details/84207895 由於排版和圖片原因,請儘量轉制原文觀看,在此只是作為個人的一個記錄。 作者:AISHWARYA SINGH 翻譯:陳之炎 校對:丁楠雅 本

學python90%人的不知道的python使用小計巧 程式碼

這些小技巧,小編用的非常上手,所以分享出來,希望對你有幫助。 顯示有限的介面到外部 當釋出python第三方package時, 並不希望程式碼中所有的函式或者class可以被外部import,在__init__.py中新增__all__屬性,該list中填寫可以import的類或者函式名,可以起到限制的im