根据这个例子(参见“Train On Multiple Lag Timesteps Example”部分),为了基于过去两年的数据预测未来6小时的污染情况,我是否只需要设置n_hours=17520,并设置我想预测的未来步数n_out=6?
另外,我在别处读到应该将Dense层单元的数量修改为要预测的未来步数(这里是6),但是这样做总是返回错误。问题出在哪里?
谢谢
修改后的代码:
from math import sqrtfrom numpy import concatenatefrom matplotlib import pyplotfrom pandas import read_csvfrom pandas import DataFramefrom pandas import concatfrom sklearn.preprocessing import MinMaxScalerfrom sklearn.preprocessing import LabelEncoderfrom sklearn.metrics import mean_squared_errorfrom keras.models import Sequentialfrom keras.layers import Densefrom keras.layers import LSTM# convert series to supervised learningdef series_to_supervised(data, n_in=1, n_out=1, dropnan=True): n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # input sequence (t-n, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) if i == 0: names += [('var%d(t)' % (j+1)) for j in range(n_vars)] else: names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)] # put it all together agg = concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg# load datasetdataset = read_csv('pollution.csv', header=0, index_col=0)values = dataset.values# integer encode directionencoder = LabelEncoder()values[:,4] = encoder.fit_transform(values[:,4])# ensure all data is floatvalues = values.astype('float32')# normalize featuresscaler = MinMaxScaler(feature_range=(0, 1))scaled = scaler.fit_transform(values)# specify the number of lag hoursn_hours = 17520n_features = 8# frame as supervised learningreframed = series_to_supervised(scaled, n_hours, 6) # predict the next 6 hoursprint(reframed.shape)# split into train and test setsvalues = reframed.valuesn_train_hours = 365 * 24 *2train = values[:n_train_hours, :]test = values[n_train_hours:, :]# split into input and outputsn_obs = n_hours * n_featurestrain_X, train_y = train[:, :n_obs], train[:, -n_features]test_X, test_y = test[:, :n_obs], test[:, -n_features]print(train_X.shape, len(train_X), train_y.shape)# reshape input to be 3D [samples, timesteps, features]train_X = train_X.reshape((train_X.shape[0], n_hours, n_features))test_X = test_X.reshape((test_X.shape[0], n_hours, n_features))print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)# design networkmodel = Sequential()model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))model.add(Dense(1))model.compile(loss='mae', optimizer='adam')# fit networkhistory = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)# plot historypyplot.plot(history.history['loss'], label='train')pyplot.plot(history.history['val_loss'], label='test')pyplot.legend()pyplot.show()# make a predictionyhat = model.predict(test_X)test_X = test_X.reshape((test_X.shape[0], n_hours*n_features))# invert scaling for forecastinv_yhat = concatenate((yhat, test_X[:, -7:]), axis=1)inv_yhat = scaler.inverse_transform(inv_yhat)inv_yhat = inv_yhat[:,0]# invert scaling for actualtest_y = test_y.reshape((len(test_y), 1))inv_y = concatenate((test_y, test_X[:, -7:]), axis=1)inv_y = scaler.inverse_transform(inv_y)inv_y = inv_y[:,0]# calculate RMSErmse = sqrt(mean_squared_error(inv_y, inv_yhat))print('Test RMSE: %.3f' % rmse)
编辑:我已经将Dense层的单元数量改为6,同时也将train_y.shape[1]
和test_y.shape[1]
改为6,如下所示:
# load datasetdataset = read_csv('pollution.csv', header=0, index_col=0)values = dataset.values# integer encode directionencoder = LabelEncoder()values[:,4] = encoder.fit_transform(values[:,4])# ensure all data is floatvalues = values.astype('float32')# normalize featuresscaler = MinMaxScaler(feature_range=(0, 1))scaled = scaler.fit_transform(values)# specify the number of lag hoursn_hours =48n_out=6n_features = 8# frame as supervised learningreframed = series_to_supervised(scaled, n_hours, n_out)print(reframed.shape)# split into train and test setsvalues = reframed.valuesn_train_hours = 365 * 24 * 2train = values[:n_train_hours, :]test = values[n_train_hours:, :]# split into input and outputsn_obs = n_hours * n_featurestrain_X, train_y = train[:, :n_obs], train[:, :6]#我将-n_features改为6print(train_X.shape, len(train_X), train_y.shape)test_X, test_y = test[:, :n_obs], test[:,:6] # 我将-n_features改为6print(test_X.shape, len(test_X), test_y.shape)# reshape input to be 3D [samples, timesteps, features]train_X = train_X.reshape((train_X.shape[0], n_hours, n_features))train_y = train_ytest_X = test_X.reshape((test_X.shape[0], n_hours, n_features))print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)train_y.shape# design networkmodel = Sequential()model.add(LSTM(5, input_shape=(train_X.shape[1], train_X.shape[2])))model.add(Dense(6))model.compile(loss='mae', optimizer='adam')# fit networkhistory = model.fit(train_X, train_y, epochs=5, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False) # plot historypyplot.plot(history.history['loss'], label='train')pyplot.plot(history.history['val_loss'], label='test')pyplot.legend()pyplot.show()# make a predictionyhat = model.predict(test_X)test_X = test_X.reshape((test_X.shape[0], n_hours*n_features))# invert scaling for forecastinv_yhat = concatenate((yhat, test_X[:, -7:]), axis=1)inv_yhat = scaler.inverse_transform(inv_yhat)inv_yhat = inv_yhat[:,0]# invert scaling for actualtest_y = test_y.reshape((len(test_y), 1))inv_y = concatenate((test_y, test_X[:, -7:]), axis=1)inv_y = scaler.inverse_transform(inv_y)inv_y = inv_y[:,0]# calculate RMSErmse = sqrt(mean_squared_error(inv_y, inv_yhat))print('Test RMSE: %.3f' % rmse)
我遇到的错误:
---------------------------------------------------------------------------ValueError Traceback (most recent call last)<ipython-input-57-8e17d1d76420> in <module> 9 # invert scaling for forecast 10 inv_yhat = concatenate((yhat, test_X[:, -7:]), axis=1)---> 11 inv_yhat = scaler.inverse_transform(inv_yhat) 12 inv_yhat = inv_yhat[:,0] 13 # invert scaling for actual~\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\preprocessing\data.py in inverse_transform(self, X) 404 force_all_finite="allow-nan") 405 --> 406 X -= self.min_ 407 X /= self.scale_ 408 return XValueError: operands could not be broadcast together with shapes (26227,13) (8,) (26227,13)
回答: