I can't figure out how to predict next 100 values in future? I have array of values(1000) and I need to predict next 100 values.
Please check my code
close_arr = close_arr[::-1]
close = np.array(close_arr)
print(close)
print(len(close))
# Dataframe must have columns "ds" and "y" with the dates and values respectively.
df = pd.DataFrame({'y': close}) #'ds': timestamp,
df = df[['y']]
# prepere data for tensorflow
scaler = MinMaxScaler(feature_range=(0, 1))
yahoo_stock_prices = scaler.fit_transform(df)
train_size = int(len(yahoo_stock_prices) * 0.80)
print(f"train_size: {train_size}")
test_size = len(yahoo_stock_prices) - train_size
train, test = yahoo_stock_prices[0:train_size, :], yahoo_stock_prices[train_size:len(yahoo_stock_prices), :]
print(len(train), len(test))
# reshape into X=t and Y=t+1
look_back = 1
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))
# Step 2 Build Model
model = Sequential()
model.add(LSTM(50, activation='relu', return_sequences=True, input_shape=(1, look_back)))
model.add(LSTM(50, activation='relu', return_sequences=True))
model.add(Dense(25))
model.add(Dense(1, activation='linear'))
model.compile(loss='mse', optimizer='rmsprop')
model.fit(trainX, trainX, batch_size=128, epochs=100,validation_split=0.05)
model.evaluate(trainX, trainX, verbose=2)
predict_length = 50
# how to predict next 50 values from testX?
# Step 1 - predict the future values
predicted = model.predict(testX)
print(f"predicted: {scaler.inverse_transform(np.array(predicted).reshape(-1, 1))}")
print(len(predicted))
# Step 2 - Plot the predictions!
plot_results_multiple(predicted, testX, predict_length)
def create_dataset(dataset, look_back=1):
# prepare data
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return np.array(dataX), np.array(dataY)
Code is work but I receive only redicted data with same length, not future prediction.
Also here is result what I received
enter image description here
First of all, you need to prepare your output data (y_train, y_test) to have the shape of (number_of_rows, 100). The last layer of your network should be 100, not 1.
model.add(Dense(100, activation='linear'))
Also, the lock_back means how many of the last days to use which is 1 in this case, it should be more, so First look at prepare data function and change there in a way to have outputs of shape 100. Fix the output layer of your network to have 100
I would assume that look_back refers to the number of lags of the time-series you are using, which in this case is 1. Not sure where do you import the create_dataset function, but I would assume that it creates your datasets so the X contains the values of the time-series at time t-1 and the Y contains the values at time t.
That being said you have two options for generating a forecast for 100 time steps.
You could train your model to predict 1 time step as you have done in your code. In order to generate a forecast for 100 time steps ahead you need to iteratively input into the model your last forecast in order to produce a forecast for the next time step.
The other option is to use this create_dataset function to set up the dataset so that your Y datasets contain 100 time steps. This means that the model be set up to output a sequence of 100 values.
Hope this helps!
Related
I am trying to feed stock data to Conv2D. But ran into dimension problem. I have no idea how to solve it and need help. Below are detailed steps that I have implemented.
I have attached data and code in the following link:
https://drive.google.com/drive/folders/1snsQ-96AeRn521oc0aQVlTTd9nHbtyjO?usp=sharing
by the code itself should run. It will download the data automatically. but ive taken out the featuers to simplify the run. So it will have 5 features in the attached code.
but to give you quick glance of
The Problem I had-----------------------
1. Got stock data and generated some features, it looks like:
2. Add time step to it by using:
def reshape_data(X, y, period=28):
n_past = period # number of days to look back in the past and compile into a time series
trainX = []
trainY = np.array(y.iloc[n_past:])
trainY = trainY[..., np.newaxis]
for i in range(n_past, len(X)):
trainX.append(X[i - n_past:i, 0:X.shape[1]])
trainX = np.array(trainX)
return trainX, trainY
Note:
data can be found here
https://drive.google.com/drive/folders/1snsQ-96AeRn521oc0aQVlTTd9nHbtyjO?usp=sharing
I have applied pca on it. But simply convert it into numpy and apply reshap_data() on trainX should work
trainX, trainY = reshape_data(X_train_pca, y_train, period=30)
3. shape
trainX (5768, 30, 30) # 5768-rows, 30- time steps, 30- # of features
trainY (5768,1)
4. Add 1 axis after train X
trainX = trainX[...,np.newaxis]
trainX is now (5768, 30, 30, 1)
5. Build model
6. fit and run
model.compile(optimizer=Adam(learning_rate=0.01) , metrics="mse", loss='binary_crossentropy')
reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',factor=0.5,patience=10,verbose=0,mode='auto',min_delta=0.0002,cooldown=0,min_lr=0.0001)
early_stop = tf.keras.callbacks.EarlyStopping(monitor="val_loss", patience=80, mode="min", restore_best_weights = True)
history = model.fit(trainX, trainY, epochs=300,
batch_size= 512, shuffle=False, verbose = 1,
# validation_data=(testX, testY),
validation_split=0.2,
callbacks=[early_stop, reduce_lr] )
7. ERROR
I thought since I have convered the stock into 30,30,1 should looks like a image dataset, which would enable tensorflow to work. But somehow it doesn't
Add two layers after your convolution layer:
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
And do not mix up tensorflow.keras and keras. Rather just use tensorflow.keras for everything.
I am trying to train a LSTM model to reconstruct time series data. I have a data set of ~1800 univariant time-series.
Basically I'm trying to solve a problem similar to this one Anomaly detection in ECG plots, but my time series have different lengths.
I used this approach to deal with variant length:
How to apply LSTM-autoencoder to variant-length time-series data?
and this approach to split the input data based on shape:
Keras misinterprets training data shape
When looping over the data and fitting a model for every shape. is the model eventually only based on the last shape it trained on or is it using all the data to train the final model?
How would I train the model on all input data regardless shape of data?
I know I can add padding but I am trying to use the data as is at this point.
Any suggestions or other approaches to deal with different length on timeseries?
(It is not an issue of time sampling it is more of one timeseries started recording on day X and some only on day X+100)
Here is the code I am using for my autoencoder:
import keras.backend as K
from keras.layers import (Input, Dense, TimeDistributed, LSTM, GRU, Dropout, merge,
Flatten, RepeatVector, Bidirectional, SimpleRNN, Lambda)
def encoder(model_input, layer, size, num_layers, drop_frac=0.0, output_size=None,
bidirectional=False):
"""Encoder module of autoencoder architecture"""
if output_size is None:
output_size = size
encode = model_input
for i in range(num_layers):
wrapper = Bidirectional if bidirectional else lambda x: x
encode = wrapper(layer(size, name='encode_{}'.format(i),
return_sequences=(i < num_layers - 1)))(encode)
if drop_frac > 0.0:
encode = Dropout(drop_frac, name='drop_encode_{}'.format(i))(encode)
encode = Dense(output_size, activation='linear', name='encoding')(encode)
return encode
def repeat(x):
stepMatrix = K.ones_like(x[0][:,:,:1]) #matrix with ones, shaped as (batch, steps, 1)
latentMatrix = K.expand_dims(x[1],axis=1) #latent vars, shaped as (batch, 1, latent_dim)
return K.batch_dot(stepMatrix,latentMatrix)
def decoder(encode, layer, size, num_layers, drop_frac=0.0, aux_input=None,
bidirectional=False):
"""Decoder module of autoencoder architecture"""
decode = Lambda(repeat)([inputs,encode])
if aux_input is not None:
decode = merge([aux_input, decode], mode='concat')
for i in range(num_layers):
if drop_frac > 0.0 and i > 0: # skip these for first layer for symmetry
decode = Dropout(drop_frac, name='drop_decode_{}'.format(i))(decode)
wrapper = Bidirectional if bidirectional else lambda x: x
decode = wrapper(layer(size, name='decode_{}'.format(i),
return_sequences=True))(decode)
decode = TimeDistributed(Dense(1, activation='linear'), name='time_dist')(decode)
return decode
inputs = Input(shape=(None, 1))
encoded = encoder(inputs,LSTM,128, 2, drop_frac=0.0, output_size=None, bidirectional=False)
decoded = decoder(encoded, LSTM, 128, 2, drop_frac=0.0, aux_input=None,
bidirectional=False,)
sequence_autoencoder = Model(inputs, decoded)
sequence_autoencoder.compile(optimizer='adam', loss='mae')
trainByShape = {}
for item in train_data:
if item.shape in trainByShape:
trainByShape[item.shape].append(item)
else:
trainByShape[item.shape] = [item]
for shape in trainByShape:
modelHistory =sequence_autoencoder.fit(
np.asarray(trainByShape[shape]),
np.asarray(trainByShape[shape]),
epochs=100, batch_size=1, validation_split=0.15)
use a bidirectional lstm and increase the number of parameters to gain accuracy. I increased the latent_dim to 1000 and it fit the data closely. More hardware and more memory.
def create_dataset(dataset, look_back=3):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back)]
dataX.append(a)
dataY.append(dataset[i + look_back])
return np.array(dataX), np.array(dataY)
COLUMNS=['Open']
dataset=eqix_df[COLUMNS]
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(np.array(dataset).reshape(-1,1))
train_size = int(len(dataset) * 0.70)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size], dataset[train_size:len(dataset)]
look_back=10
trainX=[]
testX=[]
y_train=[]
trainX, y_train = create_dataset(train, look_back)
testX, y_test = create_dataset(test, look_back)
X_train = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
X_test = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))
latent_dim=700
n_future=1
model = Sequential()
model.add(Bidirectional(LSTM(units=latent_dim, return_sequences=True,
input_shape=(X_train.shape[1], 1))))
#LSTM 1
model.add(Bidirectional(LSTM(latent_dim,return_sequences=True,dropout=0.4,recurrent_dropout=0.4,name='lstm1')))
#LSTM 2
model.add(Bidirectional(LSTM(latent_dim,return_sequences=True,dropout=0.2,recurrent_dropout=0.4,name='lstm2')))
#LSTM 3
model.add(Bidirectional(LSTM(latent_dim, return_sequences=False,dropout=0.2,recurrent_dropout=0.4,name='lstm3')))
model.add(Dense(units = n_future))
model.compile(optimizer="adam", loss="mean_squared_error", metrics=["acc"])
history=model.fit(X_train, y_train,epochs=50,verbose=0)
plt.plot(history.history['loss'])
plt.title('loss accuracy')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
#print(X_test)
prediction = model.predict(X_test)
# shift train predictions for plotting
trainPredictPlot = np.empty_like(dataset)
trainPredictPlot[:, :] = np.nan
trainPredictPlot[look_back:len(prediction)+look_back, :] = prediction
# shift test predictions for plotting
#plt.plot(scaler.inverse_transform(dataset))
plt.plot(trainPredictPlot, color='red')
#plt.plot(testPredictPlot)
#plt.legend(['Actual','Train','Test'])
x=np.linspace(look_back,len(prediction)+look_back,len(y_test))
plt.plot(x,y_test)
plt.show()
Keras LSTM implementation expect a input of type: (Batch, Timesteps, Features).
One solution would be to set Timesteps = 1 and pass the sequence lengths as the Batch dimensions.
If the sampling procedure is the same (no need for resampling), and the difference in length only comes from when the recording time start (X+100 instead of X), I would try to get rid off the lag in the pre-processing stages to get the section of interest only.
Part 1: Plotting the irregular heartbeat. Part 2 is a DENSE network to classify incoming heartbeat voltage to predict irregular beat patterns. 94% accuracy!
from scipy.io import arff
import pandas as pd
from scipy.misc import electrocardiogram
import matplotlib.pyplot as plt
import numpy as np
data = arff.loadarff('ECG5000_TRAIN.arff')
df = pd.DataFrame(data[0])
#for column in df.columns:
# print(column)
columns=[x for x in df.columns if x!="target"]
print(columns)
#print(df[df.target == "b'1'"].drop(labels='target', axis=1).mean(axis=0).to_numpy())
normal=df.query("target==b'1'").drop(labels='target', axis=1).mean(axis=0).to_numpy()
rOnT=df.query("target==b'2'").drop(labels='target', axis=1).mean(axis=0).to_numpy()
pcv=df.query("target==b'3'").drop(labels='target', axis=1).mean(axis=0).to_numpy()
sp=df.query("target==b'4'").drop(labels='target', axis=1).mean(axis=0).to_numpy()
ub=df.query("target==b'5'").drop(labels='target', axis=1).mean(axis=0).to_numpy()
plt.plot(normal,label="Normal")
plt.plot(rOnT,label="R on T",alpha=.3)
plt.plot(pcv, label="PCV",alpha=.3)
plt.plot(sp, label="SP",alpha=.3)
plt.plot(ub, label="UB",alpha=.3)
plt.legend()
plt.title("ECG")
plt.show()
Frame by frame comparision for normal. There are bands of operation which a normal heart stays with:
def PlotTheFrames(df,title,color):
fig,ax = plt.subplots(figsize=(140,50))
for key,item in df.iterrows():
array=[]
for value in np.array(item).flatten():
array.append(value);
x=np.linspace(0,100,len(array))
ax.plot(x,array,c=color)
plt.title(title)
plt.show()
normal=df.query("target==b'1'").drop(labels='target', axis=1)
PlotTheFrames(normal,"Normal Heart beat",'r')
R on T the valves don't seem to be operating correctly
rOnT=df.query("target==b'2'").drop(labels='target', axis=1)
PlotTheFrames(rOnT,"R on T Heart beat","b")
Use a deep learning dense network instead of LSTM! I used leakyReLU for the smaller gradient descent
X=df[columns]
y=pd.get_dummies(df['target'])
model=Sequential()
model.add(Dense(440, input_shape=(len(columns),),activation='LeakyReLU'))
model.add(Dropout(0.4))
model.add(Dense(280, activation='LeakyReLU'))
model.add(Dropout(0.2))
model.add(Dense(240, activation='LeakyReLU'))
model.add(Dense(32, activation='LeakyReLU'))
model.add(Dense(16, activation='LeakyReLU'))
model.add(Dense(5))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.3, random_state=42)
scaler = StandardScaler()
scaler.fit(X_train)
X_train=scaler.transform(X_train)
X_test=scaler.transform(X_test)
history=model.fit(X_train, y_train,epochs = 1000,verbose=0)
model.evaluate(X_test, y_test)
plt.plot(history.history['loss'])
plt.title('loss accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
Here is my model definition:
model = Sequential()
model.add(LSTM(i, input_shape=(None, 1), return_sequences=True))
model.add(Dropout(l))
model.add(LSTM(j))
model.add(Dropout(l))
model.add(Dense(k))
model.add(Dropout(l))
model.add(Dense(1))
and here is result
p = model.predict(x_test)
plt.plot(y_test)
plt.plot(p)
The sequential input represents the past signal in previous time-steps, the output is predicting the signal in next time-step. After splitting the training and testing data, the predictions on the test data is as follows:
The figure shows almost a perfect match with gold test data and the predictions. Is it possible to predict with such high accuracy?
I think something is wrong because there's no volatility. So I wonder if it's been implemented properly.
If the implementation is correct, how can you get the following(next) value?
Is it right to do this implement?
a = x_test[-1]
b = model.predict(a)
c = model.predict(b)
...
To sum up the question:
Is the implementation right way?
I wonder how to get the value of the next data.
def create_dataset(signal_data, look_back=1):
dataX, dataY = [], []
for i in range(len(signal_data) - look_back):
dataX.append(signal_data[i:(i + look_back), 0])
dataY.append(signal_data[i + look_back, 0])
return np.array(dataX), np.array(dataY)
train_size = int(len(signal_data) * 0.80)
test_size = len(signal_data) - train_size - int(len(signal_data) * 0.05)
val_size = len(signal_data) - train_size - test_size
train = signal_data[0:train_size]
val = signal_data[train_size:train_size+val_size]
test = signal_data[train_size+val_size:len(signal_data)]
x_train, y_train = create_dataset(train, look_back)
x_val, y_val = create_dataset(val, look_back)
x_test, y_test = create_dataset(test, look_back)
I use create_dataset with look_back=20.
signal_data is preprocessed with min-max normalisation MinMaxScaler(feature_range=(0, 1)).
Is the implementation right way?
Your code seems correct. I think you are not getting surprising results. You need to compare the results with a baseline that next prediction is randomly sampled from the range of possible day-to-day change. This way at least you can understand if your model is doing better than random sampling.
delta_train = train[1][1:] - train[1][:-1]
delta_range_train = delta_train.max()-delta_train.min()
# generating the baseline based on the change range in training:
random_p = test[0][:, -1] + (np.random.rand(test[0].shape[0])-0.5)*delta_range_train
You can check if your results are better than just a random sample random_p.
I wonder how to get the value of the next data.
this gives you the last data point in the test set:
a = x_test[-1:]
then, here you are predicting the next point day:
b = model.predict(a)
based on look_back you may need to keep some of the datapoints from to predict the next-next point:
c = model.predict(np.array([list(a[0,1:])+[b]])
I'm currently building an LSTM multivariate time-series model to predict one output at current time (t) using 22 features from the previous timestamp (t-1) as inputs. I've been following the instructions from this example, and everything seems to be working correctly, but the one issue I'm having involves the final inverse_transform() functions.
Specifically, I'm expecting that once I invert the scaling for both the forecasted values and the actual values, the output will be in the same units as the original data before I normalized and transformed my dataset. The variable I'm trying to predict has a mean of around 29.186, but when I run inverse_transform() and plot the predictions against the actuals, the output of my results ranges from 3.30 - 3.55.
It could be that I've made a simple error slicing the array, or it could be something completely different, but I can't seem to identify the root cause of why my predicted and actual values aren't in the same units as the data before I transformed everything.
For additional context, here's the printed output of train_X.shape, train_y.shape, test_X.shape, test_y.shape:
(1804950, 1, 22) (1804950,) (849389, 1, 22) (849389,)
Here's the relevant parts of my code:
# ensure all data is float
values = ips_data.values.astype('float32')
# normalize features
scaler = MinMaxScaler(feature_range=(0, 1))
scaled = scaler.fit_transform(values)
# frame as supervised learning
ips_reframed = series_to_supervised(scaled, 1, 1)
# drop a bunch of columns I don't want to predict
ips_reframed.drop(ips_reframed.columns[[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,43]], axis=1, inplace=True)
# print(ips_reframed.head())
# split into train and test sets
values = ips_reframed.values
# n_train_hours = (365 * 24 * 60) * 3
n_train_hours = int(len(values) * 0.68)
train = values[:n_train_hours, :]
test = values[n_train_hours:, :]
# split into input and outputs
train_X, train_y = train[:, :-1], train[:, -1]
test_X, test_y = test[:, :-1], test[:, -1]
# reshape input to be 3D [samples, timesteps, features]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
# print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
# design network
model = Sequential()
model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2]), return_sequences=True))
model.add(Dropout(0.5))
model.add(LSTM(50))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation("linear"))
model.compile(loss='mae', optimizer='adam')
# fit network
history = model.fit(train_X, train_y, epochs=100, batch_size=1000,
validation_data=(test_X, test_y), verbose=2, shuffle=False)
# plot history
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend()
plt.show()
# make a prediction
yhat = model.predict(test_X)
# invert scaling for forecast
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
inv_yhat = scaler.inverse_transform(inv_yhat)
inv_yhat = inv_yhat[:,0]
# invert scaling for actual
test_y = test_y.reshape((len(test_y), 1))
inv_y = concatenate((test_y, test_X[:, 1:]), axis=1)
inv_y = scaler.inverse_transform(inv_y)
inv_y = inv_y[:,0]
# calculate RMSE
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
# print('Test RMSE: %.3f' % rmse)
# plotting the predictions
plt.plot(inv_yhat[-100:], label='predictions')
plt.plot(inv_y[-100:], label='actual')
plt.title("Prediction vs. Actual")
plt.legend()
plt.show()
Please let me know if you need any additional information or context, and thank you so much for your help!
I have a dataset with 3 features in a timeseries. The dimension of the dataset is 1000 x 3 (1000 timesteps and 3 features). Basically, 1000 rows and 3 columns
The data looks like this:
A B C
131 111 100
131 110 120
131 100 100
...
131 100 100
The problem is how to train the first 25 steps and predict the next 25 steps in order to get the output of 3 features predictions which is (A, B and C). I successful train and predict 1-D (1 features(A)) array. But I have no idea how to predict the 3 features using same the dataset.
And I got this error:
Error when checking target: expected dense_1 to have shape (None, 3) but got array with shape (21, 1)
The code as below:
# -*- coding: utf-8 -*-
import numpy as np
import numpy
import matplotlib.pyplot as plt
import pandas
import math
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset) - look_back - 1):
a = dataset[i:(i + look_back):]
dataX.append(a)
dataY.append(dataset[i + look_back, :])
return numpy.array(dataX), numpy.array(dataY)
# fix random seed for reproducibility
numpy.random.seed(7)
# load the dataset
dataframe = pandas.read_csv('v77.csv', engine='python',skiprows=0)
dataset = dataframe.values
print dataset
# normalize the dataset
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
# split into train and test sets
train_size = 10
test_size = 10
train, test = dataset[0:train_size, :], dataset[train_size:train_size+test_size, :]
print (train_size,test_size)
# reshape into X=t and Y=t+1
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
print trainX
# reshape input to be [samples, time steps, features]
#trainX = numpy.reshape(trainX, (trainX.shape[0], look_back, 3))
#testX = numpy.reshape(testX, (testX.shape[0],look_back, 3))
# create and fit the LSTM network
model = Sequential()
model.add(LSTM(32, input_shape=(3,3)))
model.add(Dense(3))
model.compile(loss='mean_squared_error', optimizer='adam')
history= model.fit(trainX, trainY,validation_split=0.33, nb_epoch=10, batch_size=16)
# make predictions
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# print testPredict
# print np.shape(testPredict)
# Get something which has as many features as dataset
trainPredict_extended = numpy.zeros((len(trainPredict),3))
print trainPredict_extended
print np.shape(trainPredict_extended[:,2])
print np.shape(trainPredict[:,0])
# Put the predictions there
trainPredict_extended[:,2] = trainPredict[:,0]
# Inverse transform it and select the 3rd coumn.
trainPredict = scaler.inverse_transform(trainPredict_extended) [:,2]
# print(trainPredict)
# Get something which has as many features as dataset
testPredict_extended = numpy.zeros((len(testPredict),3))
# Put the predictions there
testPredict_extended[:,2] = testPredict[:,0]
# Inverse transform it and select the 3rd column.
testPredict = scaler.inverse_transform(testPredict_extended)[:,2]
# print testPredict_extended
trainY_extended = numpy.zeros((len(trainY),3))
trainY_extended[:,2]=trainY
trainY=scaler.inverse_transform(trainY_extended)[:,2]
testY_extended = numpy.zeros((len(testY),3))
testY_extended[:,2]=testY
testY=scaler.inverse_transform(testY_extended)[:,2]
# print
# print testY
# calculate root mean squared error
trainScore = math.sqrt(mean_squared_error(trainY, trainPredict))
print('Train Score: %.2f RMSE' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY, testPredict))
print('Test Score: %.2f RMSE' % (testScore))
Sample data:
v77.txt
Help Needed. Thanks
Your Y shape does not match up with the last layer in your model. Your Y is in the form of (num_samples, 1), which means that for every sample it outputs a vector of length 1.
Your last layer, however, is a Dense(3) layer, which outputs (num_samples, 3), which means that for every sample it outputs a vector of length 3.
Since the output of your neural network and your y-data aren't in the same format, the neural network cannot train.
You can fix this in two ways:
1.Convert the output of your neural network to the shape of your y data by replacing Dense(3) with Dense(1):
model = Sequential()
model.add(LSTM(32, input_shape=(3,3)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')history= model.fit(trainX, trainY,validation_split=0.33, nb_epoch=10, batch_size=16)
2.Convert the shape of your y data to the output of your neural network by modifying your create_dataset() function such that all of the features are added to the y instead of just one:
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset) - look_back - 1):
a = dataset[i:(i + look_back):]
dataX.append(a)
dataY.append(dataset[i + look_back, :])
return numpy.array(dataX), numpy.array(dataY)
Since you stated that you wanted to predict 3 feature most likely you will be using the second option. Note that the second option does break the last part of your code to extend the y, but your model trains fine.