利用深度學習來預測股票價格變動

https://www.toutiao.com/i6644852565341110791/

?

?

利用深度學習來預測股票價格變動(長文,建議收藏)

原創?不靠譜的貓?2019-01-10 21:01:39
利用深度學習來預測股票價格變動(長文,建議收藏)

完整架構概述

在這篇文章中,我將創建一個預測股票價格變動的完整過程。我們將使用生成對抗網絡(GAN)與LSTM(一種循環神經網絡)作為生成器,使用卷積神經網絡CNN作為鑒別器。我們使用LSTM的原因很明顯,我們正在嘗試預測時間序列數據。為什么我們使用GAN,特別是卷積神經網絡(CNN)作為鑒別器呢?這是一個很好的問題:稍后會有特別的部分。

當然,我們將詳細介紹每個步驟,但最困難的部分是GAN:成功訓練GAN的非常棘手的部分是獲得正確的超參數集。出于這個原因,我們將使用貝葉斯優化(還有高斯過程)和深度強化學習(DRL)來決定何時以及如何改變GAN的超參數。在創建強化學習時,我將使用該領域的最新進展,例如Rainbow和PPO。

我們將使用許多不同類型的輸入數據。除了股票的歷史交易數據和技術指標,我們將使用NLP的最新進展(使用“BERT,對NLP進行遷移學習)來創建情感分析(作為基本面分析的來源) ),用于提取整體趨勢方向的傅里葉變換,用于識別其他高級特征的棧式自動編碼器,用于查找相關資產的特征投資組合,差分整合移動平均自回歸模型(ARIMA))對于股票函數近似,以便捕獲盡可能多的關于股票的信息,模式,依賴關系等。我們都知道,數據越多越好。預測股價走勢是一項極其復雜的任務,所以我們對股票(從不同的角度)了解得越多,我們的系統就會越好。

為了創建所有神經網絡,我們將使用MXNet和它的高級API - Gluon,并在多個GPU上訓練它們。

注:盡管我試圖深入探討數學和幾乎所有算法和技術背后的機制,但本文并沒有明確地解釋機器/深度學習或股票市場是如何運作的。其目的是展示我們如何使用不同的技術和算法來準確預測股票價格的變動,并給出每一步使用每種技術的原因和有用性背后的理論基礎。

1.簡介

準確預測股票市場是一項復雜的任務,因為有數百萬種情況會影響它。因此,我們需要能夠盡可能多地捕獲這些前置條件。我們還需要做出幾個重要的假設:1)市場不是100%隨機,2)歷史重復,3)市場遵循人們的理性行為,4)市場是“ 完美的 ”。

我們將嘗試預測高盛(NYSE: GS)的價格走勢。為此,我們將使用2010年1月1日至2018年12月31日的每日收盤價(七年數據用于訓練,兩年數據用于驗證)。我們將交替使用“高盛”和“GS”這兩個術語。

2.數據

我們需要盡可能多地合并信息(從不同方面和角度描繪股票)。我們將使用每日數據,1585天來訓練各種算法(我們有70%的數據)并預測接下來的680天(測試數據),然后我們將把預測結果與測試數據進行比較。每種類型的數據(我們將其稱為特征)將在后面的章節中進行更詳細的解釋,但是,作為一個高層次的概述,我們將使用的特征是:

  1. 相關資產 - 這些是其他資產(任何類型,不一定是股票,如商品,外匯,指數,甚至固定收益證券)。像高盛這樣的大公司顯然不會“生活”在一個孤立的世界中 - 它依賴于許多外部因素,并與之相互作用,包括競爭對手,客戶,全球經濟,地緣政治形勢,財政和貨幣政策,獲得資金等。詳情將在后面列出。
  2. 技術指標 - 很多投資者都遵循技術指標。我們將最受歡迎的指標作為獨立特征。如 - 7和21天移動平均線,指數移動平均線,momentum,布林線,MACD。
  3. 一個非常重要的特征,表明股票可能上漲或下跌。基本面分析有兩個特征:1)使用10-K和10-Q報告分析公司業績,分析ROE和P/E等(我們不會使用這個);我們將為高盛(Goldman Sachs)和閱讀每日新聞提取總情緒是否對高盛(Goldman Sachs)在那一天是正面的,還是負面的(如得分從0到1)。由于許多投資者會仔細閱讀新聞,并根據新聞(當然是部分依據新聞)做出投資決策,因此,如果高盛(Goldman Sachs)今天的消息非常正面,那么該股明天將大幅上漲的可能性在一定程度上是很高的。關鍵的一點是,我們將在以后對每個特征(包括這個特征)執行特征重要性(意思是它對GS波動的指示性),并決定是否使用它。我們將使用BERT?- 谷歌最近公布的NLP方法,用于情感分類股票新聞情緒提取的遷移學習。
  4. 傅里葉變換 - 除了每日收盤價,我們還將創建傅里葉變換,以概括多個長期和短期趨勢。使用這些變換,我們將消除大量噪聲(隨機游走)并創建真實股票移動的近似值。趨勢近似可以幫助LSTM網絡更準確地選擇其預測趨勢。
  5. 自回歸整合移動平均線(ARIMA) - 這是預測時間序列數據未來值的最流行的技術之一(在pre-neural網絡時代)。讓我們添加它,看看它是否是一個重要的預測特征。
  6. 棧式自動編碼器 - 上述大部分特征(基礎分析、技術分析等)都是人們經過幾十年的研究發現的。也許有一些隱藏的相關性,人們無法理解,因為有大量的數據點、事件、資產、圖表等。通過棧式自動編碼器(神經網絡的類型),我們可以利用計算機的力量,可能會發現影響股票走勢的新類型的特征。即使我們無法理解人類語言中的這些特征,我們也將在GAN中使用它們。
  7. 期權定價中異常檢測的深度無監督學習。我們將再使用一項功能 - 每天我們都會為高盛股票增加90天看漲期權的價格。期權定價本身結合了大量數據。期權合約的價格取決于股票的未來值(分析師也試圖預測價格,以便為看漲期權提供最準確的價格)。使用深度無監督機器學習(Self-organized Maps),我們將嘗試發現每天定價中的異常情況。異常(例如價格的劇烈變化)可能表明一個事件可能對LSTM了解整個股票模式有用。

接下來,有這么多特征,我們需要執行幾個重要步驟:

  1. 對數據的“質量”進行統計檢查。如果我們創建的數據有缺陷,那么無論我們的算法多么復雜,結果都不會是正確的。檢查包括確保數據不受異方差、多重共線性或序列相關性的影響。
  2. 創建特征的重要性。如果一個特征(如另一只股票或一個技術指標)對我們想預測的股票沒有解釋力,那么我們就沒有必要在神經網絡的訓練中使用它。我們將使用XGBoost(eXtreme Gradient boost),一種boosted 樹回歸算法。

作為數據準備的最后一步,我們還將使用主成分分析(PCA)創建Eigen投資組合,以減少自動編碼器創建的特征的維數。

from utils import *
import time
import numpy as np
from mxnet import nd, autograd, gluon
from mxnet.gluon import nn, rnn
import mxnet as mx
import datetime
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.decomposition import PCA
import math
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler
import xgboost as xgb
from sklearn.metrics import accuracy_score
import warnings
warnings.filterwarnings("ignore")
context = mx.cpu(); model_ctx=mx.cpu()
mx.random.seed(1719)
def parser(x):
return datetime.datetime.strptime(x,'%Y-%m-%d')
dataset_ex_df = pd.read_csv('data/panel_data_close.csv', header=0, parse_dates=[0], date_parser=parser)
dataset_ex_df[['Date', 'GS']].head(3)
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)
print('There are {} number of days in the dataset.'.format(dataset_ex_df.shape[0]))

output >>> There are 2265 number of days in the dataset.

讓我們想象一下過去九年的股票。垂直虛線表示訓練和測試數據之間的分離。

plt.figure(figsize=(14, 5), dpi=100)
plt.plot(dataset_ex_df['Date'], dataset_ex_df['GS'], label='Goldman Sachs stock')
plt.vlines(datetime.date(2016,4, 20), 0, 270, linestyles='--', colors='gray', label='Train/Test data cut-off')
plt.xlabel('Date')
plt.ylabel('USD')
plt.title('Figure 2: Goldman Sachs stock price')
plt.legend()
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)
num_training_days = int(dataset_ex_df.shape[0]*.7)
print('Number of training days: {}. Number of test days: {}.'.format(num_training_days,
dataset_ex_df.shape[0]-num_training_days))
利用深度學習來預測股票價格變動(長文,建議收藏)

Number of training days: 1585. Number of test days: 680.

2.1、相關資產

如前所述,我們將使用其他資產作為特征,而不僅僅是GS。

那么,還有哪些資產會影響高盛的股價走勢呢?對公司、業務線、競爭環境、依賴關系、供應商和客戶類型等的良好理解對于選擇正確的相關資產集非常重要:

  • 首先是類似于GS的公司。我們將把摩根大通(JPMorgan Chase)和摩根士丹利(Morgan Stanley)等公司加入數據集。
  • 作為一家投資銀行,高盛(Goldman Sachs)依賴于全球經濟。經濟不景氣或不穩定意味著沒有并購或IPO,也可能是有限的自營交易收益。這就是為什么我們將包括全球經濟指數。此外,我們將包括LIBOR(美元和英鎊計價)利率,因為分析師可能會考慮經濟的沖擊來設定這些利率以及其他FI證券。
  • 每日波動率指數(VIX) - 由于前一點所述的原因。
  • 綜合指數 - 例如納斯達克和紐約證券交易所(美國)、FTSE100指數(英國)、Nikkei225指數(日本)、恒生指數和BSE Sensex指數(亞太)。
  • 貨幣 - 全球貿易多次反映貨幣如何變動,因此我們將使用一籃子貨幣(如美元兌日元,英鎊兌美元等)作為特征。

總的來說,我們在數據集中有72個其他資產 - 每個資產的每日價格。

2.2、技術指標

我們已經討論了什么是技術指標以及為什么使用它們,現在讓我們直接跳到Python代碼。我們將只為GS創建技術指標。

def get_technical_indicators(dataset):
# Create 7 and 21 days Moving Average
dataset['ma7'] = dataset['price'].rolling(window=7).mean()
dataset['ma21'] = dataset['price'].rolling(window=21).mean()

# Create MACD
dataset['26ema'] = pd.ewma(dataset['price'], span=26)
dataset['12ema'] = pd.ewma(dataset['price'], span=12)
dataset['MACD'] = (dataset['12ema']-dataset['26ema'])
# Create Bollinger Bands
dataset['20sd'] = pd.stats.moments.rolling_std(dataset['price'],20)
dataset['upper_band'] = dataset['ma21'] + (dataset['20sd']*2)
dataset['lower_band'] = dataset['ma21'] - (dataset['20sd']*2)

# Create Exponential moving average
dataset['ema'] = dataset['price'].ewm(com=0.5).mean()

# Create Momentum
dataset['momentum'] = dataset['price']-1

return dataset
dataset_TI_df = get_technical_indicators(dataset_ex_df[['GS']])
dataset_TI_df.head()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

所以我們有每個交易日的技術指標(包括MACD、Bollinger bands等)。我們總共有12項技術指標。

讓我們想象一下這些指標的最后400天。

def plot_technical_indicators(dataset, last_days):
plt.figure(figsize=(16, 10), dpi=100)
shape_0 = dataset.shape[0]
xmacd_ = shape_0-last_days

dataset = dataset.iloc[-last_days:, :]
x_ = range(3, dataset.shape[0])
x_ =list(dataset.index)

# Plot first subplot
plt.subplot(2, 1, 1)
plt.plot(dataset['ma7'],label='MA 7', color='g',linestyle='--')
plt.plot(dataset['price'],label='Closing Price', color='b')
plt.plot(dataset['ma21'],label='MA 21', color='r',linestyle='--')
plt.plot(dataset['upper_band'],label='Upper Band', color='c')
plt.plot(dataset['lower_band'],label='Lower Band', color='c')
plt.fill_between(x_, dataset['lower_band'], dataset['upper_band'], alpha=0.35)
plt.title('Technical indicators for Goldman Sachs - last {} days.'.format(last_days))
plt.ylabel('USD')
plt.legend()
# Plot second subplot
plt.subplot(2, 1, 2)
plt.title('MACD')
plt.plot(dataset['MACD'],label='MACD', linestyle='-.')
plt.hlines(15, xmacd_, shape_0, colors='g', linestyles='--')
plt.hlines(-15, xmacd_, shape_0, colors='g', linestyles='--')
plt.plot(dataset['log_momentum'],label='Momentum', color='b',linestyle='-')
plt.legend()
plt.show()
plot_technical_indicators(dataset_TI_df, 400)
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

2.3、基本面分析

對于基本面分析,我們將對所有關于GS的每日新聞進行情感分析。最后使用sigmoid,結果將在0和1之間。分數越接近0 - 新聞越負面(接近1表示正面情感)。對于每一天,我們將創建平均每日得分(作為0到1之間的數字)并將其添加為特征。

2.3.1、 BERT

為了將新聞分類為正面或負面(或中性),我們將使用BERT,這是一種預訓練的語言表示。

已經在MXNet / Gluon中提供預訓練的BERT模型。我們只需要實例化它們并添加兩個(任意數量)Dense層,softmax - 得分從0到1。

# just import bert
import bert

2.4、傅立葉變換用于趨勢分析

傅立葉變換采用函數并創建一系列正弦波(具有不同的幅度和幀)。組合時,這些正弦波接近原始函數。從數學上講,變換看起來像這樣:

利用深度學習來預測股票價格變動(長文,建議收藏)

我們將使用傅里葉變換來提取GS股票的整體和局部趨勢,并對其進行降噪。我們來看看它是如何工作的。

data_FT = dataset_ex_df[['Date', 'GS']]
close_fft = np.fft.fft(np.asarray(data_FT['GS'].tolist()))
fft_df = pd.DataFrame({'fft':close_fft})
fft_df['absolute'] = fft_df['fft'].apply(lambda x: np.abs(x))
fft_df['angle'] = fft_df['fft'].apply(lambda x: np.angle(x))
plt.figure(figsize=(14, 7), dpi=100)
fft_list = np.asarray(fft_df['fft'].tolist())
for num_ in [3, 6, 9, 100]:
fft_list_m10= np.copy(fft_list); fft_list_m10[num_:-num_]=0
plt.plot(np.fft.ifft(fft_list_m10), label='Fourier transform with {} components'.format(num_))
plt.plot(data_FT['GS'], label='Real')
plt.xlabel('Days')
plt.ylabel('USD')
plt.title('Figure 3: Goldman Sachs (close) stock prices & Fourier transforms')
plt.legend()
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

正如您在圖3中看到的,我們使用傅里葉變換的成分越多,逼近函數越接近實際股票價格(100個成分變換幾乎與原始函數相同 - 紅色和紫色線幾乎重疊)。我們使用傅立葉變換來提取長期和短期趨勢,因此我們將使用具有3,6和9個成分的變換。您可以推斷出具有3個成分的轉換是長期趨勢。

用于去噪數據的另一種技術是調用小波。小波和傅里葉變換給出了類似的結果,因此我們只使用傅里葉變換。

from collections import deque
items = deque(np.asarray(fft_df['absolute'].tolist()))
items.rotate(int(np.floor(len(fft_df)/2)))
plt.figure(figsize=(10, 7), dpi=80)
plt.stem(items)
plt.title('Figure 4: Components of Fourier transforms')
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

2.5、ARIMA作為一項特征值

ARIMA是一種預測時間序列數據的技術。我們將展示如何使用它,雖然ARIMA不能作為我們的最終預測,但我們將使用它作為一種技術來稍微降低噪聲,并(可能)提取一些新的模式或特征。

from statsmodels.tsa.arima_model import ARIMA
from pandas import DataFrame
from pandas import datetime
series = data_FT['GS']
model = ARIMA(series, order=(5, 1, 0))
model_fit = model.fit(disp=0)
print(model_fit.summary())
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)
from pandas.tools.plotting import autocorrelation_plot
autocorrelation_plot(series)
plt.figure(figsize=(10, 7), dpi=80)
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)
from pandas import read_csv
from pandas import datetime
from statsmodels.tsa.arima_model import ARIMA
from sklearn.metrics import mean_squared_error
X = series.values
size = int(len(X) * 0.66)
train, test = X[0:size], X[size:len(X)]
history = [x for x in train]
predictions = list()
for t in range(len(test)):
model = ARIMA(history, order=(5,1,0))
model_fit = model.fit(disp=0)
output = model_fit.forecast()
yhat = output[0]
predictions.append(yhat)
obs = test[t]
history.append(obs)
error = mean_squared_error(test, predictions)
print('Test MSE: %.3f' % error)
利用深度學習來預測股票價格變動(長文,建議收藏)

Test MSE: 10.151

# Plot the predicted (from ARIMA) and real prices
plt.figure(figsize=(12, 6), dpi=100)
plt.plot(test, label='Real')
plt.plot(predictions, color='red', label='Predicted')
plt.xlabel('Days')
plt.ylabel('USD')
plt.title('Figure 5: ARIMA model on GS stock')
plt.legend()
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

從圖5中可以看出,ARIMA給出了一個非常接近實際股價的結果。我們將通過ARIMA使用預測價格作為LSTM的輸入特征,因為正如我們前面提到的,我們希望盡可能多地捕獲關于高盛的特征和模式。我們測試MSE(均方誤差)為10.151,這本身并不是一個壞結果(考慮到我們有很多測試數據),但是我們仍然只將其作為LSTM中的一個特征。

2.6、統計檢查

確保數據具有良好的質量對于機器學習模型非常重要。為了確保我們的數據擬合,我們將執行幾個簡單的檢查,以確保我們實現和觀察到的結果是真實的,而不是因為底層數據分布存在基本錯誤而受到損害。

2.6.1、異方差性,多重共線性,序列相關性

  • 條件異方差發生在誤差項(通過回歸得到的預測值與實際值之間的差)依賴于數據時——例如,誤差項隨著數據點(沿x軸)的增長而增長。
  • 多重共線性是指誤差項(也稱為殘差)相互依賴的時間。
  • 序列相關性是指一個數據(特征)是另一個特征的公式(或完全不相關)。

我們不會在這里進入代碼,因為它很簡單,我們的重點更多地放在深度學習部分,但數據是定性的。

2.7、特征工程

print('Total dataset has {} samples, and {} features.'.format(dataset_total_df.shape[0], 
dataset_total_df.shape[1]))
利用深度學習來預測股票價格變動(長文,建議收藏)

Total dataset has 2265 samples, and 112 features.

因此,在添加了所有類型的數據(相關資產、技術指標、基礎分析、傅立葉和Arima)之后,我們在這2,265天中總共有112個特征(如前所述,訓練數據只有1,585天)。

我們還將從自動編碼器生成更多特征。

2.7.1、XGBoost的重要性

有這么多的特征,我們必須要考慮它們是否真的代表了走勢。例如,我們在機器學習數據集中包含了以美元計價的LIBOR利率,因為我們認為LIBOR的變化可能表明經濟的變化,而經濟的變化又可能表明GS的股票行為的變化。但我們需要測試。測試特征重要性的方法有很多,但是我們將使用XGBoost,因為它在分類和回歸問題中都給出了最好的結果之一。

由于特征數據集非常大,出于演示目的,我們將僅使用技術指標。在真實特征重要性測試期間,所有選定的特征都證明有些重要,因此我們在訓練GAN時不會排除任何內容。

def get_feature_importance_data(data_income):
data = data_income.copy()
y = data['price']
X = data.iloc[:, 1:]

train_samples = int(X.shape[0] * 0.65)

X_train = X.iloc[:train_samples]
X_test = X.iloc[train_samples:]
y_train = y.iloc[:train_samples]
y_test = y.iloc[train_samples:]

return (X_train, y_train), (X_test, y_test)
# Get training and test data
(X_train_FI, y_train_FI), (X_test_FI, y_test_FI) = get_feature_importance_data(dataset_TI_df)
regressor = xgb.XGBRegressor(gamma=0.0,n_estimators=150,base_score=0.7,colsample_bytree=1,learning_rate=0.05)
xgbModel = regressor.fit(X_train_FI,y_train_FI,
eval_set = [(X_train_FI, y_train_FI), (X_test_FI, y_test_FI)],
verbose=False)
eval_result = regressor.evals_result()
training_rounds = range(len(eval_result['validation_0']['rmse']))
利用深度學習來預測股票價格變動(長文,建議收藏)

讓我們繪制訓練和驗證誤差的曲線圖,以便觀察訓練和檢查過擬合(欠擬合)。

plt.scatter(x=training_rounds,y=eval_result['validation_0']['rmse'],label='Training Error')
plt.scatter(x=training_rounds,y=eval_result['validation_1']['rmse'],label='Validation Error')
plt.xlabel('Iterations')
plt.ylabel('RMSE')
plt.title('Training Vs Validation Error')
plt.legend()
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)
fig = plt.figure(figsize=(8,8))
plt.xticks(rotation='vertical')
plt.bar([i for i in range(len(xgbModel.feature_importances_))], xgbModel.feature_importances_.tolist(), tick_label=X_test_FI.columns)
plt.title('Figure 6: Feature importance of the technical indicators.')
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

毫不奇怪,MA7,MACD和BB是其中的重要特征。

我遵循相同的邏輯來對整個數據集執行特征重要性 - 與僅少數幾個特征相比,訓練花費的時間更長,結果更難以閱讀。

2.8、使用Stacked Autoencoders提取高級特征

在我們進入自動編碼器之前,我們將探索激活函數。

2.8.1、激活功函數- GELU(高斯誤差)

最近提出了GELU - Gaussian Error Linear Unites - link。在論文中,作者展示了使用ReLU作為激活的使用GELU的神經網絡優于網絡的幾個實例。gelu也用于BERT,我們用于新聞情緒分析的NLP方法。

我們將使用GELU作為自動編碼器。

注:下面的單元格展示了GELU數學背后的邏輯。它不是作為激活函數的實際實現。我必須在MXNet中實現GELU。如果您按照代碼將act_type='relu'更改為act_type='gelu',那么它將不起作用,除非您更改MXNet的實現。對整個項目發出pull請求,以訪問GELU的MXNet實現。

def gelu(x):
return 0.5 * x * (1 + math.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * math.pow(x, 3))))
def relu(x):
return max(x, 0)
def lrelu(x):
return max(0.01*x, x)
利用深度學習來預測股票價格變動(長文,建議收藏)

讓我們來看看GELU、ReLU和LeakyReLU(最后一個主要用于GAN)。

plt.figure(figsize=(15, 5))
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=.5, hspace=None)
ranges_ = (-10, 3, .25)
plt.subplot(1, 2, 1)
plt.plot([i for i in np.arange(*ranges_)], [relu(i) for i in np.arange(*ranges_)], label='ReLU', marker='.')
plt.plot([i for i in np.arange(*ranges_)], [gelu(i) for i in np.arange(*ranges_)], label='GELU')
plt.hlines(0, -10, 3, colors='gray', linestyles='--', label='0')
plt.title('Figure 7: GELU as an activation function for autoencoders')
plt.ylabel('f(x) for GELU and ReLU')
plt.xlabel('x')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot([i for i in np.arange(*ranges_)], [lrelu(i) for i in np.arange(*ranges_)], label='Leaky ReLU')
plt.hlines(0, -10, 3, colors='gray', linestyles='--', label='0')
plt.ylabel('f(x) for Leaky ReLU')
plt.xlabel('x')
plt.title('Figure 8: LeakyReLU')
plt.legend()
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

