Я пытаюсь предсказать направления транспортировки (пока что двоичные), используя классификатор временных рядов CNN-LSTM. Наблюдения ограничены из-за данных, относящихся только к 2010 году, поэтому сбор дополнительных данных невозможен. Исходные данные состоят из двоичной переменной Y и 68 X переменных, которые дополнительно расширены, чтобы включить 50 лагов тех же переменных, относящихся ко времени, давая измерение [:, 50,68] для X.
Проблема в том, что когда я подгоняю модель, она быстро сводится к прогнозированию только одного класса (да, данные не сбалансированы 65/35). При попытке использовать только 1-слойный LSTM или простой CNN он полностью переопределяется, в то время как более сложная модель возвращает только один класс. Любые предложения (я пробовал разные скорости обучения и увеличение отсева), см. Код:
def to_supervised():# array[obs,lag,features] every y is denoted by todays and 30 last day values
dataset = read_csv('alldataDests.csv', header=0, infer_datetime_format=True, parse_dates=['0'], index_col=['0'])
lag,endTrain,startTest = 50,2000,2001
mean = dataset.iloc[0:endTrain, 1:].mean(axis=0)
dataset.iloc[:,1:]-=mean
std = dataset.iloc[0:endTrain,1:].std(axis=0)
dataset.iloc[:,1:] /= std
x = dataset.values[:,1:]
y = dataset.values[:,0]
#train, test = dataset.values[0:endTrain], dataset.values[startTest:]
# restructure into windows of lagged data
xLag = array([x[i:i+lag] for i in range(len(x)-lag+1)])
trainY = to_categorical(y[lag-1:endTrain])
trainX=xLag[:endTrain-(lag-1),:,:]
testY = to_categorical(y[startTest:])
testX = xLag[startTest-(lag-1):,:,:]
testX = testX[:1316,:,:]
testY = testY[:1316]
return trainX,trainY,testX,testY
def evaluate_model(trainX, trainY, testX, testy):
verbose, epochs, batch_size = 1, 500, 128
n_timesteps, n_features, n_outputs = trainX.shape[1], trainX.shape[2], trainY.shape[1]
model = Sequential()
model.add(Conv1D(32, 2, activation='relu', input_shape=(n_timesteps,n_features),
kernel_regularizer = l2(0.02),
bias_regularizer=l2(0.02)))
model.add(Conv1D(32, 2, activation='relu',kernel_regularizer = l2(0.02),
bias_regularizer=l2(0.02)))
model.add(Dropout(0.5))
model.add(MaxPooling1D())
model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dense(n_outputs, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer=optimizers.SGD(lr=0.00001), metrics=['accuracy'])
# fit network
model.fit(trainX, trainY, epochs=epochs, batch_size=batch_size, verbose=verbose)
# evaluate model
_, accuracy = model.evaluate(testX, testy, batch_size=batch_size, verbose=0)
preds = model.predict_classes(testX, batch_size=batch_size, verbose=0)
preds_proba = model.predict_proba(testX, batch_size=batch_size, verbose=0)
return accuracy, preds,preds_proba
# summarize scores
def summarize_results(scores):
print(scores)
m, s = mean(scores), std(scores)
print('Accuracy: %.3f%% (+/-%.3f)' % (m, s))
# run an experiment
def run_experiment(repeats=1):
# load data
trainX, trainY, testX, testY = to_supervised()
# repeat experiment
scores = list()
for r in range(repeats):
score, preds, preds_proba = evaluate_model(trainX, trainY, testX, testY)
score = score * 100.0
print('>#%d: %.3f' % (r+1, score))
scores.append(score)
# summarize results
summarize_results(scores)
return preds, preds_proba
preds, preds_proba= run_experiment()```