午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

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

 leafcho 2019-01-11

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

完整架構(gòu)概述

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

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

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

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

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

1.簡介

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

我們將嘗試預(yù)測高盛(NYSE: GS)的價(jià)格走勢。為此,我們將使用2010年1月1日至2018年12月31日的每日收盤價(jià)(七年數(shù)據(jù)用于訓(xùn)練,兩年數(shù)據(jù)用于驗(yàn)證)。我們將交替使用“高盛”和“GS”這兩個(gè)術(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ì)的解釋,但是,作為一個(gè)高層次的概述,我們將使用的特征是:

  1. 相關(guān)資產(chǎn) - 這些是其他資產(chǎn)(任何類型,不一定是股票,如商品,外匯,指數(shù),甚至固定收益證券)。像高盛這樣的大公司顯然不會(huì)“生活”在一個(gè)孤立的世界中 - 它依賴于許多外部因素,并與之相互作用,包括競爭對手,客戶,全球經(jīng)濟(jì),地緣政治形勢,財(cái)政和貨幣政策,獲得資金等。詳情將在后面列出。
  2. 技術(shù)指標(biāo) - 很多投資者都遵循技術(shù)指標(biāo)。我們將最受歡迎的指標(biāo)作為獨(dú)立特征。如 - 7和21天移動(dòng)平均線,指數(shù)移動(dòng)平均線,momentum,布林線,MACD。
  3. 一個(gè)非常重要的特征,表明股票可能上漲或下跌。基本面分析有兩個(gè)特征:1)使用10-K和10-Q報(bào)告分析公司業(yè)績,分析ROE和P/E等(我們不會(huì)使用這個(gè));我們將為高盛(Goldman Sachs)和閱讀每日新聞提取總情緒是否對高盛(Goldman Sachs)在那一天是正面的,還是負(fù)面的(如得分從0到1)。由于許多投資者會(huì)仔細(xì)閱讀新聞,并根據(jù)新聞(當(dāng)然是部分依據(jù)新聞)做出投資決策,因此,如果高盛(Goldman Sachs)今天的消息非常正面,那么該股明天將大幅上漲的可能性在一定程度上是很高的。關(guān)鍵的一點(diǎn)是,我們將在以后對每個(gè)特征(包括這個(gè)特征)執(zhí)行特征重要性(意思是它對GS波動(dòng)的指示性),并決定是否使用它。我們將使用

    BERT

    - 谷歌最近公布的NLP方法,用于情感分類股票新聞情緒提取的遷移學(xué)習(xí)。
  4. 傅里葉變換 - 除了每日收盤價(jià),我們還將創(chuàng)建傅里葉變換,以概括多個(gè)長期和短期趨勢。使用這些變換,我們將消除大量噪聲(隨機(jī)游走)并創(chuàng)建真實(shí)股票移動(dòng)的近似值。趨勢近似可以幫助LSTM網(wǎng)絡(luò)更準(zhǔn)確地選擇其預(yù)測趨勢。
  5. 自回歸整合移動(dòng)平均線(ARIMA) - 這是預(yù)測時(shí)間序列數(shù)據(jù)未來值的最流行的技術(shù)之一(在pre-neural網(wǎng)絡(luò)時(shí)代)。讓我們添加它,看看它是否是一個(gè)重要的預(yù)測特征。
  6. 棧式自動(dòng)編碼器 - 上述大部分特征(基礎(chǔ)分析、技術(shù)分析等)都是人們經(jīng)過幾十年的研究發(fā)現(xiàn)的。也許有一些隱藏的相關(guān)性,人們無法理解,因?yàn)橛写罅康臄?shù)據(jù)點(diǎn)、事件、資產(chǎn)、圖表等。通過棧式自動(dòng)編碼器(神經(jīng)網(wǎng)絡(luò)的類型),我們可以利用計(jì)算機(jī)的力量,可能會(huì)發(fā)現(xiàn)影響股票走勢的新類型的特征。即使我們無法理解人類語言中的這些特征,我們也將在GAN中使用它們。
  7. 期權(quán)定價(jià)中異常檢測的深度無監(jiān)督學(xué)習(xí)。我們將再使用一項(xiàng)功能 - 每天我們都會(huì)為高盛股票增加90天看漲期權(quán)的價(jià)格。期權(quán)定價(jià)本身結(jié)合了大量數(shù)據(jù)。期權(quán)合約的價(jià)格取決于股票的未來值(分析師也試圖預(yù)測價(jià)格,以便為看漲期權(quán)提供最準(zhǔn)確的價(jià)格)。使用深度無監(jiān)督機(jī)器學(xué)習(xí)(Self-organized Maps),我們將嘗試發(fā)現(xiàn)每天定價(jià)中的異常情況。異常(例如價(jià)格的劇烈變化)可能表明一個(gè)事件可能對LSTM了解整個(gè)股票模式有用。

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

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

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