好的,回到自動編碼器,如下所示(圖像只是原理圖,它不代表實際的層數,units等)

注意:通常,在自動編碼器中編碼器的數量==解碼器的數量。但是,我們希望提取更高級別的特征(而不是創建相同的輸入),因此我們可以跳過解碼器中的最后一層。我們實現了這一點,在訓練期間創建了具有相同層數的編碼器和解碼器。

利用深度學習來預測股票價格變動(長文,建議收藏)
batch_size = 64
n_batches = VAE_data.shape[0]/batch_size
VAE_data = VAE_data.values
train_iter = mx.io.NDArrayIter(data={'data': VAE_data[:num_training_days,:-1]},
label={'label': VAE_data[:num_training_days, -1]}, batch_size = batch_size)
test_iter = mx.io.NDArrayIter(data={'data': VAE_data[num_training_days:,:-1]},
label={'label': VAE_data[num_training_days:,-1]}, batch_size = batch_size)
model_ctx = mx.cpu()
class VAE(gluon.HybridBlock):
def __init__(self, n_hidden=400, n_latent=2, n_layers=1, n_output=784,
batch_size=100, act_type='relu', **kwargs):
self.soft_zero = 1e-10
self.n_latent = n_latent
self.batch_size = batch_size
self.output = None
self.mu = None
super(VAE, self).__init__(**kwargs)

with self.name_scope():
self.encoder = nn.HybridSequential(prefix='encoder')

for i in range(n_layers):
self.encoder.add(nn.Dense(n_hidden, activation=act_type))
self.encoder.add(nn.Dense(n_latent*2, activation=None))
self.decoder = nn.HybridSequential(prefix='decoder')
for i in range(n_layers):
self.decoder.add(nn.Dense(n_hidden, activation=act_type))
self.decoder.add(nn.Dense(n_output, activation='sigmoid'))
def hybrid_forward(self, F, x):
h = self.encoder(x)
#print(h)
mu_lv = F.split(h, axis=1, num_outputs=2)
mu = mu_lv[0]
lv = mu_lv[1]
self.mu = mu
eps = F.random_normal(loc=0, scale=1, shape=(self.batch_size, self.n_latent), ctx=model_ctx)
z = mu + F.exp(0.5*lv)*eps
y = self.decoder(z)
self.output = y
KL = 0.5*F.sum(1+lv-mu*mu-F.exp(lv),axis=1)
logloss = F.sum(x*F.log(y+self.soft_zero)+ (1-x)*F.log(1-y+self.soft_zero), axis=1)
loss = -logloss-KL
return loss
n_hidden=400 # neurons in each layer
n_latent=2
n_layers=3 # num of dense layers in encoder and decoder respectively
n_output=VAE_data.shape[1]-1
net = VAE(n_hidden=n_hidden, n_latent=n_latent, n_layers=n_layers, n_output=n_output, batch_size=batch_size, act_type='gelu')
net.collect_params().initialize(mx.init.Xavier(), ctx=mx.cpu())
net.hybridize()
trainer = gluon.Trainer(net.collect_params(), 'adam', {'learning_rate': .01})
print(net)
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

所以我們在編碼器和解碼器中都有3層(每個層有400個神經元)。

n_epoch = 150
print_period = n_epoch // 10
start = time.time()
training_loss = []
validation_loss = []
for epoch in range(n_epoch):
epoch_loss = 0
epoch_val_loss = 0
train_iter.reset()
test_iter.reset()
n_batch_train = 0
for batch in train_iter:
n_batch_train +=1
data = batch.data[0].as_in_context(mx.cpu())
with autograd.record():
loss = net(data)
loss.backward()
trainer.step(data.shape[0])
epoch_loss += nd.mean(loss).asscalar()
n_batch_val = 0
for batch in test_iter:
n_batch_val +=1
data = batch.data[0].as_in_context(mx.cpu())
loss = net(data)
epoch_val_loss += nd.mean(loss).asscalar()
epoch_loss /= n_batch_train
epoch_val_loss /= n_batch_val
training_loss.append(epoch_loss)
validation_loss.append(epoch_val_loss)
"""if epoch % max(print_period, 1) == 0:
print('Epoch {}, Training loss {:.2f}, Validation loss {:.2f}'.
format(epoch, epoch_loss, epoch_val_loss))"""
end = time.time()
print('Training completed in {} seconds.'.format(int(end-start)))
利用深度學習來預測股票價格變動(長文,建議收藏)

Training completed in 62 seconds.

dataset_total_df['Date'] = dataset_ex_df['Date']
vae_added_df = mx.nd.array(dataset_total_df.iloc[:, :-1].values)
print('The shape of the newly created (from the autoencoder) features is {}.'.format(vae_added_df.shape))
利用深度學習來預測股票價格變動(長文,建議收藏)

The shape of the newly created (from the autoencoder) features is (2265, 112).

我們從自動編碼器中創建了112個更多特征。由于我們只想擁有高級特征(整體模式),我們將使用主成分分析(PCA)在新創建的112個特征上創建特征投資組合。這將減少數據的維度(列數)。Eigen組合的描述能力將與原始的112個特征相同。

注意再一次,這純粹是實驗性的。我并非100%確定描述的邏輯將成立。作為人工智能和深度學習的其他一切,這是藝術和需要實驗。

2.8.2、主成分分析的特征組合

# We want the PCA to create the new components to explain 80% of the variance
pca = PCA(n_components=.8)
x_pca = StandardScaler().fit_transform(vae_added_df)
principalComponents = pca.fit_transform(x_pca)
principalComponents.n_components_
利用深度學習來預測股票價格變動(長文,建議收藏)

84

所以,為了解釋80%的方差我們需要84個(112個)特征。這仍然是一個很大的問題。因此,目前我們不包括自動編碼器創建的特征。我將致力于創建autoencoder架構,在該架構中,我們從中間層(而不是最后一層)獲得輸出,并使用30個神經元將其連接到另一個Dense 層。因此,我們將1)只提取更高級別的特征,2)提供更少的列數。

3.生成性對抗網絡(GAN)

利用深度學習來預測股票價格變動(長文,建議收藏)

GAN的體系結構

GAN如何運作?

如前所述,本文的目的不是詳細解釋深度學習背后的數學,而是展示其應用。當然,在我看來,徹底和非常堅實的理解從基礎到最小的細節,是極其必要的。因此,我們將嘗試平衡并給出一個關于GAN如何工作的高級概述,以便讀者充分理解使用GAN預測股價走勢背后的原理。

GAN網絡由兩個模型組成 -?Generator(G)和Discriminator?(D)。訓練GAN的步驟如下:

  1. 使用隨機數據(噪聲表示為z),Generator試圖“生成”與真實數據無法區分或非常接近的數據。它的目的是學習真實數據的分布。
  2. 將隨機、真實或生成的數據擬合到Discriminator?中,Discriminator?作為分類器,試圖了解數據是來自Generator還是真實數據。
  3. 然后,G和D的損失被組合并通過Generator傳播回來。因此,Generator的損失取決于GeneratorDiscriminator?。這是幫助Generator了解真實數據分布的步驟。如果Generator在生成真實數據(具有相同分布)方面做得不好,則Discriminator的工作將很容易區分生成與實際數據集。因此,Discriminator?的損失將非常小。小的Discriminator?損失將導致更大的Generator損耗(參見下面的等式 L(D,G))。這使得創建Discriminator?有點棘手,因為Discriminator?太好會導致巨大的Generator損失,使得Generator無法學習。
  4. 該過程一直持續到Discriminator無法再將生成數據與實際數據區分開來。

