久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

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

 天下小糧倉 2019-01-12
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

完整架構(gòu)概述

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

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

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

為了創(chuàng)建所有神經(jīng)網(wǎng)絡(luò),,我們將使用MXNet和它的高級API - Gluon,,并在多個GPU上訓(xùn)練它們。

注:盡管我試圖深入探討數(shù)學(xué)和幾乎所有算法和技術(shù)背后的機(jī)制,,但本文并沒有明確地解釋機(jī)器/深度學(xué)習(xí)或股票市場是如何運作的,。其目的是展示我們?nèi)绾问褂貌煌募夹g(shù)和算法來準(zhǔn)確預(yù)測股票價格的變動,并給出每一步使用每種技術(shù)的原因和有用性背后的理論基礎(chǔ),。

1.簡介

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

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

2.數(shù)據(jù)

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

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

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

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

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

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)
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

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

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.

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

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

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))
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

2.1,、相關(guān)資產(chǎn)

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

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

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

總的來說,,我們在數(shù)據(jù)集中有72個其他資產(chǎn) - 每個資產(chǎn)的每日價格,。

2.2、技術(shù)指標(biāo)

我們已經(jīng)討論了什么是技術(shù)指標(biāo)以及為什么使用它們,,現(xiàn)在讓我們直接跳到Python代碼,。我們將只為GS創(chuàng)建技術(shù)指標(biāo)。

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

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

讓我們想象一下這些指標(biāo)的最后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)
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

2.3、基本面分析

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

2.3.1,、 BERT

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

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

# just import bert
import bert

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

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

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

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

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

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

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

用于去噪數(shù)據(jù)的另一種技術(shù)是調(diào)用小波,。小波和傅里葉變換給出了類似的結(jié)果,因此我們只使用傅里葉變換,。

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

2.5,、ARIMA作為一項特征值

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

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())
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

from pandas.tools.plotting import autocorrelation_plot
autocorrelation_plot(series)
plt.figure(figsize=(10, 7), dpi=80)
plt.show()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

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

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)
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

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

從圖5中可以看出,,ARIMA給出了一個非常接近實際股價的結(jié)果。我們將通過ARIMA使用預(yù)測價格作為LSTM的輸入特征,,因為正如我們前面提到的,,我們希望盡可能多地捕獲關(guān)于高盛的特征和模式,。我們測試MSE(均方誤差)為10.151,這本身并不是一個壞結(jié)果(考慮到我們有很多測試數(shù)據(jù)),,但是我們?nèi)匀恢粚⑵渥鳛長STM中的一個特征,。

2.6、統(tǒng)計檢查

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

2.6.1、異方差性,,多重共線性,,序列相關(guān)性

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

我們不會在這里進(jìn)入代碼,因為它很簡單,,我們的重點更多地放在深度學(xué)習(xí)部分,,但數(shù)據(jù)是定性的,。

2.7,、特征工程

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

Total dataset has 2265 samples, and 112 features.

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

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

2.7.1、XGBoost的重要性

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

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

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']))
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

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

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

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

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

在我們進(jìn)入自動編碼器之前,,我們將探索激活函數(shù)。

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

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

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

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

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)
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

讓我們來看看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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

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

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

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

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

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)
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

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

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)))
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

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))
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

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

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

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_
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,建議收藏)

84

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

3.生成性對抗網(wǎng)絡(luò)(GAN)

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

GAN的體系結(jié)構(gòu)

GAN如何運作,?

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

GAN網(wǎng)絡(luò)由兩個模型組成 - Generator(G)和Discriminator (D),。訓(xùn)練GAN的步驟如下:

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

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

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

3.1,、為什么GAN用于股市預(yù)測

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

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

3.2、Metropolis-Hastings GAN和Wasserstein GAN

I. Metropolis-Hastings GAN

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

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

注意:MHGAN最初由優(yōu)步在pytorch中實現(xiàn)。我只把它轉(zhuǎn)移到MXNet / Gluon,。

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

圖10:MHGAN的視覺表示

II。Wasserstein GAN

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

最值得注意的要點是:

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

3.4,、Generator - One layer RNN

3.4.1,、LSTM或GRU

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

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

嚴(yán)格地說,,LSTM cell (gates)背后的數(shù)學(xué)是:

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

LSTM cell背后的數(shù)學(xué)

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

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

3.4.2LSTM架構(gòu)

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

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

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

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

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

LSTM背后的邏輯是:我們?nèi)?7天(sequence_length)的數(shù)據(jù)(同樣,,這些數(shù)據(jù)是GS股票每天的股價+當(dāng)天的所有其他特性——相關(guān)資產(chǎn),、情緒等),并嘗試預(yù)測第18天,。

3.4.3,、學(xué)習(xí)率調(diào)度程序

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

讓我們繪制我們將在每個epoch使用的學(xué)習(xí)率。

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()
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

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

3.4.4、如何防止過度擬合和偏差 - 方差權(quán)衡

有很多特征和神經(jīng)網(wǎng)絡(luò),,我們需要確保我們避免過擬合,,并注意總損失。

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

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

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

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

3.5,、Discriminator

為什么CNN作為Discriminator?,?

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

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

3.5.1,。CNN架構(gòu)

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

建議的CNN模型的架構(gòu)

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
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

讓我們打印CNN,。

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

3.6,、超參數(shù)

我們將跟蹤和優(yōu)化的超參數(shù)是:

  • batch_size :LSTM和CNN的批量大小
  • cnn_lr:CNN的學(xué)習(xí)率
  • 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數(shù)量

我們將訓(xùn)練超過200個epochs,。

4.超參數(shù)優(yōu)化

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

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

4.1、超參數(shù)優(yōu)化的強(qiáng)化學(xué)習(xí)

為什么我們在超參數(shù)優(yōu)化中使用強(qiáng)化學(xué)習(xí),?股市一直在變化,。即使我們設(shè)法訓(xùn)練我們的GAN和LSTM以創(chuàng)建非常準(zhǔn)確的結(jié)果,結(jié)果可能僅在一段時間內(nèi)有效,。意思是,,我們需要不斷優(yōu)化整個過程。為了優(yōu)化流程,,我們可以:

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

4.1.1、強(qiáng)化學(xué)習(xí)理論

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

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

構(gòu)建RL算法的一個關(guān)鍵方面是準(zhǔn)確設(shè)置獎勵。它必須捕獲環(huán)境的所有方面以及代理與環(huán)境的交互,。我們將獎勵R定義為:

Reward=2?lossG+lossD+accuracyG,

其中l(wèi)ossG,,accuracyG和lossD分別是Generator的損失和準(zhǔn)確性,以及Discriminator的損失,。環(huán)境是GAN和LSTM訓(xùn)練的結(jié)果,。不同代理可以采取的動作是如何更改GAN的D和G網(wǎng)絡(luò)的超參數(shù),。

4.1.1.1,、Rainbow

Rainbow(link)是一種基于Q學(xué)習(xí)的非策略深度強(qiáng)化學(xué)習(xí)算法,,它將七種算法結(jié)合在一起:

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

4.1.1.2、PPO

近端策略優(yōu)化(PPO)是一種無策略優(yōu)化模型的強(qiáng)化學(xué)習(xí),。實現(xiàn)其他算法要簡單得多,,效果非常好。

我們?yōu)槭裁匆褂肞PO,?PPO的一個優(yōu)點是它直接學(xué)習(xí)策略,,而不是間接地通過值(Q學(xué)習(xí)使用Q值來學(xué)習(xí)策略的方式)。它可以在連續(xù)動作空間中很好地工作,,這在我們的使用案例中是合適的,,并且可以(通過平均值和標(biāo)準(zhǔn)偏差)學(xué)習(xí)分布概率(如果將softmax作為輸出添加)。

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

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

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

4.1.2、進(jìn)一步加強(qiáng)學(xué)習(xí)的工作

進(jìn)一步探索強(qiáng)化學(xué)習(xí)的一些想法:

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

4.2,、貝葉斯優(yōu)化

我們將使用貝葉斯優(yōu)化來代替網(wǎng)格搜索,,這可能需要花費大量時間來找到超參數(shù)的最佳組合,。我們將使用的庫已經(jīng)實現(xiàn) - 鏈接(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)
利用深度學(xué)習(xí)來預(yù)測股票價格變動(長文,,建議收藏)

4.2.2,、高斯過程結(jié)果

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

5.結(jié)果

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

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

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

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

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

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

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

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多