本文介紹了如何運(yùn)用深度學(xué)習(xí)法預(yù)測(cè)股票市場(chǎng)。 簡(jiǎn)介 預(yù)測(cè)股市將如何變化歷來是最困難的事情之一。這個(gè)預(yù)測(cè)行為中包含著如此之多的因素—包括物理或心理因素、理性或者不理性行為因素等等。所有這些因素結(jié)合在一起,使得股價(jià)波動(dòng)劇烈,很難準(zhǔn)確預(yù)測(cè)。 使用機(jī)器學(xué)習(xí)可能改變游戲規(guī)則嗎?機(jī)器學(xué)習(xí)技術(shù)使用最新的組織公告、季度收益等作為特征,有潛力挖掘出我們以前沒有見過的模式和見解,并可用于準(zhǔn)確無誤的預(yù)測(cè)。 在本文中,我們將研究上市公司股價(jià)的歷史數(shù)據(jù)。我們將結(jié)合機(jī)器學(xué)習(xí)算法來預(yù)測(cè)這家公司的未來股價(jià),從平均和線性回歸這樣的簡(jiǎn)單算法開始,然后轉(zhuǎn)向像Auto ARIMA和LSTM這樣的高級(jí)模型。 本文背后的核心思想是展示這些算法是如何實(shí)現(xiàn)的,因此我只會(huì)簡(jiǎn)單描述該技術(shù)并提供相關(guān)參考鏈接,以便在必要時(shí)對(duì)這些概念進(jìn)行復(fù)習(xí)。如果您是時(shí)間序列領(lǐng)域的新手,我建議您先閱讀以下文章: 創(chuàng)建時(shí)間序列預(yù)測(cè)的初學(xué)者綜合指南 時(shí)間序列建模的完整教程 目錄 1、 問題理解 2、 移動(dòng)平均 3、 線性回歸 4、 K-近鄰 5、 自動(dòng)ARIMA 6、 先知(Prophet) 7、 長(zhǎng)短時(shí)記憶網(wǎng)絡(luò)(LSTM) 1、問題理解 我們將很快深入本文的實(shí)現(xiàn)部分,但首先重要的是確定我們要解決的問題。一般來說,股票市場(chǎng)分析分為兩個(gè)部分——基本面分析和技術(shù)分析。 基本面分析是根據(jù)公司目前的經(jīng)營(yíng)環(huán)境和財(cái)務(wù)狀況,對(duì)公司未來的盈利能力進(jìn)行分析。 技術(shù)分析包括閱讀圖表和使用統(tǒng)計(jì)數(shù)字來確定股票市場(chǎng)的趨勢(shì)。 您可能已經(jīng)猜到,我們的重點(diǎn)將放在技術(shù)分析部分。我們將使用來自Quandl的數(shù)據(jù)集(您可以在這里找到各種股票的歷史數(shù)據(jù)),這個(gè)項(xiàng)目中,我使用了“塔塔全球飲料”的數(shù)據(jù)。是時(shí)候開始了! 首先讓我們加載數(shù)據(jù)集,定義問題的目標(biāo)變量: #import packages import pandas as pd import numpy as np #to plot within notebook import matplotlib.pyplot as plt %matplotlib inline #setting figure size from matplotlib.pylab import rcParams rcParams['figure.figsize'] = 20,10 #for normalizing data from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1)) #read the file df = pd.read_csv('NSE-TATAGLOBAL(1).csv') #print the head df.head() 數(shù)據(jù)集中有多個(gè)變量——日期(date)、開盤價(jià)(open)、最高價(jià)(high)、最低價(jià)(low)、最后交易價(jià)(last)、收盤價(jià)(close)、總交易額(total_trade_quantity)和營(yíng)業(yè)額(turnover)。 開盤價(jià)和收盤價(jià)代表股票在某一天交易的起始價(jià)和最終價(jià)。 最高價(jià)、最低價(jià)和最后交易價(jià)表示當(dāng)天股票的最高價(jià)、最低價(jià)和最后交易價(jià)格。 交易總量是指當(dāng)天買賣的股票數(shù)量,而營(yíng)業(yè)額(Lacs)是指某一特定公司在某一特定日期的營(yíng)業(yè)額。 要注意的另一點(diǎn)是,市場(chǎng)在周末和公共假期休市。注意上表缺失了一些日期值——2/10/2018、6/10/2018、7/10/2018。其中2號(hào)是國(guó)慶節(jié),6號(hào)和7號(hào)是周末。 損益的計(jì)算通常由股票當(dāng)日的收盤價(jià)決定,因此我們將收盤價(jià)作為目標(biāo)變量。讓我們畫出目標(biāo)變量來理解它在我們的數(shù)據(jù)集中的分布: #setting index as date df['Date'] = pd.to_datetime(df.Date,format='%Y-%m-%d') df.index = df['Date'] #plot plt.figure(figsize=(16,8)) plt.plot(df['Close'], label='Close Price history') 在接下來的部分中,我們將探索這些變量,并使用不同的技術(shù)來預(yù)測(cè)股票的每日收盤價(jià)。 2、移動(dòng)平均 簡(jiǎn)介 “平均數(shù)”是我們?nèi)粘I钪凶畛S玫慕y(tǒng)計(jì)量之一。例如,計(jì)算平均分?jǐn)?shù)來確定整體表現(xiàn),或者根據(jù)過去幾天的平均溫度來了解今天的溫度——這些都是我們經(jīng)常做的日常工作。因此,使用這個(gè)方法開始用數(shù)據(jù)集進(jìn)行預(yù)測(cè)是個(gè)不錯(cuò)的選擇。 我們利用一組先前觀測(cè)值的平均值作為每天的預(yù)期收盤價(jià)。我們將使用移動(dòng)平均法,而不是使用簡(jiǎn)單的平均值,移動(dòng)平均法使用最近的一組數(shù)據(jù)計(jì)算預(yù)測(cè)值。換句話說,對(duì)于后續(xù)的每個(gè)新的時(shí)間,在考慮預(yù)測(cè)值時(shí),將從集合中刪除最早的觀測(cè)值,并加入上一個(gè)觀測(cè)值。下面是一個(gè)簡(jiǎn)單的圖,它將幫助您更清楚地理解這一點(diǎn)。 我們將在數(shù)據(jù)集上使用這種技術(shù)。第一步是創(chuàng)建一個(gè)只包含日期和收盤價(jià)列的數(shù)據(jù)框,然后將其拆分為訓(xùn)練集和驗(yàn)證集來驗(yàn)證我們的預(yù)測(cè)。 實(shí)現(xiàn) #creating dataframe with date and the target variable data = df.sort_index(ascending=True, axis=0) new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Close']) for i in range(0,len(data)): new_data['Date'][i] = data['Date'][i] new_data['Close'][i] = data['Close'][i] 在將數(shù)據(jù)分割為訓(xùn)練和驗(yàn)證時(shí),我們不能使用隨機(jī)分割,因?yàn)檫@會(huì)破壞時(shí)間順序。所以這里我將去年的數(shù)據(jù)作為驗(yàn)證集,將之前4年的數(shù)據(jù)作為訓(xùn)練集。 #splitting into train and validation train = new_data[:987] valid = new_data[987:] new_data.shape, train.shape, valid.shape ((1235, 2), (987, 2), (248, 2)) train['Date'].min(), train['Date'].max(), valid['Date'].min(), valid['Date'].max() (Timestamp('2013-10-08 00:00:00'), Timestamp('2017-10-06 00:00:00'), Timestamp('2017-10-09 00:00:00'), Timestamp('2018-10-08 00:00:00')) 下一步是為驗(yàn)證集創(chuàng)建預(yù)測(cè)值,并使用真實(shí)值來檢查RMSE誤差。 #make predictions preds = [] for i in range(0,248): a = train['Close'][len(train)-248+i:].sum() + sum(preds) b = a/248 preds.append(b) 結(jié)果 #calculate rmse rms=np.sqrt(np.mean(np.power((np.array(valid['Close'])-preds),2))) rms 104.51415465984348 僅僅檢查RMSE并不能幫助我們?cè)u(píng)估模型預(yù)測(cè)效果的。讓我們通過做圖得到更直觀的理解。下面是預(yù)測(cè)值和實(shí)際值的曲線圖。 #plot valid['Predictions'] = 0 valid['Predictions'] = preds plt.plot(train['Close']) plt.plot(valid[['Close', 'Predictions']]) 推論 RMSE值接近105,但是結(jié)果不是很理想(從圖中可以看出)。預(yù)測(cè)值與訓(xùn)練集的觀測(cè)值的范圍相同(開始有上升趨勢(shì),然后緩慢下降)。 在下一節(jié)中,我們將使用兩種常用的機(jī)器學(xué)習(xí)技術(shù)——線性回歸和kNN,看看它們?cè)谖覀兊墓善笔袌?chǎng)數(shù)據(jù)上表現(xiàn)如何。 3、線性回歸 簡(jiǎn)介 在這些數(shù)據(jù)上可以實(shí)現(xiàn)的最基本的機(jī)器學(xué)習(xí)算法是線性回歸。線性回歸模型生成一個(gè)確定自變量和因變量之間關(guān)系的方程。 線性回歸方程可以寫成: 在這里x1, x2, ....xn代表自變量,系數(shù)θ1,θ2,....θn代表權(quán)重。你可以參考下面的文章來更詳細(xì)地學(xué)習(xí)線性回歸: 對(duì)于線性回歸和Lasso回歸的一個(gè)綜合的初學(xué)者指南. 我們的問題中,沒有太多的自變量,只有日期。讓我們使用時(shí)間(date)列提取特征,如- day, month, year, mon/fri等,然后擬合線性回歸模型。 實(shí)現(xiàn) 我們將首先按升序?qū)?shù)據(jù)集進(jìn)行排序,然后創(chuàng)建一個(gè)單獨(dú)的數(shù)據(jù)集,這樣創(chuàng)建的任何新特性都不會(huì)影響原始數(shù)據(jù)。 #setting index as date values df['Date'] = pd.to_datetime(df.Date,format='%Y-%m-%d') df.index = df['Date'] #sorting data = df.sort_index(ascending=True, axis=0) #creating a separate dataset new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Close']) for i in range(0,len(data)): new_data['Date'][i] = data['Date'][i] new_data['Close'][i] = data['Close'][i] #create features from fastai.structured import add_datepart add_datepart(new_data, 'Date') new_data.drop('Elapsed', axis=1, inplace=True) #elapsed will be the time stamp 這將創(chuàng)建以下特征: ‘Year’, ‘Month’, ‘Week’, ‘Day’, ‘Dayofweek’, ‘Dayofyear’, ‘Is_month_end’, ‘Is_month_start’, ‘Is_quarter_end’, ‘Is_quarter_start’, ‘Is_year_end’, and ‘Is_year_start’. 注意:我使用了來自fastai庫(kù)的add_datepart。如果您沒有安裝它,您可以簡(jiǎn)單地使用命令pip install fastai。您也可以使用python中的簡(jiǎn)單for循環(huán)來創(chuàng)建這些特性。我在下面展示了一個(gè)例子。 除此之外,我們還可以添加自己的一組特性,我們認(rèn)為這些特性與預(yù)測(cè)相關(guān)。例如,我的假設(shè)是,本周的頭幾天和最后幾天對(duì)股票收盤價(jià)的影響可能遠(yuǎn)遠(yuǎn)超過其他日子。因此,我創(chuàng)建了一個(gè)特性來識(shí)別給定的一天是星期一/星期五還是星期二/星期三/星期四。這可以用以下幾行代碼來完成: new_data['mon_fri'] = 0 for i in range(0,len(new_data)): if (new_data['Dayofweek'][i] == 0 or new_data['Dayofweek'][i] == 4): new_data['mon_fri'][i] = 1 else: new_data['mon_fri'][i] = 0 如果是星期日或星期五,列值將為1,否則為0。類似地,您可以創(chuàng)建多個(gè)特性。如果你對(duì)有助于預(yù)測(cè)股價(jià)的特征有一些想法,請(qǐng)?jiān)诹粞岳锓窒怼?/p> 現(xiàn)在我們將把數(shù)據(jù)分成訓(xùn)練集和驗(yàn)證集來檢查模型的性能。 #split into train and validation train = new_data[:987] valid = new_data[987:] x_train = train.drop('Close', axis=1) y_train = train['Close'] x_valid = valid.drop('Close', axis=1) y_valid = valid['Close'] #implement linear regression from sklearn.linear_model import LinearRegression model = LinearRegression() model.fit(x_train,y_train) 結(jié)果 #make predictions and find the rmse preds = model.predict(x_valid) rms=np.sqrt(np.mean(np.power((np.array(y_valid)-np.array(preds)),2))) rms 121.16291596523156 RMSE值高于之前的方法,這清楚地表明線性回歸的表現(xiàn)很差。讓我們看看這個(gè)圖,并理解為什么線性回歸預(yù)測(cè)效果不是很好: #plot valid['Predictions'] = 0 valid['Predictions'] = preds valid.index = new_data[987:].index train.index = new_data[:987].index plt.plot(train['Close']) plt.plot(valid[['Close', 'Predictions']]) 推論 線性回歸是一種簡(jiǎn)單的技術(shù),很容易解釋,但也有一些明顯的缺點(diǎn)。使用回歸算法的一個(gè)問題是,模型過度擬合了日期和月份。模型將考慮一個(gè)月前相同日期或一年前相同日期/月的值,而不是從預(yù)測(cè)的角度考慮以前的值。 從上圖可以看出,2016年1月和2017年1月,股價(jià)出現(xiàn)下跌。該模型預(yù)測(cè)2018年1月也將如此。線性回歸技術(shù)可以很好地解決像大賣場(chǎng)銷售這樣的問題,在這些問題中,獨(dú)立的特征對(duì)于確定目標(biāo)值是有用的。 4、k-近鄰 簡(jiǎn)介 另一個(gè)有趣的ML算法是kNN (k近鄰)。基于自變量,kNN可以發(fā)現(xiàn)新數(shù)據(jù)點(diǎn)與舊數(shù)據(jù)點(diǎn)之間的相似性。讓我用一個(gè)簡(jiǎn)單的例子來解釋這個(gè)問題。 考慮11個(gè)人的身高和年齡。根據(jù)給定的特征(“年齡”和“身高”),下表可以用圖形形式表示,如下圖所示: 為了確定ID #11的權(quán)重,kNN考慮該ID的最近鄰居的權(quán)重。ID #11的權(quán)重被預(yù)測(cè)為其鄰居的平均值。如果我們現(xiàn)在考慮三個(gè)鄰居(k=3), ID#11的重量將是= (77+72+60)/3 = 69.66 kg。 對(duì)于kNN的詳細(xì)了解,可以參考以下文章: k近鄰介紹:簡(jiǎn)介 對(duì)k近鄰回歸算法的實(shí)際介紹 實(shí)現(xiàn) #importing libraries from sklearn import neighbors from sklearn.model_selection import GridSearchCV from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1)) 使用上一節(jié)中相同的訓(xùn)練和驗(yàn)證集: #scaling data x_train_scaled = scaler.fit_transform(x_train) x_train = pd.DataFrame(x_train_scaled) x_valid_scaled = scaler.fit_transform(x_valid) x_valid = pd.DataFrame(x_valid_scaled) #using gridsearch to find the best parameter params = {'n_neighbors':[2,3,4,5,6,7,8,9]} knn = neighbors.KNeighborsRegressor() model = GridSearchCV(knn, params, cv=5) #fit the model and make predictions model.fit(x_train,y_train) preds = model.predict(x_valid) 結(jié)果 #rmse rms=np.sqrt(np.mean(np.power((np.array(y_valid)-np.array(preds)),2))) rms 115.17086550026721 RMSE值并沒有太大的差異,但是一個(gè)預(yù)測(cè)值和實(shí)際值的曲線圖應(yīng)該提供一個(gè)更清晰的理解。 #plot valid['Predictions'] = 0 valid['Predictions'] = preds plt.plot(valid[['Close', 'Predictions']]) plt.plot(train['Close']) 推論 RMSE值與線性回歸模型近似,圖中呈現(xiàn)出相同的模式。與線性回歸一樣,kNN也發(fā)現(xiàn)了2018年1月的下降,因?yàn)檫@是過去幾年的模式。我們可以有把握地說,回歸算法在這個(gè)數(shù)據(jù)集上表現(xiàn)得并不好。 讓我們來看一些時(shí)間序列預(yù)測(cè)技術(shù),看看它們?cè)诿鎸?duì)股價(jià)預(yù)測(cè)挑戰(zhàn)時(shí)的表現(xiàn)。 5、自動(dòng)ARIMA 簡(jiǎn)介 ARIMA是一種非常流行的時(shí)間序列預(yù)測(cè)統(tǒng)計(jì)方法。ARIMA模型使用過去的值來預(yù)測(cè)未來的值。ARIMA中有三個(gè)重要參數(shù): p(用來預(yù)測(cè)下一個(gè)值的過去值) q(用來預(yù)測(cè)未來值的過去預(yù)測(cè)誤差) d(差分的順序) ARIMA的參數(shù)優(yōu)化需要大量時(shí)間。因此我們將使用自動(dòng) ARIMA,自動(dòng)選擇誤差最小的(p,q,d)最佳組合。要了解更多關(guān)于自動(dòng)ARIMA的工作原理,請(qǐng)參閱本文: 利用自動(dòng)ARIMA建立高性能時(shí)間序列模型 實(shí)現(xiàn) from pyramid.arima import auto_arima data = df.sort_index(ascending=True, axis=0) train = data[:987] valid = data[987:] training = train['Close'] validation = valid['Close'] model = auto_arima(training, start_p=1, start_q=1,max_p=3, max_q=3, m=12,start_P=0, seasonal=True,d=1, D=1, trace=True,error_action='ignore',suppress_warnings=True) model.fit(training) forecast = model.predict(n_periods=248) forecast = pd.DataFrame(forecast,index = valid.index,columns=['Prediction']) 結(jié)果 rms=np.sqrt(np.mean(np.power((np.array(valid['Close'])-np.array(forecast['Prediction'])),2))) rms 44.954584993246954 #plot plt.plot(train['Close']) plt.plot(valid['Close']) plt.plot(forecast['Prediction']) 推論 正如我們前面看到的,自動(dòng)ARIMA模型使用過去的數(shù)據(jù)來理解時(shí)間序列中的模式。利用這些值,該模型捕捉到該系列中的增長(zhǎng)趨勢(shì)。雖然使用這種技術(shù)的預(yù)測(cè)比以前實(shí)現(xiàn)的機(jī)器學(xué)習(xí)模型的預(yù)測(cè)要好得多,但是這些預(yù)測(cè)仍然與實(shí)際值相距甚遠(yuǎn)。 從圖中可以明顯看出,該模型在序列中捕捉到了一種趨勢(shì),但忽略了季節(jié)的影響。在下一節(jié)中,我們將使用一個(gè)同時(shí)考慮了序列的趨勢(shì)和季節(jié)性的時(shí)間序列模型。該模型。 6、先知(Prophet) 簡(jiǎn)介 有許多時(shí)間序列技術(shù)可以用在股票預(yù)測(cè)數(shù)據(jù)集上,但是大多數(shù)技術(shù)在擬合模型之前需要大量的數(shù)據(jù)預(yù)處理。Prophet(先知)由Facebook設(shè)計(jì)和開發(fā),是一個(gè)時(shí)間序列預(yù)測(cè)庫(kù),不需要數(shù)據(jù)預(yù)處理,并且非常容易實(shí)現(xiàn)。先知的輸入是一個(gè)帶有兩列的數(shù)據(jù)框:日期和目標(biāo)(ds和y)。 先知試圖在過去的數(shù)據(jù)中捕捉季節(jié)性,并且在數(shù)據(jù)集很大的時(shí)候依然表現(xiàn)良好。這里有一篇有趣的文章,用一個(gè)簡(jiǎn)單和直觀的方式解釋了先知算法: 使用Facebook的Prophet生成快速準(zhǔn)確的時(shí)間序列預(yù)測(cè) 實(shí)現(xiàn) #importing prophet from fbprophet import Prophet #creating dataframe new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Close']) for i in range(0,len(data)): new_data['Date'][i] = data['Date'][i] new_data['Close'][i] = data['Close'][i] new_data['Date'] = pd.to_datetime(new_data.Date,format='%Y-%m-%d') new_data.index = new_data['Date'] #preparing data new_data.rename(columns={'Close': 'y', 'Date': 'ds'}, inplace=True) #train and validation train = new_data[:987] valid = new_data[987:] #fit the model model = Prophet() model.fit(train) #predictions close_prices = model.make_future_dataframe(periods=len(valid)) forecast = model.predict(close_prices) 結(jié)果 #rmse forecast_valid = forecast['yhat'][987:] rms=np.sqrt(np.mean(np.power((np.array(valid['y'])-np.array(forecast_valid)),2))) rms 57.494461930575149 #plot valid['Predictions'] = 0 valid['Predictions'] = forecast_valid.values plt.plot(train['y']) plt.plot(valid[['y', 'Predictions']]) 推論 先知(像大多數(shù)時(shí)間序列預(yù)測(cè)技術(shù)一樣)試圖從過去的數(shù)據(jù)中捕捉趨勢(shì)和季節(jié)性。該模型通常在時(shí)間序列數(shù)據(jù)集上表現(xiàn)良好,但在本例中沒有達(dá)到預(yù)期效果。 事實(shí)證明,股票價(jià)格沒有特定的趨勢(shì)或季節(jié)性。價(jià)格的漲跌很大程度上取決于目前市場(chǎng)上的情況。因此,像ARIMA、SARIMA和Prophet這樣的預(yù)測(cè)技術(shù)并不能很好地解決這個(gè)特殊的問題。 讓我們繼續(xù)嘗試另一種高級(jí)技術(shù)——長(zhǎng)短時(shí)記憶網(wǎng)絡(luò)(LSTM)。 7、長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM) 簡(jiǎn)介 LSTM 算法廣泛應(yīng)用于序列預(yù)測(cè)問題中,并被證明是一種非常有效的方法。它們之所表現(xiàn)如此出色,是因?yàn)長(zhǎng)STM能夠存儲(chǔ)重要的既往信息,并忽略不重要的信息。 LSTM有三個(gè)門: 輸入門:輸入門將信息添加到細(xì)胞狀態(tài) 遺忘門:它移除模型不再需要的信息 輸出門:LSTM的輸出門選擇作為輸出的信息 要更詳細(xì)地了解LSTM及其體系結(jié)構(gòu),可以閱讀下面的文章: 長(zhǎng)短期記憶網(wǎng)絡(luò)簡(jiǎn)介 現(xiàn)在,讓我們將LSTM實(shí)現(xiàn)為一個(gè)黑盒,并檢查它在特定數(shù)據(jù)上的性能。 實(shí)現(xiàn) #importing required libraries from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential from keras.layers import Dense, Dropout, LSTM #creating dataframe data = df.sort_index(ascending=True, axis=0) new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Close']) for i in range(0,len(data)): new_data['Date'][i] = data['Date'][i] new_data['Close'][i] = data['Close'][i] #setting index new_data.index = new_data.Date new_data.drop('Date', axis=1, inplace=True) #creating train and test sets dataset = new_data.values train = dataset[0:987,:] valid = dataset[987:,:] #converting dataset into x_train and y_train scaler = MinMaxScaler(feature_range=(0, 1)) scaled_data = scaler.fit_transform(dataset) x_train, y_train = [], [] for i in range(60,len(train)): x_train.append(scaled_data[i-60:i,0]) y_train.append(scaled_data[i,0]) x_train, y_train = np.array(x_train), np.array(y_train) x_train = np.reshape(x_train, (x_train.shape[0],x_train.shape[1],1)) # create and fit the LSTM network model = Sequential() model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape[1],1))) model.add(LSTM(units=50)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') model.fit(x_train, y_train, epochs=1, batch_size=1, verbose=2) #predicting 246 values, using past 60 from the train data inputs = new_data[len(new_data) - len(valid) - 60:].values inputs = inputs.reshape(-1,1) inputs = scaler.transform(inputs) X_test = [] for i in range(60,inputs.shape[0]): X_test.append(inputs[i-60:i,0]) X_test = np.array(X_test) X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[1],1)) closing_price = model.predict(X_test) closing_price = scaler.inverse_transform(closing_price) 結(jié)果 rms=np.sqrt(np.mean(np.power((valid-closing_price),2))) rms 11.772259608962642 #for plotting train = new_data[:987] valid = new_data[987:] valid['Predictions'] = closing_price plt.plot(train['Close']) plt.plot(valid[['Close','Predictions']]) 推論 哇!LSTM輕松地超越了我們目前看到的任何算法。LSTM模型可以對(duì)各種參數(shù)進(jìn)行調(diào)優(yōu),如改變LSTM層數(shù)、增加dropout值或增加訓(xùn)練迭代輪數(shù)(epoch)數(shù)。但LSTM的預(yù)測(cè)是否足以確定股票價(jià)格將上漲還是下跌?當(dāng)然不行! 正如我在文章開頭提到的,股價(jià)受到公司新聞和其他因素的影響,如公司的非貨幣化或合并/分拆。還有一些無形的因素往往是無法事先預(yù)測(cè)的。 寫在最后 我在寫這些文章時(shí)意識(shí)到時(shí)間序列預(yù)測(cè)是一個(gè)非常有趣的領(lǐng)域。在社區(qū)中有觀點(diǎn)認(rèn)為這是一個(gè)復(fù)雜的領(lǐng)域,雖然有一定道理,我還是想說一旦你掌握了基本的技巧,就不難理解它了。 我對(duì)LSTM如何處理其他時(shí)間序列的問題很感興趣,并鼓勵(lì)您自己也嘗試一下。如果你有任何問題,請(qǐng)?jiān)谙旅娴牧粞圆糠峙c我聯(lián)系。 原文鏈接:https://www./blog/2018/10/predicting-stock-price-machine-learningnd-deep-learning-techniques-python/ 譯者簡(jiǎn)介 趙雪堯,北郵研三在讀,京東見習(xí)算法工程師,目前研究強(qiáng)化學(xué)習(xí)廣告競(jìng)價(jià)模型。相信數(shù)據(jù)和算法將為企業(yè)發(fā)展賦能,希望跟志同道合的小伙伴一起追尋前沿消息,深入探索算法的極限。在玄學(xué)調(diào)參的道路上,一路狂奔。 翻譯組招募信息 工作內(nèi)容:需要一顆細(xì)致的心,將選取好的外文文章翻譯成流暢的中文。如果你是數(shù)據(jù)科學(xué)/統(tǒng)計(jì)學(xué)/計(jì)算機(jī)類的留學(xué)生,或在海外從事相關(guān)工作,或?qū)ψ约和庹Z水平有信心的朋友歡迎加入翻譯小組。 你能得到:定期的翻譯培訓(xùn)提高志愿者的翻譯水平,提高對(duì)于數(shù)據(jù)科學(xué)前沿的認(rèn)知,海外的朋友可以和國(guó)內(nèi)技術(shù)應(yīng)用發(fā)展保持聯(lián)系,THU數(shù)據(jù)派產(chǎn)學(xué)研的背景為志愿者帶來好的發(fā)展機(jī)遇。 |
|