當組合在一起時,D和G作為一種playing minmax游戲(Generator試圖欺騙Discriminator,使其增加假例子的概率,即最小化z?pz(z)[log(1-D(G) z)))]。Discriminator想要通過最大化x~pr(x)[logD(x)]來分離來自發生器D(G(z))的數據。但是,具有分離的損失函數,它是不清楚兩者如何匯合在一起(這就是為什么我們使用普通GAN的一些進步,例如Wasserstein GAN)。總的來說,組合損失函數看起來像:

利用深度學習來預測股票價格變動(長文,建議收藏)

3.1、為什么GAN用于股市預測

生成對抗網絡(GAN)最近主要用于創建逼真的圖像,繪畫和視頻剪輯。在我們的案例中,沒有多少GAN用于預測時間序列數據。然而,主要想法應該是相同的 - 我們希望預測未來的股票變動。在未來,GS股票的模式和行為應該或多或少相同(除非它開始以完全不同的方式運作,或者經濟急劇變化)。因此,我們希望“生成”未來的數據,這些數據將具有與我們已有的相似(當然不完全相同)的分布 - 歷史交易數據。所以,從理論上講,它應該有效。

在我們的例子中,我們將使用LSTM作為時間序列生成器,并使用CNN作為Discriminator

3.2、Metropolis-Hastings GAN和Wasserstein GAN

I. Metropolis-Hastings GAN

Uber的工程團隊最近對傳統GAN進行了改進,稱為Metropolis-Hastings GAN(MHGAN)。優步的方法背后的想法(正如他們所述)與谷歌和加州大學伯克利分校創建的另一種方法有點類似,稱為DRS。基本上,當我們訓練GAN時,我們使用Discriminator(D)的唯一目的是更好地訓練Generator(G)。通常,在訓練GAN之后我們不再使用D. 然而,MHGAN和DRS嘗試使用D來選擇由G生成的接近實際數據分布的樣本(MHGAN之間的微小差異是使用馬爾可夫鏈蒙特卡羅(MCMC)進行采樣)。

MHGAN采用從G生成的K個樣本(從獨立的噪聲輸入到下圖中的G-z0到zK)。然后它依次運行K個輸出(x'0到x'K)并遵循接受規則(從Discriminator創建)決定是接受當前樣本還是保留最后接受的樣本。最后保留的輸出是被認為是G的實際輸出的輸出。

注意:MHGAN最初由優步在pytorch中實現。我只把它轉移到MXNet / Gluon。

利用深度學習來預測股票價格變動(長文,建議收藏)

圖10:MHGAN的視覺表示

II。Wasserstein GAN

訓練GAN非常困難。模型可能永遠不會收斂,模式崩潰很容易發生。我們將使用名為Wasserstein GAN - WGAN的GAN修改。

最值得注意的要點是:

  • 我們知道GAN背后的主要目標是讓Generator開始將隨機噪聲轉換為我們想要模仿的某些給定數據。因此,在GAN中,比較兩個分布之間的相似性的想法是非常必要的。這兩個最廣泛使用的指標是:
  • KL散度(Kullback-Leibler) - DKL(p‖q)=∫xp(x)logp(x)q(x)dx。當p(x)等于q(x)時,DKL為零,
  • JS Divergence(Jensen-Shannon)。JS散度以0和1為界,與KL散度不同,它是對稱的,更平滑。當損失從KL轉移到JS散度時,GAN訓練取得了顯著的成功。
  • WGAN使用?Wasserstein距離,W(PR,PG)=1Ksup‖f‖L≤Kx~pr[F(X)] - x~pg[F(X)](其中supsup代表supremum),作為損失函數。與KL和JS的差異相比,Wasserstein度量提供了一個平滑的度量(沒有突然的跳躍)。這使得它更適合在梯度下降期間創建穩定的學習過程。
  • 此外,與KL和JS相比,Wasserstein距離幾乎無處不在。眾所周知,在反向傳播過程中,我們會區分損失函數以創建梯度,從而更新權重。因此,具有可微分的損失函數是非常重要的。

3.4、Generator - One layer RNN

3.4.1、LSTM或GRU

如前所述,Generator是LSTM網絡的一種循環神經網絡(RNN)。RNN用于時間序列數據,因為它們跟蹤所有先前的數據點,并且可以捕獲隨時間發展的模式。由于它們的性質,RNN很多時候都會受到梯度消失的影響 - 也就是說,在訓練期間權重變化的變化變得如此之小,以至于它們不會改變,使得網絡無法收斂到最小的損失(相反的問題也可以有時會觀察到 - 當梯度變得太大時。這稱為梯度爆炸,但解決方法很簡單。兩個方法解決了這個問題 - 門控循環單元(GRU)和長短期記憶(LSTM)。兩者之間最大的區別是:1)GRU有2個門(update 和reset),LSTM有4個(update, input, forget, 和output),2)LSTM保持內部存儲器狀態,而GRU沒有, 3)LSTM在輸出門之前應用非線性(sigmoid),GRU不應用。

在大多數情況下,LSTM和GRU在準確性方面給出了類似的結果,但GRU的計算密集程度要低得多,因為GRU的可訓練參數更少。然而,LSTM使用得更多。

嚴格地說,LSTM cell (gates)背后的數學是:

利用深度學習來預測股票價格變動(長文,建議收藏)

LSTM cell背后的數學

其中⊙是一個逐元素的乘法運算符,并且,對于所有x = [x1,x2,...,xk]?∈R^ k,激活函數:

利用深度學習來預測股票價格變動(長文,建議收藏)

3.4.2LSTM架構

LSTM架構非常簡單 - LSTM一層有112個輸入單元(因為我們在數據集中有112個特征)和500個隱藏單元,Dense層有1個輸出 - 每天的價格。初始化器是Xavier,我們將使用L1損失(這是L1正則化的平均絕對誤差損失)。

注意 - 在Python代碼中,您可以看到我們使用Adam(使用learning rate.01)作為優化器。

gan_num_features = dataset_total_df.shape[1]
sequence_length = 17
class RNNModel(gluon.Block):
def __init__(self, num_embed, num_hidden, num_layers, bidirectional=False,
sequence_length=sequence_length, **kwargs):
super(RNNModel, self).__init__(**kwargs)
self.num_hidden = num_hidden
with self.name_scope():
self.rnn = rnn.LSTM(num_hidden, num_layers, input_size=num_embed,
bidirectional=bidirectional, layout='TNC')

self.decoder = nn.Dense(1, in_units=num_hidden)

def forward(self, inputs, hidden):
output, hidden = self.rnn(inputs, hidden)
decoded = self.decoder(output.reshape((-1, self.num_hidden)))
return decoded, hidden

def begin_state(self, *args, **kwargs):
return self.rnn.begin_state(*args, **kwargs)

lstm_model = RNNModel(num_embed=gan_num_features, num_hidden=500, num_layers=1)
lstm_model.collect_params().initialize(mx.init.Xavier(), ctx=mx.cpu())
trainer = gluon.Trainer(lstm_model.collect_params(), 'adam', {'learning_rate': .01})
loss = gluon.loss.L1Loss()
利用深度學習來預測股票價格變動(長文,建議收藏)

我們將在LSTM層中使用500個神經元并使用Xavier初始化。為了正則化,我們將使用L1。讓我們來看看LSTMMXNet打印的內容。

print(lstm_model)
利用深度學習來預測股票價格變動(長文,建議收藏)

正如我們所看到的,LSTM的輸入是112個特征(dataset_total_df.shape[1])然后進入LSTM層中的500個神經元,然后轉換為單個輸出 - 股票價格值。

LSTM背后的邏輯是:我們取17天(sequence_length)的數據(同樣,這些數據是GS股票每天的股價+當天的所有其他特性——相關資產、情緒等),并嘗試預測第18天。

3.4.3、學習率調度程序