from utils import *import timeimport numpy as npfrom mxnet import nd, autograd, gluonfrom mxnet.gluon import nn, rnnimport mxnet as mximport datetimeimport seaborn as snsimport matplotlib.pyplot as plt%matplotlib inlinefrom sklearn.decomposition import PCAimport mathfrom sklearn.preprocessing import MinMaxScalerfrom sklearn.metrics import mean_squared_errorfrom sklearn.preprocessing import StandardScalerimport xgboost as xgbfrom sklearn.metrics import accuracy_scoreimport warningswarnings.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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

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

那么,還有哪些資產(chǎn)會(huì)影響高盛的股價(jià)走勢呢?對公司、業(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ì)價(jià))利率,因?yàn)榉治鰩熆赡軙?huì)考慮經(jīng)濟(jì)的沖擊來設(shè)定這些利率以及其他FI證券。
  • 每日波動(dòng)率指數(shù)(VIX) - 由于前一點(diǎn)所述的原因。
  • 綜合指數(shù) - 例如納斯達(dá)克和紐約證券交易所(美國)、FTSE100指數(shù)(英國)、Nikkei225指數(shù)(日本)、恒生指數(shù)和BSE Sensex指數(shù)(亞太)。
  • 貨幣 - 全球貿(mào)易多次反映貨幣如何變動(dòng),因此我們將使用一籃子貨幣(如美元兌日元,英鎊兌美元等)作為特征。

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

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 datasetdataset_TI_df = get_technical_indicators(dataset_ex_df[['GS']])dataset_TI_df.head()

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

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

所以我們有每個(gè)交易日的技術(shù)指標(biāo)(包括MACD、Bollinger bands等)。我們總共有12項(xiàng)技術(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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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í)例化它們并添加兩個(gè)(任意數(shù)量)Dense層,softmax - 得分從0到1。

# just import bertimport bert

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

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

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

我們將使用傅里葉變換來提取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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

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

from collections import dequeitems = 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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

2.5、ARIMA作為一項(xiàng)特征值

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

from statsmodels.tsa.arima_model import ARIMAfrom pandas import DataFramefrom pandas import datetimeseries = data_FT['GS']model = ARIMA(series, order=(5, 1, 0))model_fit = model.fit(disp=0)print(model_fit.summary())

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

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

from pandas.tools.plotting import autocorrelation_plotautocorrelation_plot(series)plt.figure(figsize=(10, 7), dpi=80)plt.show()

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

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

from pandas import read_csvfrom pandas import datetimefrom statsmodels.tsa.arima_model import ARIMAfrom sklearn.metrics import mean_squared_errorX = series.valuessize = 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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

Test MSE: 10.151

# Plot the predicted (from ARIMA) and real pricesplt.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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

2.6、統(tǒng)計(jì)檢查

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

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

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

我們不會(huì)在這里進(jìn)入代碼,因?yàn)樗芎唵?,我們的重點(diǎ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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

Total dataset has 2265 samples, and 112 features.

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

我們還將從自動(dòng)編碼器生成更多特征。

2.7.1、XGBoost的重要性

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

由于特征數(shù)據(jù)集非常大,出于演示目的,我們將僅使用技術(shù)指標(biāo)。在真實(shí)特征重要性測試期間,所有選定的特征都證明有些重要,因此我們在訓(xùn)練GAN時(shí)不會(huì)排除任何內(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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

讓我們繪制訓(xùn)練和驗(yà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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

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

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

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

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

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

我們將使用GELU作為自動(dòng)編碼器。

注:下面的單元格展示了GELU數(shù)學(xué)背后的邏輯。它不是作為激活函數(shù)的實(shí)際實(shí)現(xiàn)。我必須在MXNet中實(shí)現(xiàn)GELU。如果您按照代碼將act_type='relu'更改為act_type='gelu',那么它將不起作用,除非您更改MXNet的實(shí)現(xiàn)。對整個(gè)項(xiàng)目發(fā)出pull請求,以訪問GELU的MXNet實(shí)現(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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

讓我們來看看GELU、ReLU和LeakyReLU(最后一個(gè)主要用于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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

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

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

batch_size = 64n_batches = VAE_data.shape[0]/batch_sizeVAE_data = VAE_data.valuestrain_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 lossn_hidden=400 # neurons in each layern_latent=2 n_layers=3 # num of dense layers in encoder and decoder respectivelyn_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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

n_epoch = 150print_period = n_epoch // 10start = 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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

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

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

# We want the PCA to create the new components to explain 80% of the variancepca = PCA(n_components=.8)x_pca = StandardScaler().fit_transform(vae_added_df)principalComponents = pca.fit_transform(x_pca)principalComponents.n_components_

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

84

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

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

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

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

GAN如何運(yùn)作?

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

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

  1. 使用隨機(jī)數(shù)據(jù)(噪聲表示為z),

    Generator

    試圖“生成”與真實(shí)數(shù)據(jù)無法區(qū)分或非常接近的數(shù)據(jù)。它的目的是學(xué)習(xí)真實(shí)數(shù)據(jù)的分布。
  2. 將隨機(jī)、真實(shí)或生成的數(shù)據(jù)擬合到

    Discriminator

    中,

    Discriminator

    作為分類器,試圖了解數(shù)據(jù)是來自

    Generator

    還是真實(shí)數(shù)據(jù)。
  3. 然后,G和D的損失被組合并通過

    Generator

    傳播回來。因此,

    Generator

    的損失取決于

    Generator

    Discriminator

    。這是幫助Generator了解真實(shí)數(shù)據(jù)分布的步驟。如果

    Generator

    在生成真實(shí)數(shù)據(jù)(具有相同分布)方面做得不好,則

    Discriminator

    的工作將很容易區(qū)分生成與實(shí)際數(shù)據(jù)集。因此,

    Discriminator

    的損失將非常小。小的

    Discriminator

    損失將導(dǎo)致更大的

    Generator

    損耗(參見下面的等式 L(D,G))。這使得創(chuàng)建

    Discriminator

    有點(diǎn)棘手,因?yàn)?p>Discriminator

    太好會(huì)導(dǎo)致巨大的

    Generator

    損失,使得

    Generator

    無法學(xué)習(xí)。
  4. 該過程一直持續(xù)到Discriminator無法再將生成數(shù)據(jù)與實(shí)際數(shù)據(jù)區(qū)分開來。

當(dāng)組合在一起時(shí),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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

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

3.2、Metropolis-Hastings GAN和Wasserstein GAN

I. Metropolis-Hastings GAN

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

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

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

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

圖10:MHGAN的視覺表示

II。Wasserstein GAN

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

最值得注意的要點(diǎn)是:

  • 我們知道GAN背后的主要目標(biāo)是讓Generator開始將隨機(jī)噪聲轉(zhuǎn)換為我們想要模仿的某些給定數(shù)據(jù)。因此,在GAN中,比較兩個(gè)分布之間的相似性的想法是非常必要的。這兩個(gè)最廣泛使用的指標(biāo)是:
  • KL散度(Kullback-Leibler) - DKL(p‖q)=∫xp(x)logp(x)q(x)dx。當(dāng)p(x)等于q(x)時(shí),DKL為零,
  • JS Divergence(Jensen-Shannon)。JS散度以0和1為界,與KL散度不同,它是對稱的,更平滑。當(dāng)損失從KL轉(zhuǎn)移到JS散度時(shí),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度量提供了一個(gè)平滑的度量(沒有突然的跳躍)。這使得它更適合在梯度下降期間創(chuàng)建穩(wěn)定的學(xué)習(xí)過程。
  • 此外,與KL和JS相比,Wasserstein距離幾乎無處不在。眾所周知,在反向傳播過程中,我們會(huì)區(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í)間序列數(shù)據(jù),因?yàn)樗鼈兏櫵邢惹暗臄?shù)據(jù)點(diǎn),并且可以捕獲隨時(shí)間發(fā)展的模式。由于它們的性質(zhì),RNN很多時(shí)候都會(huì)受到梯度消失的影響 - 也就是說,在訓(xùn)練期間權(quán)重變化的變化變得如此之小,以至于它們不會(huì)改變,使得網(wǎng)絡(luò)無法收斂到最小的損失(相反的問題也可以有時(shí)會(huì)觀察到 - 當(dāng)梯度變得太大時(shí)。這稱為梯度爆炸,但解決方法很簡單。兩個(gè)方法解決了這個(gè)問題 - 門控循環(huán)單元(GRU)和長短期記憶(LSTM)。兩者之間最大的區(qū)別是:1)GRU有2個(gè)門(update 和reset),LSTM有4個(gè)(update, input, forget, 和output),2)LSTM保持內(nèi)部存儲(chǔ)器狀態(tài),而GRU沒有, 3)LSTM在輸出門之前應(yīng)用非線性(sigmoid),GRU不應(yīng)用。

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

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

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

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

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

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

3.4.2LSTM架構(gòu)

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

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

gan_num_features = dataset_total_df.shape[1]sequence_length = 17class 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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

print(lstm_model)

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

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

LSTM背后的邏輯是:我們?nèi)?7天(sequence_length)的數(shù)據(jù)(同樣,這些數(shù)據(jù)是GS股票每天的股價(jià)+當(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ò)時(shí),為幾乎所有優(yōu)化器(例如SGD,Adam或RMSProp)設(shè)置學(xué)習(xí)速率至關(guān)重要,因?yàn)樗饶芸刂剖諗克俣龋帜芸刂凭W(wǎng)絡(luò)的最終性能。最簡單的學(xué)習(xí)率策略之一是在整個(gè)訓(xùn)練過程中具有固定的學(xué)習(xí)率。選擇較小的學(xué)習(xí)速率可以使優(yōu)化器找到好的解決方案,但這是以限制初始收斂速度為代價(jià)的。隨著時(shí)間的推移改變學(xué)習(xí)率可以克服這種權(quán)衡。

讓我們繪制我們將在每個(gè)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_cycleclass 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_idxschedule = CyclicalSchedule(TriangularSchedule, min_lr=0.5, max_lr=2, cycle_length=500)iterations=1500plt.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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

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

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

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

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

  • 確保數(shù)據(jù)質(zhì)量。我們已經(jīng)進(jìn)行了統(tǒng)計(jì)檢查,確保數(shù)據(jù)不受多重共線性或序列自相關(guān)的影響。進(jìn)一步,我們對每個(gè)特征執(zhí)行了特征重要性檢查。最后,利用一些有關(guān)股票市場運(yù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)同時(shí)進(jìn)行變量選擇和參數(shù)收縮,而Ridge歸僅進(jìn)行參數(shù)收縮并最終包括模型中的所有系數(shù)。在存在相關(guān)變量的情況下,嶺回歸可能是首選。此外,嶺回歸在最小二乘估計(jì)具有較高方差的情況下效果最佳。因此,這取決于我們的模型目標(biāo)。兩種類型的正則化的影響是完全不同的。雖然它們都會(huì)對大權(quán)重進(jìn)行懲罰,但L1正則化會(huì)導(dǎo)致零不可微函數(shù)。L2正則化有利于較小的權(quán)重,但L1正則化有利于權(quán)重變?yōu)榱?。所以,使用L1正則化,您可以得到一個(gè)稀疏模型 - 一個(gè)參數(shù)較少的模型。在這兩種情況下,L1和L2正則化模型的參數(shù)“收縮”,但在L1正則化的情況下,收縮直接影響模型的復(fù)雜性(參數(shù)的數(shù)量)。
  • Dropout。Dropout層隨機(jī)刪除隱藏圖層中的節(jié)點(diǎn)。
  • ense-sparse-dense training

  • Early stopping

    .

構(gòu)建復(fù)雜神經(jīng)網(wǎng)絡(luò)時(shí)的另一個(gè)重要考慮因素是偏差 - 方差權(quán)衡。基本上,我們在訓(xùn)練網(wǎng)絡(luò)時(shí)得到的誤差是偏差,方差和不可減少誤差的函數(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)的工作(分類,上下文提取等)。例如,在狗的圖像中,第一個(gè)卷積層將檢測邊緣,第二個(gè)將開始檢測圓圈,第三個(gè)將檢測到鼻子。在我們的例子中,數(shù)據(jù)點(diǎn)形成小趨勢,小趨勢形成更大,趨勢形成模式。CNN檢測特征的能力可用于提取有關(guān)GS股票價(jià)格變動(dòng)模式的信息。

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

3.5.1。CNN架構(gòu)

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

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

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

num_fc = 512# ... other parts of the GANcnn_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ù)測股票價(jià)格變動(dòng)(長文,建議收藏)

讓我們打印CNN。

print(cnn_net)

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

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個(gè)epochs。

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

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

