本文搭建一个简单的CNN网络去做股票趋势预测。
另一篇文章(CSDN)用LSTM也做了股票预测可对比参考
最经典卷积神经网络有三层:
卷积的计算:
红框框里与蓝色矩阵filter做矩阵乘法,即:
(2*1+5*0+5*1)+(2*2+3*1+4*3)+(4*1+3*1+1*2)= 35
之后红色框框往后移一列,继续上述计算
卷积神经计算完成得到的数据
与深度神经网络的区别 CNN不是全连接 Filter中的每个数据是学出来的
用在提取图片特征上
Pooling Layer池化层
max pooling顾名思义去最大的那一个 对应的有平均池化average pooling 即取平均值
全连接
非全连接
计算出loss 使用反向传播法 往回传 在使用梯度下降法 减小误差
本次股价的预测三层:卷积层——池化层——全连接神经网络
用20天的股价预测第21天的股价 用mse计算和真实数据的误差
(1)数据集准备
在finance.yaoo.com 这个网站下载用到的数据集
这次预测股价用到的是苹果的股价预测 直接输入AAPL搜索
下载完成是一个csv文件,我们这里用5年的股价 每天的收盘价来预测
看一下我们的数据
(2)代码实现
使用pandas读取数据,df.head()打印前五行数据
df = pd.read_csv('AAPL.csv')
df.head()
我们用调整后的收盘价 Adj Close来预测股价,首先取出数据保存到x0中,用values属性把它转成numpy形式,len(x0)看下x0有多少个数据
x0 = df['Adj Close'].values
x0.shape
len(x0)
接下来对数据做预处理,我们希望每个数据都介于0-1之间,方便我们做预测
首先我们去除x0中最大的数据,之后所有的数据都与最大数据做除法
x0[:10] 输出看下x0中的数据
m = max(x0)
x0 = x0/m
x0[:10]
x是训练数据的一部分 从k到k+p,k是从总数量中减去p再加1取
n = len(x0)
p = 20
x = np.array([x0[k:k+p] for k in range(n-p+1)])
x.shape
1240笔数据 每个数据都包含20个数据
y = np.array(x0[p:])
y.shape
y.shape()看到y有1239个数据,会发现比x少一个数据,因为前20个数据才预测出一个y
因为keras读入的数据有三个维度,这里我们给x加上一个新的维度,方便keras读取数据
X.shape()可以看到X变成了三维的数据
X = x[:-1]
X = X[:, :, np.newaxis]
X.shape
test_size = 0.2 表示 20%的数据做训练,80%的数据做预测
shuffle=True,让数据重新洗过(当shuffle设置为False时,可以发现预测效果差很多)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=True)
接下来进行模型搭建,主要用到的是keras中的Sequential来搭建
下面是搭建模型用到的一些包,这里用到一维的卷积,一维的最大池化,优化器我这里导入了两个,可以分别尝试下看看预测效果
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Reshape, Dropout, Activation
from tensorflow.keras.layers import Conv1D, MaxPooling1D
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.optimizers import Adam
模型搭建的较为简单,只有三层。一维的卷积层、最大池化层、摊平数据之后连接了一个全连接网络。激活函数这里用到的是sigmoid。(softmax通常用在分类问题上,我们今天的数据类似于回归问题,所以这里使用sigmoid)
model.sumary() 看下model的详细信息
#模型搭建
model = Sequential()
#50个filter卷积核 学习到更多的特征,same保证维度不变
model.add(Conv1D(50,4,padding='same',activation='relu',input_shape=(p,1)))
model.add(MaxPooling1D(2))#每两个取一个大的 数据会减少一半
model.add(Flatten())#把二维数据变成一维的
model.add(Dense(20))#20个神经元的全连接层
model.add(Dropout(0.2))#防止过拟合 20%权重冻结
model.add(Activation('relu'))
model.add(Dense(1))#输出层 是一个一维的全连接神经网络
model.add(Activation('sigmoid'))
#model.compile(loss='mse',optimizer=SGD(lr=0.2), metrics['accuracy'])
model.compile(loss='mse', optimizer=SGD(lr=0.2))
model.summary()
下面开始训练模型,用到model.fit()这个函数
model.fit(X_train,y_train,epochs=50,batch_size=32)
下面进行绘图数据可视化
y_predict = model.predict(X_test)
plt.plot(y_test[:100])#取前一百个 真实数据
plt.plot(y_predict[:100],'r') #模型学到的
其实可以看到预测效果还是比较好的。
大家可以试下不同的优化器,激活函数,以及不同的epoch和batch_size......的预测结果
直接跑下代码程序体验会更直观。
LSTM、CNN、Hadoop
Transformer
%matplotlib inline
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Reshape, Dropout, Activation
from tensorflow.keras.layers import Conv1D, MaxPooling1D
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import train_test_split
df = pd.read_csv('AAPL.csv')
df.head()
#len(df) out:1259
x0 = df['Adj Close'].values
#plt.plot(x0[:100])
x0.shape
#len(x0)
#取出x0中最大的数据 让所有的x0与这个最大的值做除法 得到的都是小于1的数据 便于训练神经网络
m = max(x0)
x0 = x0/m
x0[:10]
n = len(x0)
#用20天的数据去预测下一天的数据
p = 20
x = np.array([x0[k:k+p] for k in range(n-p+1)])
#1240笔数据 每个数据都包含20个数据
x.shape
y = np.array(x0[p:])
y.shape
X = x[:-1]
X.shape
X = X[:, :, np.newaxis]
X.shape
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=True)
X_train.shape
#模型搭建
model = Sequential()
model.add(Conv1D(50,4,padding='same',activation='relu',input_shape=(p,1)))#50个filter卷积核 大小4
model.add(MaxPooling1D(2))#每两个取一个大的 数据会减少一半
model.add(Flatten())#把二维数据变成一维的
model.add(Dense(20))#20个神经元的全连接层
model.add(Dropout(0.2))#防止过拟合 20%权重冻结
model.add(Activation('relu'))
model.add(Dense(1))#输出层 是一个一维的全连接神经网络
model.add(Activation('sigmoid'))
#model.compile(loss='mse',optimizer=SGD(lr=0.2), metrics['accuracy'])
model.compile(loss='mse', optimizer=SGD(lr=0.2))
model.summary()
#模型训练
model.fit(X_train,y_train,epochs=50,batch_size=32)
#数据可视化
y_predict = model.predict(X_test)
#plt.plot(y_test)
#plt.plot(y_predict,'r')
plt.plot(y_test[:100])#取前一百个数据绘图 真实数据
plt.plot(y_predict[:100],'r') #模型学到的