最重要的超參數之一是學習率。在訓練神經網絡時,為幾乎所有優化器(例如SGD,Adam或RMSProp)設置學習速率至關重要,因為它既能控制收斂速度,又能控制網絡的最終性能。最簡單的學習率策略之一是在整個訓練過程中具有固定的學習率。選擇較小的學習速率可以使優化器找到好的解決方案,但這是以限制初始收斂速度為代價的。隨著時間的推移改變學習率可以克服這種權衡。

讓我們繪制我們將在每個epoch使用的學習率。

class TriangularSchedule():
def __init__(self, min_lr, max_lr, cycle_length, inc_fraction=0.5):
self.min_lr = min_lr
self.max_lr = max_lr
self.cycle_length = cycle_length
self.inc_fraction = inc_fraction

def __call__(self, iteration):
if iteration <= self.cycle_length*self.inc_fraction:
unit_cycle = iteration * 1 / (self.cycle_length * self.inc_fraction)
elif iteration <= self.cycle_length:
unit_cycle = (self.cycle_length - iteration) * 1 / (self.cycle_length * (1 - self.inc_fraction))
else:
unit_cycle = 0
adjusted_cycle = (unit_cycle * (self.max_lr - self.min_lr)) + self.min_lr
return adjusted_cycle
class CyclicalSchedule():
def __init__(self, schedule_class, cycle_length, cycle_length_decay=1, cycle_magnitude_decay=1, **kwargs):
self.schedule_class = schedule_class
self.length = cycle_length
self.length_decay = cycle_length_decay
self.magnitude_decay = cycle_magnitude_decay
self.kwargs = kwargs

def __call__(self, iteration):
cycle_idx = 0
cycle_length = self.length
idx = self.length
while idx <= iteration:
cycle_length = math.ceil(cycle_length * self.length_decay)
cycle_idx += 1
idx += cycle_length
cycle_offset = iteration - idx + cycle_length

schedule = self.schedule_class(cycle_length=cycle_length, **self.kwargs)
return schedule(cycle_offset) * self.magnitude_decay**cycle_idx
schedule = CyclicalSchedule(TriangularSchedule, min_lr=0.5, max_lr=2, cycle_length=500)
iterations=1500
plt.plot([i+1 for i in range(iterations)],[schedule(i) for i in range(iterations)])
plt.title('Learning rate for each epoch')
plt.xlabel("Epoch")
plt.ylabel("Learning Rate")
plt.show()
利用深度學習來預測股票價格變動(長文,建議收藏)
利用深度學習來預測股票價格變動(長文,建議收藏)

3.4.4、如何防止過度擬合和偏差 - 方差權衡

有很多特征和神經網絡,我們需要確保我們避免過擬合,并注意總損失。

我們使用幾種技術來防止過度擬合(不僅在LSTM中,并且在CNN和自動編碼器中):

  • 確保數據質量。我們已經進行了統計檢查,確保數據不受多重共線性或序列自相關的影響。進一步,我們對每個特征執行了特征重要性檢查。最后,利用一些有關股票市場運作機制的領域知識進行了初始特征選擇(例如,選擇相關資產、技術指標等)。
  • 正規化(或權重懲罰)。兩種最廣泛使用的正則化技術是LASSO(L1)和Ridge(L2)。L1增加了平均絕對誤差,L2增加了平均誤差。在沒有涉及太多數學細節的情況下,基本區別是:LASSO回歸(L1)同時進行變量選擇和參數收縮,而Ridge歸僅進行參數收縮并最終包括模型中的所有系數。在存在相關變量的情況下,嶺回歸可能是首選。此外,嶺回歸在最小二乘估計具有較高方差的情況下效果最佳。因此,這取決于我們的模型目標。兩種類型的正則化的影響是完全不同的。雖然它們都會對大權重進行懲罰,但L1正則化會導致零不可微函數。L2正則化有利于較小的權重,但L1正則化有利于權重變為零。所以,使用L1正則化,您可以得到一個稀疏模型 - 一個參數較少的模型。在這兩種情況下,L1和L2正則化模型的參數“收縮”,但在L1正則化的情況下,收縮直接影響模型的復雜性(參數的數量)。
  • Dropout。Dropout層隨機刪除隱藏圖層中的節點。
  • ense-sparse-dense training
  • Early stopping.

構建復雜神經網絡時的另一個重要考慮因素是偏差 - 方差權衡。基本上,我們在訓練網絡時得到的誤差是偏差,方差和不可減少誤差的函數 - σ(由噪聲和隨機性引起的誤差)。權衡的最簡單公式是:Error=bias^2+variance+σ.

  • 偏見。偏差衡量訓練的(訓練數據集)算法在看不見的數據上的表現。高偏差(欠擬合)意味著模型不能很好地處理看不見的數據。
  • 方差。方差衡量模型對數據集變化的敏感性。高度差異是過度擬合。

3.5、Discriminator

為什么CNN作為Discriminator??

我們通常將CNN用于與圖像相關的工作(分類,上下文提取等)。例如,在狗的圖像中,第一個卷積層將檢測邊緣,第二個將開始檢測圓圈,第三個將檢測到鼻子。在我們的例子中,數據點形成小趨勢,小趨勢形成更大,趨勢形成模式。CNN檢測特征的能力可用于提取有關GS股票價格變動模式的信息。

使用CNN的另一個原因是CNN在空間數據上運行良好 - 這意味著彼此更接近的數據點彼此之間的相關性更高,而不是數據點。對于時間序列數據,這應該適用。在我們的例子中,每個數據點(對于每個特征)是連續的每一天。很自然地假設彼此距離越近,彼此之間的相關性就越大。需要考慮的一件事(雖然沒有涉及這項工作)是季節性以及它如何改變(如果有的話)CNN的工作。

3.5.1。CNN架構

利用深度學習來預測股票價格變動(長文,建議收藏)

建議的CNN模型的架構

GAN中CNN的Python代碼是這樣的:

num_fc = 512
# ... other parts of the GAN
cnn_net = gluon.nn.Sequential()
with net.name_scope():

# Add the 1D Convolutional layers
cnn_net.add(gluon.nn.Conv1D(32, kernel_size=5, strides=2))
cnn_net.add(nn.LeakyReLU(0.01))
cnn_net.add(gluon.nn.Conv1D(64, kernel_size=5, strides=2))
cnn_net.add(nn.LeakyReLU(0.01))
cnn_net.add(nn.BatchNorm())
cnn_net.add(gluon.nn.Conv1D(128, kernel_size=5, strides=2))
cnn_net.add(nn.LeakyReLU(0.01))
cnn_net.add(nn.BatchNorm())

# Add the two Fully Connected layers
cnn_net.add(nn.Dense(220, use_bias=False), nn.BatchNorm(), nn.LeakyReLU(0.01))
cnn_net.add(nn.Dense(220, use_bias=False), nn.Activation(activation='relu'))
cnn_net.add(nn.Dense(1))

# ... other parts of the GAN
利用深度學習來預測股票價格變動(長文,建議收藏)

讓我們打印CNN。

print(cnn_net)
利用深度學習來預測股票價格變動(長文,建議收藏)

3.6、超參數

我們將跟蹤和優化的超參數是:

  • batch_size :LSTM和CNN的批量大小
  • cnn_lr:CNN的學習率
  • strides:CNN中的strides
  • lrelu_alpha:GAN中LeakyReLU的alpha
  • batchnorm_momentum:momentum for the batch normalisation in the CNN
  • padding:CNN中的padding
  • kernel_size':1:CNN中的核大小
  • dropout:LSTM中的dropout
  • filters:初始filters數量

我們將訓練超過200個epochs。

4.超參數優化

在200個epochs的GAN訓練之后,它將記錄MAE(這是LSTM中的誤差函數,GG)并將其作為獎勵值傳遞給強化學習,該學習決定是否改變繼續訓練的超參數。

如果RL決定它將更新超參數,它將調用貝葉斯優化(下面討論)庫,它將提供下一個最佳預期的超級參數集

4.1、超參數優化的強化學習

