Tensorflow2(预课程)---11.3.2、(a)循环神经网络实现股票预测(GRU)
一、总结
一句话总结:
这个应用不看准确率(这里不是分类问题),看loss就好了,loss低的话,预测自然准
# 构建容器 model = tf.keras.Sequential() # 输入层 model.add(tf.keras.Input(shape=(60,1))) model.add(tf.keras.layers.GRU(80, return_sequences=True)) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.GRU(100)) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.Dense(1)) # 模型的结构 model.summary()
# 该应用只观测loss数值,不观测准确率 # 配置优化函数和损失器 model.compile(optimizer=tf.keras.optimizers.Adam(0.001),loss='mse',metrics=['acc']) # 开始训练 history = model.fit(x_train,y_train,epochs=50,validation_data=(x_test,y_test)) #epochs表示训练的次数
1、报错:ValueError: Failed to find data adapter that can handle input: <class 'numpy.ndarray'>, (<class 'list'> containing values of types {"<class 'numpy.float64'>"})?
很可能是没有将数据转为numpy:是没有将数据(y_train、y_test)转为numpy
2、异常二:训练集和测试集准确率都为0?
真正原因是 该应用只观测loss数值,不观测准确率
3、从归一化转换成正常数据?
MinMaxScaler的inverse_transform方法:predicted_stock_price = sc.inverse_transform(predicted_stock_price)
# 测试集输入模型进行预测 predicted_stock_price = model.predict(x_test) # 对预测数据还原---从(0,1)反归一化到原始范围 predicted_stock_price = sc.inverse_transform(predicted_stock_price) # 对真实数据还原---从(0,1)反归一化到原始范围 real_stock_price = sc.inverse_transform(test_set[60:]) # 画出真实数据和预测数据的对比曲线 plt.plot(real_stock_price, color='red', label='MaoTai Stock Price') plt.plot(predicted_stock_price, color='blue', label='Predicted MaoTai Stock Price') plt.title('MaoTai Stock Price Prediction') plt.xlabel('Time') plt.ylabel('MaoTai Stock Price') plt.legend() plt.show()
4、.iloc[0:2126,2:3].values和.iloc[0:2126,2:3]获取的数据格式分别是什么?
(I)、.iloc[0:2126,2:3].values 获取的是 numpy.ndarray
(II)、.iloc[0:2126,2:3] 获取的是 pandas.core.frame.DataFrame
二、循环神经网络实现股票预测(GRU)
博客对应课程的视频位置:
步骤
1、读取数据集
2、拆分数据集(拆分成训练数据集和测试数据集)
3、构建模型
4、训练模型
5、检验模型
需求
对
In [1]:
import pandas as pd import numpy as np import tensorflow as tf import matplotlib.pyplot as plt
1、读取数据集
In [2]:
data = pd.read_csv("SH600519.csv") print(data.head(5)) print(data.shape)
2、拆分数据集(拆分成训练数据集和测试数据集)
将后300行做测试集,之前的做训练集
In [3]:
# .iloc[0:2126,2:3].values 获取的是 numpy.ndarray
# .iloc[0:2126,2:3] 获取的是 pandas.core.frame.DataFrame train_data = data.iloc[0:2126,2:3].values train_data1 = data.iloc[0:2126,2:3] test_data = data.iloc[2126:,2:3].values print(type(train_data)) print(type(train_data1)) print(train_data.shape) print(test_data.shape) print(train_data[0:5]) print(test_data[0:5])
In [4]:
# 归一化
from sklearn.preprocessing import MinMaxScaler sc = MinMaxScaler(feature_range=(0, 1)) # 定义归一化:归一化到(0,1)之间 training_set = sc.fit_transform(train_data) # 求得训练集的最大值,最小值这些训练集固有的属性,并在训练集上进行归一化 test_set = sc.transform(test_data) # 利用训练集的属性对测试集进行归一化
In [5]:
# min-max归一化中的min和max
print(sc.data_max_) print(sc.data_min_) print(training_set.shape) print(test_set.shape) print(training_set[:5]) print(test_set[:5])
2.1、构建训练和测试数据集
In [6]:
x_train = [] y_train = [] x_test = [] y_test = []
In [7]:
print(type(training_set)) # 切片的索引 # 前面一个是行,后面一个是列 print(training_set[70-10:70,0]) print(training_set[70,0])
In [8]:
print(training_set[70-10:70]) print(training_set[70])
In [9]:
print(training_set[70-10:70,0]) print(training_set[70,0])
组装 train 数据
In [10]:
for i in range(60,len(training_set)): x_train.append(training_set[i-60:i,0]) y_train.append(training_set[i,0]) # 对训练集进行打乱 np.random.seed(7) np.random.shuffle(x_train) np.random.seed(7) np.random.shuffle(y_train) tf.random.set_seed(7)
In [11]:
print(len(x_train)) print(len(y_train)) print(x_train[:2]) print(y_train[:2])
组装 test 数据
In [12]:
for i in range(60,len(test_set)): x_test.append(test_set[i-60:i,0]) y_test.append(test_set[i,0])
In [13]:
print(len(x_test)) print(len(y_test)) print(x_test[:2]) print(y_test[:2])
如此便构建了训练数据和测试数据
In [14]:
print(type(x_train)) print(type(x_test))
In [15]:
print(x_train[0]) print(x_test[0])
In [16]:
x_train=np.array(x_train) x_test=np.array(x_test) y_train=np.array(y_train) y_test=np.array(y_test)
In [17]:
x_train = np.reshape(x_train, (x_train.shape[0], 60, 1)) x_test = np.reshape(x_test, (x_test.shape[0], 60, 1)) print(x_train.shape) print(x_test.shape)
3、构建模型
In [18]:
# 构建容器
model = tf.keras.Sequential() # 输入层 model.add(tf.keras.Input(shape=(60,1))) model.add(tf.keras.layers.GRU(80, return_sequences=True)) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.GRU(100)) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.Dense(1)) # 模型的结构 model.summary()
4、训练模型
In [19]:
# 该应用只观测loss数值,不观测准确率
# 配置优化函数和损失器 model.compile(optimizer=tf.keras.optimizers.Adam(0.001),loss='mse',metrics=['acc']) # 开始训练 history = model.fit(x_train,y_train,epochs=50,validation_data=(x_test,y_test)) #epochs表示训练的次数
问题一:
报错:
ValueError: Failed to find data adapter that can handle input:
<class 'numpy.ndarray'>,
(<class 'list'> containing values of types {"<class 'numpy.float64'>"})
问题原因:
很可能是没有将数据转为numpy。
In [ ]:
print(type(x_train)) print(type(y_train)) print(type(x_test)) print(type(y_test))
问题二:
训练集和测试集准确率都为0
解决方案:
来初步检验一下训练和测试数据
不是因为我没有打乱数据
真正原因是 该应用只观测loss数值,不观测准确率
In [ ]:
print(x_train.shape) print(y_train.shape) print(x_test.shape) print(y_test.shape)
In [19]:
print("===================x_train[0:2]===================") print(x_train[0:2]) print("===================y_train[0:2]===================") print(y_train[0:2]) print("===================x_test[0:2]===================") print(x_test[0:2]) print("===================y_test[0:2]===================") print(y_test[0:2])
5、检验模型
In [20]:
################## predict ######################
# 测试集输入模型进行预测 predicted_stock_price = model.predict(x_test) # 对预测数据还原---从(0,1)反归一化到原始范围 predicted_stock_price = sc.inverse_transform(predicted_stock_price) # 对真实数据还原---从(0,1)反归一化到原始范围 real_stock_price = sc.inverse_transform(test_set[60:]) # 画出真实数据和预测数据的对比曲线 plt.plot(real_stock_price, color='red', label='MaoTai Stock Price') plt.plot(predicted_stock_price, color='blue', label='Predicted MaoTai Stock Price') plt.title('MaoTai Stock Price Prediction') plt.xlabel('Time') plt.ylabel('MaoTai Stock Price') plt.legend() plt.show()
In [23]:
predicted_stock_price = model.predict(x_test) print(predicted_stock_price.shape) print(predicted_stock_price)
In [24]:
# 对预测数据还原---从(0,1)反归一化到原始范围
predicted_stock_price = sc.inverse_transform(predicted_stock_price) print(predicted_stock_price.shape) print(predicted_stock_price)
In [25]:
# 对真实数据还原---从(0,1)反归一化到原始范围
real_stock_price = sc.inverse_transform(test_set[60:]) print(real_stock_price.shape) print(real_stock_price)
In [ ]: