0

I have a multivariate time series that tracks material sales over time. The most peculiar column is sales because it has an intermittent pattern (i.e. many 0 values over time)

  material   prices       date  sales
0              2     1.41 1997-01-01    0.0
1              3   400.90 1997-01-01    0.0
2              6   695.08 1997-01-01    0.0
3              9   166.99 1997-01-01    0.0
4             11    32.28 1997-01-01    0.0
...          ...      ...        ...    ...
546310     14182     1.00 2001-07-01    0.0
546311     14183     1.00 2001-07-01    0.0
546312     14184     1.00 2001-07-01    0.0
546313     14185  4724.16 2001-07-01    0.0
546314     14437    21.55 2001-07-01    0.0

[546315 rows x 4 columns]

I am currently experimenting with synthesizing data with an LSTM model, and I found a post here that tries to apply panel/multivariate time series data to LSTM, seen here. Briefly, I adapted his code to synthesize my sales column based on prices and historical sales, as seen beneath:

from keras import models
from keras import layers
from keras.layers import Dense, LSTM
import time
import numpy as np
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
import tensorflow.keras.backend as K


oil_ts_copy = oil_ts.copy()

# Select the 'sales' and 'prices' columns as your input data X
X = oil_ts_copy[['sales', 'prices']].values

# Normalize the prices data
X[:, 1] = (X[:, 1] - np.mean(X[:, 1])) / np.std(X[:, 1])

# Shift the 'sales' column by one timestep to create your target data Y
Y = oil_ts_copy[['sales']].shift(-1).values[:-1]

# Remove the last row of X
X = X[:-1]

# Reshape X and Y to a suitable format for the LSTM network
X = X.reshape(X.shape[0], X.shape[1], 1)
Y = Y.reshape(Y.shape[0], 1, 1)

# Define the LSTM model with suitable parameters
model = models.Sequential()
model.add(layers.LSTM(128, activation='relu', input_shape=(X.shape[1], X.shape[2]), return_sequences=True))
model.add(layers.Dropout(0.2))
model.add(layers.LSTM(64, activation= 'relu', return_sequences=True)) 
model.add(layers.Dropout(0.2))
model.add(layers.LSTM(32, activation= 'relu')) # added another layer
model.add(layers.Dropout(0.2))
model.add(layers.Dense(1))

# Compile the model with a suitable loss function and optimizer
model.compile(optimizer='adam', loss='mae')

# Train the model on the input and target data
start_time = time.time()
history = model.fit(X, Y, epochs=100, batch_size=32)
end_time = time.time()

# Calculate the total computational time in hours
computational_time = (end_time - start_time) / 3600

print("Computational time (in hours):", computational_time)

# Make predictions on the test data
Y_pred = model.predict(X)

# Reshape the arrays to 1D
Y = Y.reshape(Y.shape[0],)
Y_pred = Y_pred.reshape(Y_pred.shape[0],)

# Add the last row of the predicted 'synthesized_sales' to the 'oil_ts_copy' data
oil_ts_copy['synthesized_sales'] = np.concatenate((Y_pred, [np.nan]))

I have several qquesitons about my code:

  1. Is the code appropriate for my data structure? The results thus far suggest that my LSTM model cannot fit the target data very well, and that's maybe because of my code.

  2. Is it wise to include other explanation variables other than the sales variable? If I correctly understand, I would individually synthesize each identifier if I include the 'material' column, while on the other hand I'd be syntheszing across SKUs without.

  3. Is LSTM viable to synthesize intermittent sales data? I am yet to find more appropriate alternatives.

0 Answers0