Два месяца назад я начал работать с keras, чтобы получить шаблон накачки для использования в других программах.
Я не знаю причин(ы), по которым полученные мной узоры не имеют ничего общего с реальными. Я попытался установить несколько функций (входных данных) в наборе данных, а также добавить больше входных данных, но это не работает. Результаты выглядят так:
Где:
- Синий: набор данных (реальные данные, которые я пытаюсь «аппроксимировать»)
- Оранжевый: предсказание
Набор данных представляет собой временной ряд
вотфайл csv с набором данных
Вот код:
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
from keras.regularizers import l2, activity_l2
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset) - look_back - 1):
a = dataset[i:(i + look_back), 0:4]
dataX.append(a)
dataY.append(dataset[i + look_back, 4])
return numpy.array(dataX), numpy.array(dataY)
# fix random seed for reproducibility
seed=7
numpy.random.seed(seed)
# load dataset
dataframe = pandas.read_csv('datos_horarios.csv', engine='python')
dataset = dataframe.values
# normalizar el dataset
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
#split data into train data and test data
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size, :], dataset[train_size:len(dataset), :]
# reshape to X=t y Y=t+1
look_back = 1
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
# reshape inputs to be [samples, time steps, features]
trainX = numpy.reshape(trainX, (trainX.shape[0], look_back, 4))
testX = numpy.reshape(testX, (testX.shape[0], look_back, 4))
# create and adjust LSTM network
model = Sequential()
model.add(Dropout(0.3, input_shape=(look_back,4)))
model.add(LSTM(6, input_shape=(look_back,4), W_regularizer=l2(0.001)))
model.add(Dense(10))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam' ,momentum=0.99)
history= model.fit(trainX, trainY,validation_split=0.33, nb_epoch=250, batch_size=32)
# Plot
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epochs')
plt.legend(['training', 'validation'], loc='upper right')
plt.show()
# make predictions
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
print(trainPredict)
numero_inputs=4
inp=numero_inputs-1
# Get something which has as many features as dataset
trainPredict_extended = numpy.zeros((len(trainPredict),numero_inputs+1))
# Put the predictions there
trainPredict_extended[:,inp+1] = trainPredict[:,0]
# Inverse transform it and select the 3rd column.
trainPredict = scaler.inverse_transform(trainPredict_extended)[:,inp+1]
# Get something which has as many features as dataset
testPredict_extended = numpy.zeros((len(testPredict),numero_inputs+1))
# Put the predictions there
testPredict_extended[:,inp+1] = testPredict[:,0]
# Inverse transform it and select the 3rd column.
testPredict = scaler.inverse_transform(testPredict_extended)[:,inp+1]
trainY_extended = numpy.zeros((len(trainY),numero_inputs+1))
trainY_extended[:,inp+1]=trainY
trainY=scaler.inverse_transform(trainY_extended)[:,inp+1]
testY_extended = numpy.zeros((len(testY),numero_inputs+1))
testY_extended[:,inp+1]=testY
testY=scaler.inverse_transform(testY_extended)[:,inp+1]
# Calcular error medio cuadratico
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))
# add train predictions to the plot
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, 0] = trainPredict
# add test predictions to the plot
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, 0] = testPredict
# Plot real data and training and test predictions
serie,=plt.plot(scaler.inverse_transform(dataset)[:,numero_inputs]) #invierto muestras en formato (0,1) a valores reales y los ploteo
entrenamiento,=plt.plot(trainPredictPlot[:,0],linestyle='--') #ploteo las predicciones de entrenamiento
prediccion_test,=plt.plot(testPredictPlot[:,0],linestyle='--')
plt.ylabel(' (m3)')
plt.xlabel('h')
plt.legend([serie,entrenamiento,prediccion_test],['Time series','Training','Prediction'], loc='upper right')
plt.show()
Любые идеи о том, как я могу решить эту проблему? Или хотя бы в чем проблема?
ВВОДЫ ПО КОЛОННЕ:
- Время суток (каждые полчаса), преобразованное в десятичное число.
- День недели (1-понедельник...7-воскресенье)
- Месяц года (1-12)
- День месяца (1-31)
ВЫХОД:
- Перекачиваемая вода (м3)
РЕДАКТИРОВАНИЕ Используя код @a_guest и изменяя некоторые параметры, такие как количество эпох или значение history
, результаты действительно хороши:
LSTM
содержит 6 нейронов, аDense
состоит из10
. Более того - у вас всего шесть единиц для анализа истории. Я бы сначала попытался увеличить количество узлов в слоеLSTM
, скажем, до40
. - person Marcin Możejko   schedule 14.03.2017look_back
для1
, что означает, что вы пытаетесь предсказать значение только на основе предыдущего значения (?). Вероятно, вам следует увеличить количество учитываемых точек данных. Также обратите внимание, что ваши данные, вероятно, демонстрируют разную сезонность с разной периодичностью (суточный цикл (больше воды в день) + годовой цикл (больше воды летом)). Чтобы узнать годовой цикл, вам нужно гораздо больше данных. IMO для прогноза вы должны охватить как минимум последние 48 часов (чтобы сеть уже видела этот шаблон хотя бы один раз). - person a_guest   schedule 14.03.2017