计算性能和绘制 LSTM 预测的问题
Problems calculating performance and plotting LSTM predictions
我在股票数据上安装了一个神经网络,如下所示。首先我下载了所需的数据并做了一些细微的改动以获得单变量数据集:
import numpy
import pandas as pd
import yfinance as yf
df=yf.download('^GSPC', period='20y', progress=False)
df=df.drop(df.columns[0:5], axis=1)
然后我将数据分成训练集和测试集:
df=df.astype(float)
train_size = int(len(df) * 0.8)
test_size = len(df) - train_size
df_train, df_test = df[0:train_size], df[train_size:len(df)]
并对两者进行归一化:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
df_train_scaled=scaler.fit_transform(df_train)
df_test_scaled=scaler.fit_transform(df_test)
现在,进入关键部分。首先,我使用了一个方便的函数来根据 keras 的要求重塑输入数据:
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import Dropout
from numpy import array
def data_preparation_univariate(sequence, n_steps):
X, y = list(), list()
for i in range(len(sequence)):
end_ix = i + n_steps
if end_ix > len(sequence)-1:
break
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
n_steps=10
X_train, y_train = data_preparation_univariate(df_train_scaled, n_steps)
X_test, y_test = data_preparation_univariate(df_test_scaled, n_steps)
features = 1
X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], features))
X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], features))
然后我定义了模型:
model = Sequential()
model.add(LSTM(50, activation='relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(50, activation='relu', return_sequences=False))
model.add(Dense(X_train.shape[1]))
model.compile(optimizer='adam', loss='mse')
然后我在训练数据上拟合模型
history=model.fit(X_train, y_train, epochs=100, batch_size=20, validation_split=0.2, verbose=2)
和测试数据:
predict_test=model.predict(X_test,verbose=2)
最后我缩减了预测值和实际值:
y_test = scaler.inverse_transform(y_test)
predict_test=scaler.inverse_transform(forecast_test)
然而,在这一点上,当我调用 predict_test.shape
时,我得到了一个长度为 (998, 10)
的二维数组,正如所需转换所期望的那样,当我调用 y_test.shape
时我得到一个长度为 (998,1)
的二维数组。当我尝试将预测的均方误差计算为:
from sklearn.metrics import mean_squared_error
mse=mean_squared_error(y_test,predict_test)
我收到错误 ValueError: y_true and y_pred have different number of output (1!=10)
,因为数组维度当然不同。此外,当我将两个系列相互绘制时:
plt.plot(y_test, label='Actual')
plt.plot(forecast_test, label='Predicted')
plt.legend()
plt.show()
图表清楚地显示有 10 个系列的预测值。因此我的问题是:如何将我的数据重塑回原始格式,以便我可以将这两个系列绘制成一个对比另一个,然后我可以计算一些准确度指标?
P.S。如果您在我的程序中发现错误,请随时指出。我对 LSTM 和 keras 还是新手,非常感谢任何帮助。
网络的输出层形状不正确 (10),但输出值应该只有 1。所以改变行
model.add(Dense(X_train.shape[1]))
进入
model.add(Dense(1))
解决问题。
P.S。查看输入数据,日期不是严格连续的:
2001-10-04 1.609100e+09
2001-10-05 1.301700e+09
2001-10-08 9.790000e+08
然而,你对待他们就好像他们是。我建议在这里用内插数字填充序列以做出更好的预测。
我在股票数据上安装了一个神经网络,如下所示。首先我下载了所需的数据并做了一些细微的改动以获得单变量数据集:
import numpy
import pandas as pd
import yfinance as yf
df=yf.download('^GSPC', period='20y', progress=False)
df=df.drop(df.columns[0:5], axis=1)
然后我将数据分成训练集和测试集:
df=df.astype(float)
train_size = int(len(df) * 0.8)
test_size = len(df) - train_size
df_train, df_test = df[0:train_size], df[train_size:len(df)]
并对两者进行归一化:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
df_train_scaled=scaler.fit_transform(df_train)
df_test_scaled=scaler.fit_transform(df_test)
现在,进入关键部分。首先,我使用了一个方便的函数来根据 keras 的要求重塑输入数据:
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import Dropout
from numpy import array
def data_preparation_univariate(sequence, n_steps):
X, y = list(), list()
for i in range(len(sequence)):
end_ix = i + n_steps
if end_ix > len(sequence)-1:
break
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
n_steps=10
X_train, y_train = data_preparation_univariate(df_train_scaled, n_steps)
X_test, y_test = data_preparation_univariate(df_test_scaled, n_steps)
features = 1
X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], features))
X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], features))
然后我定义了模型:
model = Sequential()
model.add(LSTM(50, activation='relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(50, activation='relu', return_sequences=False))
model.add(Dense(X_train.shape[1]))
model.compile(optimizer='adam', loss='mse')
然后我在训练数据上拟合模型
history=model.fit(X_train, y_train, epochs=100, batch_size=20, validation_split=0.2, verbose=2)
和测试数据:
predict_test=model.predict(X_test,verbose=2)
最后我缩减了预测值和实际值:
y_test = scaler.inverse_transform(y_test)
predict_test=scaler.inverse_transform(forecast_test)
然而,在这一点上,当我调用 predict_test.shape
时,我得到了一个长度为 (998, 10)
的二维数组,正如所需转换所期望的那样,当我调用 y_test.shape
时我得到一个长度为 (998,1)
的二维数组。当我尝试将预测的均方误差计算为:
from sklearn.metrics import mean_squared_error
mse=mean_squared_error(y_test,predict_test)
我收到错误 ValueError: y_true and y_pred have different number of output (1!=10)
,因为数组维度当然不同。此外,当我将两个系列相互绘制时:
plt.plot(y_test, label='Actual')
plt.plot(forecast_test, label='Predicted')
plt.legend()
plt.show()
图表清楚地显示有 10 个系列的预测值。因此我的问题是:如何将我的数据重塑回原始格式,以便我可以将这两个系列绘制成一个对比另一个,然后我可以计算一些准确度指标?
P.S。如果您在我的程序中发现错误,请随时指出。我对 LSTM 和 keras 还是新手,非常感谢任何帮助。
网络的输出层形状不正确 (10),但输出值应该只有 1。所以改变行
model.add(Dense(X_train.shape[1]))
进入
model.add(Dense(1))
解决问题。
P.S。查看输入数据,日期不是严格连续的:
2001-10-04 1.609100e+09
2001-10-05 1.301700e+09
2001-10-08 9.790000e+08
然而,你对待他们就好像他们是。我建议在这里用内插数字填充序列以做出更好的预测。