如果RL決定它將更新超參數(shù),它將調(diào)用貝葉斯優(yōu)化(下面討論)庫,它將提供下一個(gè)最佳預(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é)果可能僅在一段時(shí)間內(nèi)有效。意思是,我們需要不斷優(yōu)化整個(gè)過程。為了優(yōu)化流程,我們可以:

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

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

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

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

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

Reward=2?lossG+lossD+accuracyG,

其中l(wèi)ossG,accuracyG和lossD分別是Generator的損失和準(zhǔn)確性,以及Discriminator的損失。環(huán)境是GAN和LSTM訓(xùn)練的結(jié)果。不同代理可以采取的動(dòng)作是如何更改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)、動(dòng)作、獎(jiǎng)勵(lì))來訓(xùn)練網(wǎng)絡(luò)。例如,這些層不僅可以是全連接層,而且可以是卷積層。
  • Double Q

    學(xué)習(xí)。

    Double Q

    L處理Q學(xué)習(xí)中的一個(gè)大問題,即高估偏差。
  • Prioritized replay。在vanilla DQN中,所有轉(zhuǎn)換都存儲(chǔ)在replay 緩沖區(qū)中,并均勻地對此緩沖區(qū)進(jìn)行采樣。然而,并非所有transitions在學(xué)習(xí)階段都同樣有益(這也使得學(xué)習(xí)效率低,因?yàn)樾枰嗟膃pisodes )。Prioritized experience replay 不是均勻采樣,而是使用分布,該分布為先前迭代中具有較高Q損失的樣本提供更高的概率。
  • Dueling networks

    。

    Dueling networks

    通過使用兩個(gè)單獨(dú)的流(即具有兩個(gè)不同的微型神經(jīng)網(wǎng)絡(luò))來稍微改變Q學(xué)習(xí)架構(gòu)。一個(gè)流用于值,一個(gè)用于優(yōu)勢。它們都共享一個(gè)卷積編碼器。棘手的部分是流的合并 - 它使用了一個(gè)特殊的聚合器(Wang et al.2016)。
  • Multi-step learning

    。

    Multi-step learning

    背后的巨大差異在于它使用N步返回計(jì)算Q值(不僅是下一步的返回),這自然應(yīng)該更準(zhǔn)確。
  • 分布式RL。Q學(xué)習(xí)使用平均估計(jì)的Q值作為目標(biāo)值。但是,在許多情況下,Q值在不同情況下可能不同。分布式RL可以直接學(xué)習(xí)(或近似)Q值的分布,而不是對它們求平均值。再次,數(shù)學(xué)比這復(fù)雜得多,但對我們來說,好處是Q值的更準(zhǔn)確的采樣。
  • Noisy Nets

    ?;綝QN實(shí)現(xiàn)了一個(gè)簡單的ε-貪婪機(jī)制來進(jìn)行探索。這種探索方法有時(shí)效率低下。Noisy Nets解決這個(gè)問題的方法是添加一個(gè)有噪聲的線性層。隨著時(shí)間的推移,網(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í)。實(shí)現(xiàn)其他算法要簡單得多,效果非常好。

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

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

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

注意:出于練習(xí)的目的,我們不會(huì)過多地研究和優(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ǎng)勵(lì)結(jié)果,但平均快15倍。
  • 選擇獎(jiǎng)勵(lì)函數(shù)非常重要。
  • 使用好奇心作為探索政策。
  • 根據(jù)伯克利的AI研究團(tuán)隊(duì)(BAIR)提出的建立多代理體系結(jié)構(gòu) - 鏈接(https://bair./blog/2018/12/12/rllib/)。

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

我們將使用貝葉斯優(yōu)化來代替網(wǎng)格搜索,這可能需要花費(fèi)大量時(shí)間來找到超參數(shù)的最佳組合。我們將使用的庫已經(jīng)實(shí)現(xiàn) - 鏈接(https://github.com/fmfn/BayesianOptimization)。

4.2.1、高斯過程

# Initialize the optimizerfrom bayes_opt import BayesianOptimizationfrom bayes_opt import UtilityFunctionutility = UtilityFunction(kind='ucb', kappa=2.5, xi=0.0)

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

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

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

5.結(jié)果

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

  1. 在第一個(gè)epoch之后繪制圖像。
from utils import plot_predictionplot_prediction('Predicted and Real price - after first epoch.')

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

2.繪制50個(gè)epochs后的圖像。

plot_prediction('Predicted and Real price - after first 50 epochs.')

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

plot_prediction('Predicted and Real price - after first 200 epochs.')

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

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

plot_prediction('Final result.')

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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多