In [1]:
""" From: http://danielhnyk.cz/predicting-sequences-vectors-keras-using-rnn-lstm/ """
"""
time series for 20 stocks (e.g., IBM, AT&T, APPL). Each stock has 10,000 data points (length of time series).
In fact this code is written for multivariate time series setting.
It should be simple to turn it into the univariate case, if you like that case.
In order to run the code, make sure that the data matrix is a numpy array of size
T x N where T is the length of time series and N is the number of them.
Technically, with RNNs you should pass the entire history of time series and RNNs should be able to capture
the patterns over long period of time. But in practice most of the time series do not have the same length.
The solution to this is to pad them with zeros and use masking layer (supported in Keras).
However this process can be inefficient, when you have lots of variations on the length of time series.
One solution for this is to break long sequences into smaller pieces. The size of window determines the longest
patterns in time that can possibly be captured by RNN. You need to select the window size according to the
expected length of temporal patterns.
"""
Out[1]:
Out[1]:
In [2]:
import numpy as np
In [3]:
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
import glob
dpath = '/media/db/energy'
fs = glob.glob(dpath + "/CON*")
In [4]:
dpath = '/media/db/energy/CON_consolidated.csv'
df = pd.read_csv(dpath, delimiter=';', decimal=',')
df['Date'] = pd.to_datetime(df['Date'])
df.head()
Out[4]:
In [5]:
# Xi = timeseries of energy consumption
#X = df.ix[:, 1:].as_matrix().transpose()
X = df.ix[:, 1:].as_matrix()
X[0, :5]
X.shape
Out[5]:
Out[5]:
In [6]:
scaler = preprocessing.StandardScaler()
X_std = scaler.fit_transform(X)
X_std[0, :5]
#X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.4, random_state=0)
Out[6]:
In [7]:
def _load_data(data, steps = 40):
docX, docY = [], []
for i in range(0, data.shape[0]//steps-1):
docX.append(data[i*steps:(i+1)*steps,:])
docY.append(data[(i*steps+1):((i+1)*steps+1),:])
alsX = np.array(docX)
alsY = np.array(docY)
return alsX, alsY
In [8]:
def train_test_split(data, test_size=0.15, steps=40):
# This just splits data to training and testing parts
X,Y = _load_data(data, steps=steps)
ntrn = round(X.shape[0] * (1 - test_size))
perms = np.random.permutation(X.shape[0])
X_train, Y_train = X.take(perms[0:ntrn],axis=0), Y.take(perms[0:ntrn],axis=0)
X_test, Y_test = X.take(perms[ntrn:],axis=0),Y.take(perms[ntrn:],axis=0)
return (X_train, Y_train), (X_test, Y_test)
In [9]:
steps = 80
np.random.seed(0) # For reproducability
#data = np.genfromtxt('closingAdjLog.csv', delimiter=',')
(X_train, y_train), (X_test, y_test) = train_test_split(np.flipud(X_std), steps=steps) # retrieve data
print("Data loaded.")
In [10]:
X_train.shape, y_train.shape
X_train[0,:5,0]
y_train[0,:5,0]
Out[10]:
Out[10]:
Out[10]:
In [11]:
import keras
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.wrappers import TimeDistributed
from keras.layers.recurrent import GRU
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Convolution1D
from keras.layers.convolutional import MaxPooling1D
in_out_neurons = X.shape[1]
hidden_neurons = 300
epochs = 100
batch = 64
In [12]:
def get_model1():
model = Sequential()
model.add(GRU(hidden_neurons, input_dim=in_out_neurons, input_length=steps, return_sequences=True))
#model.add(BatchNormalization())
#model.add(Dropout(0.2))
model.add(TimeDistributed(Dense(in_out_neurons)))
#model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
print("Model compiled.")
return model
h5Name = 'data/tw_stock_TF_m1'
model = get_model1()
model.summary()
In [13]:
def get_model2():
model = Sequential()
model.add(GRU(hidden_neurons, input_dim=in_out_neurons, input_length=steps, return_sequences=True))
model.add(GRU(hidden_neurons, input_dim=in_out_neurons, input_length=steps, return_sequences=True))
#model.add(Dropout(0.2))
model.add(TimeDistributed(Dense(hidden_neurons)))
model.add(TimeDistributed(Dense(in_out_neurons)))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
print("Model compiled.")
return model
h5Name = 'data/tw_stock_TF_m2'
model = get_model2()
model.summary()
In [14]:
def get_model3():
model = Sequential()
model.add(Convolution1D(input_shape=(steps, in_out_neurons) ,nb_filter=256, filter_length=3, border_mode='same', activation='relu'))
#model.add(MaxPooling1D(pool_length=2))
model.add(Dropout(0.2))
model.add(GRU(hidden_neurons, return_sequences=True))
#model.add(BatchNormalization())
#model.add(Dropout(0.2))
model.add(TimeDistributed(Dense(in_out_neurons)))
#model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
print("Model compiled.")
return model
h5Name = 'data/tw_stock_TF_m3'
model = get_model3()
model.summary()
In [15]:
# and now train the model.
import tensorflow as tf
keras.backend.get_session().run(tf.global_variables_initializer())
model.fit(X_train, y_train, batch_size=batch, nb_epoch=epochs, validation_split=0.2)
Out[15]:
In [16]:
model.save_weights(h5Name)
In [17]:
predicted = model.predict(X_test)
print(np.sqrt(((predicted - y_test) ** 2).mean(axis=0)).mean()) # Printing RMSE
In [18]:
predicted.shape, y_test.shape
period = np.random.randint(y_test.shape[0])
market = np.random.randint(y_test.shape[2])
period, market
Out[18]:
Out[18]:
In [19]:
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(predicted[period, :, market], label="predicted")
x=plt.plot(y_test[period, :, market], label="truth")
plt.legend(loc='best')
Out[19]:
Out[19]:
In [ ]: