Python中文社区(ID:python-china)LSTM神经网络长短期记忆(LSTM)神经网络是循环神经网络(RNN)的一种,特别适合处理与预测和时间序列相关的重要事件。拿下面这句话作为语境推测的例子:“我在法国长大,我能说一口流利的??”因为同一句话前面提到了国家“法国”,后面提到了动作“说”。因此,LSTM可以从“French”和“Say”这两个长短期记忆中的重要信号中推断出“French”更可能的结果。K线图与此类似,股价响应时间的流动和重要信号的出现:在价格稳定、放量缩量的盘整区间,放量突破的大红K突然出现,预示着股价可能即将上涨。跳空后出现岛形反转,预示着股价可能下跌。在连涨数日的走势中突然出现上下影线较长的十字线,预示着股价可能出现反转。LSTM要做的就是找出一段时间内K线是否有重要信号(比如带量的红K),学习预测未来的股价走势。LSTM股价预测实例数据为鸿海(2317)2013年初至2017年底的每日开盘价、收盘价、最高价、最低价、成交量。先将数据写入存储到pandas的DataFrame中,去掉可能有N/A的行:数据写入:importpandasaspdfoxconndf=pd.read_csv('./foxconn_2013-2017.csv',index_col=0)foxconndf.dropna(how='any',inplace=True)为了防止原始数据过大或过小没有统一范围,导致LSTM在训练时难以收敛,我们用最小值和最大值对数据进行修正零一正则化方法:fromsklearnimportpreprocessingdefnormalize(df):newdf=df.copy()min_max_scaler=preprocessing.MinMaxScaler()newdf['open']=min_max_scaler.fit_transform(df.open.values.reshape(-1,1))newdf['low']=min_max_scaler.fit_transform(df.low.values.reshape(-1,1))newdf['high']=min_max_scaler.fit_transform(df.high.values.reshape(-1,1))newdf['volume']=min_max_scaler.fit_transform(df.volume.values.reshape(-1,1))newdf['close']=min_max_scaler.fit_transform(df.close.values.reshape(-1,1))返回newdffoxconndf_norm=normalize(foxconndf)然后C把数据分成训练集和测试集,同时定义每条数据的时间范围:importnumpyasnpdefdata_helper(df,time_frame):#数据维度:开盘价,收盘价,最高价,最低价,成交数量,5维number_features=len(df.columns)#Convertdataframetonumpyarraydatavalue=df.as_matrix()result=[]#如果要观察time_frame20天需要再增加一天作为验证答案forindexinrange(len(datavalue)-(time_frame+1)):#从datavalue的第0个运行到倒数第二个time_frame+1result.append(datavalue[index:index+(time_frame+1)])#取time_frame+1Kstickvalue一个一个作为instanceresult=np.array(result)number_train=round(0.9*result.shape[0])#取result的前90%instanceasTrainingdatax_train=result[:int(number_train),:-1]#trainingdata中,只取每个time_frame中除最后一个以外的所有数据作为featurey_train=result[:int(number_train),-1][:,-1]#训练数据中取每个time_frame最后一个数据的最后一个值(收盘价)作为答案#测试数据x_test=result[int(number_train):,:-1]y_test=result[int(number_train):,-1][:,-1]#让数据看起来更好x_train=np.reshape(x_train,(x_train.shape[0],x_train.shape[1],number_features))x_test=np.reshape(x_test,(x_test.shape[0],x_test.shape[1],number_features))返回[x_train,y_train,x_test,y_test]#以20天为间隔进行股价预测X_train,y_train,X_test,y_test=data_helper(foxconndf_norm,20)我们使用Keras框架作为LSTM的模型选择。首先我们在前面加两层256个神经元的LSTM层,并加一个Dropout层防止数据过拟合(overfitting)最后加入两个神经元个数不同的全连接层,得到一个只有1维值的输出,即预测股票价格:input_dim):d=0.3model=Sequential()model.add(LSTM(256,input_shape=(input_length,input_dim),return_sequences=True))model.add(Dropout(d))model.add(LSTM(256,input_shape=(input_length,input_dim),return_sequences=False))model.add(Dropout(d))model.add(Dense(16,kernel_initializer="uniform",activation='relu'))model.add(Dense(1,kernel_initializer="uniform",activation='linear'))model.compile(loss='mse',optimizer='adam',metrics=['accuracy'])returnmodel#20天,5维模型=build_model(20,5)LSTM模型建立后,我们开始用之前编辑好的训练数据集训练模型:LSTM模型训练#Abatch有128个instance,一共50个iterationsarerunmodel.fit(X_train,y_train,batch_size=128,epochs=50,validation_split=0.1,verbose=1)经过一段时间的训练过程,我们可以得到LSTM模型(model)。然后用这个模型对测试数据进行预测,将预测值(pred)和实际股价(y_test)还原回原股价的大小范围:LSTM模型预测股价,还原值defdenormalize(df,norm_value):original_value=df['close'].values.reshape(-1,1)norm_valuenorm_value=norm_value.reshape(-1,1)min_max_scaler=preprocessing.MinMaxScaler()min_max_scaler.fit_transform(original_value)denorm_value=min_max_scaler。inverse_transform(norm_value)returndenorm_value#使用训练好的LSTM模型对测试数据集进行预测pred=model.predict(X_test)#将预测值和实际股价恢复到原来的区间值denorm_pred=denormalize(foxconndf,pred)denorm_ytest=denormalize(foxconndf,y_test)LSTM预测股价结果我们把还原值和实际股价画出来看看效果:LSTM预测股价结果importmatplotlib.pyplotasplt%matplotlibinlineplt.plot(denorm_pred,color='red',label='prediction')plt.plot(denorm_ytest,color='blue',label='Answer')plt.legend(loc='best')plt.show()如下图,蓝线为实际股价,红线是预测的股价。虽然看起来预测股价和实际股价总体走势相似,但细看预测股价却落后于实际股价几天。那么我们来调整一些设置:调整时间帧的长度Keras模型中全连接层的激活和优化器的调整Keras模型使用不同的神经网络(类型、阶数、数量)结合batch_size的调整,epochs的调整...我们对以上参数稍作调整后,就会得到一个更接近实际股价的预测结果。
