Как построить модель LSTM для переменного количества функций во временных сериях - PullRequest
0 голосов
/ 12 марта 2019

У меня есть рабочий keras lstm для данных временных рядов, созданный с использованием одноразовых данных. Я перестал работать над ним, чтобы работать с другими частями моей системы, но теперь я внедряю его для производства, и мне нужно преобразовать свой подход к работе с переменным количеством функций. Пользователи начнут с небольшого количества функций и постепенно добавят их со временем.

[continous_value: 0.1, categoryA: 1]
[continous_value: 0.2, categoryA: 0, categoryB: 1]
[continous_value: 0.3, categoryA: 1, categoryB: 0]
...

Большинство «выпадет» в том смысле, что они не будут повторяться, и поэтому их легко обрезать, перемещая окно с течением времени - но некоторые повторяются с регулярностью. В настоящее время мой lstm построен на данных, которые были в окне для одного пользователя.

Каждая строка представляет собой 15-минутную выборку, и мои данные выборки имеют 2 непрерывных и 7 категориальных признаков. У меня 14-дневная сезонность (4 * 24 * 14 = 1344 временного шага), поэтому я выполнял повторную выборку в форму, подобную x:(1344, 14, 9) и y:(1344, 9)

Теперь, чтобы позволить модели работать для разных пользователей, я начал добавлять «столбцы заполнения», но это не идеально: мне нужно угадать, каким будет максимум, и чем больше число, тем менее прогнозирующим модель.

Keras LSTM могут иметь переменное число объектов путем установки временного шага = Нет (поэтому x:(b, None, 9), я полагаю), но я не вижу, как реализовать это с многомерными данными временных рядов.

Как бы я изменил это для правильной генерации данных?

обработка данных:

# the memory of RNN depends on the number of timesteps you select
# if timesteps = n then the output depends on the previous n inputs

n = 14 # well over the weekly periodicity of the data

# Create input set that consists of n dimensions
# hence, the output of current day will be based on 
# the prices of previous n days

len_train = 49 * DAYS
len_test = 7 * DAYS #(4 * 24)

train, test, endog, exog = dataForTest(len_train=len_train, len_test=len_test, offset=3*DAYS)

#print(train.iloc[-1],'\n',test.iloc[-1])
print(endog, exog)

dim = len(endog) + len(exog)

window = len_test # dim * 100 #using dim ensures it is reshapable dividing by dim

X_train = []
y_train = []
for i in range(n, n+(window)): 
    X_train.append(train[i - n: i].values)
    y_train.append(train[i:i+1].values)

X_train, y_train = np.array(X_train), np.array(y_train)

y_train = y_train.reshape((window,dim))

print(X_train.shape, y_train.shape)

(batch_size, timesteps, dim) = X_train.shape

Модель:

# Initialise Sequential model
regressor = Sequential()

# units is the output dimensionality
# return sequences will return the sequence
# which will be required to the next LSTM 

# as a great big rule-o-thumb, layers should be less than 10, and perhaps 1 per endog plus 1 for all exog
# also see: https://stats.stackexchange.com/questions/181/how-to-choose-the-number-of-hidden-layers-and-nodes-in-a-feedforward-neural-netw/1097#1097

alphaNh = len(columns) if len(columns) < 10 else 10 # 2-10, with 2 or 5 being common
nh = int(batch_size/(alphaNh*2*len(series.columns)))

dropout = 0.2

print('nh', nh)  

# input shape will need only the last 2 dimensions
# of your input
################# 1st layer #######################
regressor.add(LSTM(units=nh, return_sequences=True, stateful=True, batch_size=batch_size,
                   input_shape=(timesteps, dim)))

# add Dropout to do regulariztion
# standard practise to use 20%
# regressor.add(Dropout(dropout))

layers = (len(endog) + 1) if len(endog) > 1 else 2
print('layers', layers)
for i in range(1, layers):
  # After the first time, it's not required to 
  # specify the input_shape
  ################# layer #######################
#  if i > 5:
#      break
  if i < layers - 1:
    cell = LSTM(units=nh, return_sequences=True, stateful=True, batch_size=batch_size)
  else:
    cell = LSTM(units=nh, stateful=True, batch_size=batch_size)

  regressor.add(cell)

################# Dropout layer #################
# After training layers we use some dropout.
# another option is to put this after each dim 
# layer (above)
#
# standard practise to use 20%

regressor.add(Dropout(dropout))

################# Last layer ####################
# Last layer would be the fully connected layer,
# or the Dense layer
#
# The last word will predict a single number
# hence units=1

regressor.add(Dense(units=dim))

# Compiling the RNN
# The loss function for classification problem is 
# cross entropy, since this is a regression problem
# the loss function will be mean squared error

regressor.compile(optimizer='adam', loss='mean_squared_error')

### src: https://keras.io/callbacks/
#saves the model weights after each epoch if the validation loss decreased
###
checkpointer = ModelCheckpoint(filepath='weights.hdf5', verbose=1, monitor='loss', mode='min', save_best_only=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...