為什么我們在超參數優化中使用強化學習?股市一直在變化。即使我們設法訓練我們的GAN和LSTM以創建非常準確的結果,結果可能僅在一段時間內有效。意思是,我們需要不斷優化整個過程。為了優化流程,我們可以:

  • 添加或刪除特征(例如添加可能相關的新股票或貨幣)
  • 改善我們的深度學習模式。改進機器學習模型的最重要方法之一是通過超參數。一旦找到了一組超參數,我們就需要決定何時更改它們以及何時使用已知的集合(探索與利用)。此外,股市代表一個連續的空間,取決于數百萬參數。

4.1.1、強化學習理論

在不解釋RL的基礎知識的情況下,我們將詳細介紹我們在此實現的具體方法。我們將使用model-free RL算法,原因很明顯我們不了解整個環境,因此沒有明確的環境工作模型 - 如果我們不需要預測股票價格變動 - 它們只會按照該模型。我們將使用model-free RL的兩個細分 - 策略優化和Q學習。

  • Q-learning - 在Q-learning中我們學習從一個給定的狀態采取動作的價值。Q值是采取動作后的預期回報。我們將使用Rainbow,它是七種Q學習算法的組合。
  • 策略優化 - 在策略優化中,我們學習從給定狀態采取的動作。(如果我們使用像Actor / Critic這樣的方法),我們也會學習處于給定狀態的值。我們將使用近端策略優化。

構建RL算法的一個關鍵方面是準確設置獎勵。它必須捕獲環境的所有方面以及代理與環境的交互。我們將獎勵R定義為:

Reward=2?lossG+lossD+accuracyG,

其中lossG,accuracyG和lossD分別是Generator的損失和準確性,以及Discriminator的損失。環境是GAN和LSTM訓練的結果。不同代理可以采取的動作是如何更改GAN的D和G網絡的超參數。

4.1.1.1、Rainbow

Rainbow(link)是一種基于Q學習的非策略深度強化學習算法,它將七種算法結合在一起:

  • DQN。DQN是Q學習算法的擴展,其使用神經網絡來表示Q值。與監督(深度)學習類似,在DQN中,我們訓練神經網絡并嘗試最小化損失函數。我們通過隨機抽樣轉換(狀態、動作、獎勵)來訓練網絡。例如,這些層不僅可以是全連接層,而且可以是卷積層。
  • Double Q學習。Double QL處理Q學習中的一個大問題,即高估偏差。
  • Prioritized replay。在vanilla DQN中,所有轉換都存儲在replay 緩沖區中,并均勻地對此緩沖區進行采樣。然而,并非所有transitions在學習階段都同樣有益(這也使得學習效率低,因為需要更多的episodes )。Prioritized experience replay 不是均勻采樣,而是使用分布,該分布為先前迭代中具有較高Q損失的樣本提供更高的概率。
  • Dueling networksDueling networks通過使用兩個單獨的流(即具有兩個不同的微型神經網絡)來稍微改變Q學習架構。一個流用于值,一個用于優勢。它們都共享一個卷積編碼器。棘手的部分是流的合并 - 它使用了一個特殊的聚合器(Wang et al.2016)。
  • Multi-step learningMulti-step learning背后的巨大差異在于它使用N步返回計算Q值(不僅是下一步的返回),這自然應該更準確。
  • 分布式RL。Q學習使用平均估計的Q值作為目標值。但是,在許多情況下,Q值在不同情況下可能不同。分布式RL可以直接學習(或近似)Q值的分布,而不是對它們求平均值。再次,數學比這復雜得多,但對我們來說,好處是Q值的更準確的采樣。
  • Noisy Nets。基本DQN實現了一個簡單的ε-貪婪機制來進行探索。這種探索方法有時效率低下。Noisy Nets解決這個問題的方法是添加一個有噪聲的線性層。隨著時間的推移,網絡將學習如何忽略噪聲(添加為嘈雜的流)。但是這種學習在空間的不同部分以不同的速度進行,允許進行狀態探索。

4.1.1.2、PPO

近端策略優化(PPO)是一種無策略優化模型的強化學習。實現其他算法要簡單得多,效果非常好。

我們為什么要使用PPO?PPO的一個優點是它直接學習策略,而不是間接地通過值(Q學習使用Q值來學習策略的方式)。它可以在連續動作空間中很好地工作,這在我們的使用案例中是合適的,并且可以(通過平均值和標準偏差)學習分布概率(如果將softmax作為輸出添加)。

政策梯度方法的問題在于它們對步長選擇極其敏感 - 如果它很小,則進度需要太長時間(很可能主要是由于需要二階導數矩陣); 如果它很大,會有很多噪音會顯著降低性能。由于政策的變化(以及獎勵和觀察變化的分布),輸入數據是非平穩的。與監督學習相比,選擇不當的步驟可能會更具破壞性,因為它會影響下次訪問的整個分布。PPO可以解決這些問題。更重要的是,與其他一些方法相比,PPO:

  • 例如,與ACER(它需要額外的代碼來保持策略外相關性和replay 緩沖區)或TRPO(它對代理目標函數施加了約束,即新舊策略之間的KL差異)相比,前者要簡單得多。這個約束用于控制過多更改的策略——這可能會造成不穩定。PPO減少了計算(由約束)利用 clipped 之間([1 -1 +])替代目標函數和修改目標函數用懲罰有太大的更新。
  • 與TRPO相比,它與在值和策略函數或輔助損失之間共享參數的算法兼容(盡管PPO也具有信任區域PO的增益)。

注意:出于練習的目的,我們不會過多地研究和優化RL方法,PPO和其他方法。相反,我們將采用可用的方法,并嘗試適應我們的GAN,LSTM和CNN模型的超參數優化過程。我們將重用和自定義的Python代碼由OpenAI創建,可在此處獲得(https://github.com/openai/baselines)。

4.1.2、進一步加強學習的工作

進一步探索強化學習的一些想法:

  • 我接下來要介紹的第一件事是使用增強隨機搜索(https://arxiv.org/pdf/1803.07055.pdf)作為替代算法。該算法的作者(在UC,Berkeley之外)已經設法獲得與其他最先進的方法(如PPO)類似的獎勵結果,但平均快15倍。
  • 選擇獎勵函數非常重要。
  • 使用好奇心作為探索政策。
  • 根據伯克利的AI研究團隊(BAIR)提出的建立多代理體系結構 - 鏈接(https://bair.berkeley.edu/blog/2018/12/12/rllib/)。

4.2、貝葉斯優化

我們將使用貝葉斯優化來代替網格搜索,這可能需要花費大量時間來找到超參數的最佳組合。我們將使用的庫已經實現 - 鏈接(https://github.com/fmfn/BayesianOptimization)。

4.2.1、高斯過程

# Initialize the optimizer
from bayes_opt import BayesianOptimization
from bayes_opt import UtilityFunction
utility = UtilityFunction(kind="ucb", kappa=2.5, xi=0.0)
利用深度學習來預測股票價格變動(長文,建議收藏)

4.2.2、高斯過程結果

利用深度學習來預測股票價格變動(長文,建議收藏)

5.結果

最后,當在過程的不同階段之后將看不見的(測試)數據用作輸入時,我們將比較LSTM的輸出。

  1. 在第一個epoch之后繪制圖像。
from utils import plot_prediction
plot_prediction('Predicted and Real price - after first epoch.')
利用深度學習來預測股票價格變動(長文,建議收藏)

2.繪制50個epochs后的圖像。

plot_prediction('Predicted and Real price - after first 50 epochs.')
利用深度學習來預測股票價格變動(長文,建議收藏)
plot_prediction('Predicted and Real price - after first 200 epochs.')
利用深度學習來預測股票價格變動(長文,建議收藏)

RL運行en episodes(我們將eposide定義為200個epochs上的一個完整GAN訓練)。

plot_prediction('Final result.')
利用深度學習來預測股票價格變動(長文,建議收藏)

轉載于:https://www.cnblogs.com/changbaishan/p/10266395.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/395458.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395458.shtml
英文地址,請注明出處:http://en.pswp.cn/news/395458.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言 用鏈表對學號進行排序,求解C語言中建立一個對鏈表按照學號進行排序的問題...

功能&#xff1a;選擇排序(由小到大)返回&#xff1a;指向鏈表表頭的指針*//*選擇排序的基本思想就是反復從還未排好序的那些節點中&#xff0c;選出鍵值(就是用它排序的字段&#xff0c;我們取學號num為鍵值)最小的節點&#xff0c;依次重新組合成一個鏈表。我認為寫鏈表這類程…

字符集(CHARACTER SET)和校對集(COLLATE)

http://blog.sina.com.cn/s/blog_9707fac301016wxm.html http://www.th7.cn/db/mysql/201412/84636.shtml 從上文中可以看出character_set_connection、character_set_client、 character_set_results三個字符集什么時候用到。從實際上可以看到&#xff0c;當客戶端連接服務器的…

shell 本地接口自動化

一.基于http/https的接口 一般情況下&#xff0c;當前大多公司在做接口自動化的時候都會使用一些工具&#xff1b;比如&#xff1a;postman/jmeter/python自研開發接口平臺。。。 以上的情況&#xff0c;都是在源碼與測試使用分離的情況下實踐的。也就是說&#xff1a;目前國內…

hitchhiker部署_《 Hitchhiker的Python機器學習指南》

hitchhiker部署by Conor Dewey由Conor Dewey 《 Hitchhiker的Python機器學習指南》 (The Hitchhiker’s Guide to Machine Learning in Python) 提供實施代碼&#xff0c;教學視頻等 (Featuring implementation code, instructional videos, and more) 趨勢 (The Trend) Machi…

CAD庫中列舉所有航路點

select distinct f1.airway_point_name,f1.latitude,f1.longitude,upper(f1.airway_point_type_name)type,f2.code_fir from airway_ordered_point f1, v_airway_point f2where f2.significant_point_idf1.airway_point_idorder by code_fir, type,airway_point_name轉載于:htt…

第50次二級c語言真題,2006年4月全國計算機等級考試二級C語言筆試試卷含答案

一、選擇題((1)一(10)每題2分&#xff0c;(11)一(50)每題1分&#xff0c;共60分)下列各題A)、B)、C)、D)四個選項中&#xff0c;只有一個選項是正確的&#xff0c;請將正確選項涂寫在答題卡相應位置上&#xff0c;答在試卷上不得分。(1)下列選項中不屬于結構化程序設計方法的是…

python hashlib模塊

摘要算法簡介 Python的hashlib提供了常見的摘要算法&#xff0c;如MD5&#xff0c;SHA1等等。 什么是摘要算法呢&#xff1f;摘要算法又稱哈希算法、散列算法。它通過一個函數&#xff0c;把任意長度的數據轉換為一個長度固定的數據串&#xff08;通常用16進制的字符串表示&…

TZOJ 5101 A Game(區間DP)

描述 Consider the following two-player game played with a sequence of N positive integers (2 < N < 100) laid onto a 1 x N game board. Player 1 starts the game. The players move alternately by selecting a number from either the left or the right end o…

國家職業標準職業編碼查詢_為什么我學會編碼而不是從事金融職業

國家職業標準職業編碼查詢by Amir Ghafouri通過阿米爾加富里(Amir Ghafouri) 為什么我學會編碼而不是從事金融職業 (Why I learned to code instead of pursuing a career in finance) Last year I faced a major life and career decision: commit to pursuing a Chartered F…

go tool trace goalng調優工具

為什么80%的碼農都做不了架構師&#xff1f;>>> 你想知道你的Go程序在做什么嗎&#xff1f; go tool trace 可以向你揭示&#xff1a;Go程序運行中的所有的運行時事件。 這種工具是Go生態系統中用于診斷性能問題時&#xff08;如延遲&#xff0c;并行化和競爭異常…

程序員 文本編輯器 c語言,程序員必備的五款文本編輯器

原標題&#xff1a;程序員必備的五款文本編輯器程序員的工作離不開文本編輯器&#xff0c;有人說一個txt就能搞定&#xff0c;但txt面對如今復雜的要求&#xff0c;明顯有些捉襟見肘&#xff0c;下面推薦五款超級好用的文本編輯器及搭配軟件&#xff0c;絕對是程序員的大愛。程…

PCH文件的創建和配置

1.PCH文件的的創建 (1)CommandN (2)打開新建文件窗口:ios->other->PCH file&#xff0c;創建一個pch文件 2.PCH文件的配置 (1)在工程的TARGETS里邊Building Setting中搜索Prefix Header (2)然后在Precompile Prefix Header下邊的Prefix Header右邊雙擊&#xff0c;添加剛…

ci 數據庫異常捕獲_系統地捕獲錯誤:如何通過4個步驟構建GitLab CI測試管道

ci 數據庫異常捕獲by Joyz通過喬伊斯 系統地捕獲錯誤&#xff1a;如何通過4個步驟構建GitLab CI測試管道 (Catch bugs systematically: how to build a GitLab CI testing pipeline in 4 steps) Your first app is a hit the day it’s launched. But one week later, you rea…

(小白)函數一: 聲明函數的方法—語句定義法和表達式定義法的區別

一、函數的定義&#xff1a; 在說明什么是函數前先舉一個小例子&#xff1a; 大家都知道印刷術是我國的四大發明&#xff08;科普一下&#xff1a;中國四大發明&#xff1a;造紙術、印刷術、火藥、指南針&#xff09;之一&#xff0c;之所以有印刷術&#xff0c;是因為重復的抄…

android限制輸入字符的范圍,Android EditText 對輸入字數和內容范圍進行限制

在做定制機時&#xff0c;對光敏值進行范圍控制時&#xff0c;以及對區號輸入時遇到對輸入字數以及輸入內容的顯示。找了好多方法&#xff0c;終于找到了幾種方法其中EditText的addTextChangedListener功不可沒。例如對光敏值要在0到61之間。大于61時要在輸入框中自動變為61.代…

vue13過濾器 debounce延遲、limitBy、filterBy、orderBy

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>智能社——http://www.zhinengshe.com</title><meta name"viewport" content"widthdevice-width, initial-scale1.0, maximum…

Sass:一種CSS預處理器語言

http://sass-lang.com/ Sass是一種CSS預處理器語言&#xff0c;通過編程方式生成CSS代碼。因為可編程&#xff0c;所以操控靈活性自由度高&#xff0c;方便實現一些直接編寫CSS代碼較困難的代碼。 同時&#xff0c;因為Sass是生成CSS的語言&#xff0c;所以寫出來的Sass文件是不…

Python學習(五)列表的簡單操作

#!/usr/bin/env python#_*_coding:utf8_*_# 操作列表# for循環nbaStars [yaoming,kobe,manu,23,the klaw]for nbaStar in nbaStars: print(nbaStar)nbaStars [yaoming,kobe,manu,str(23),the klaw] # 這里有 int 對象&#xff0c;沒有title方法的for nbaStar in nbaStars:…

node seneca_使用Node.js和Seneca編寫國際象棋微服務,第3部分

node senecaFinishing up a three-part series on writing a rules engine with Seneca microservices.完成有關使用Seneca微服務編寫規則引擎的三部分系列文章。 Parts 1 & 2 of this series covered:本系列的第1部分和第2部分涉及&#xff1a; The Seneca microservice…

Android開發畫布銷毀,Android DialogFragment 在頁面銷毀下的使用方式

今天看到了一篇文章,講了DialogFragment的封裝方式(Android&#xff1a;我為何要封裝DialogFragment&#xff1f;),想到當初也為頁面銷毀后DialogFragment的回調方式頭疼了好久,看到了po主的思路,與當初自己想的不太一樣,就整理一下.如何在開發中遇到頁面銷毀的情況在android開…