Я пытаюсь предсказать завтрашнюю дневную температуру. Из Google я собрал модель LSTM, так как она кажется более точной. Дело здесь не в значении, которое она предсказывает, а в возможности повторного использования модели и прогнозирования на будущее, так как я хочу тренироваться как один сервис, а прогноз - как другой.
Вот код для обучения модели:
rcParams['figure.figsize'] = 20,10
scaler = MinMaxScaler(feature_range=(0, 1))
sql_conn = pyodbc.connect(connStr)
query = 'SELECT Date, Temp FROM temps ORDER BY [Date] ASC'
df = pd.read_sql(query, sql_conn)
print(df.head(3))
totalRows = df["Date"].count()
trainRows = int(totalRows * 0.70)
#creating dataframe
data = df.sort_index(ascending=True, axis=0)
new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Temp'])
for i in range(0,len(data)):
new_data['Date'][i] = data['Date'][i]
new_data['Temp'][i] = data['Temp'][i]
#setting index
new_data.index = new_data.Date
new_data.drop('Date', axis=1, inplace=True)
#creating train and test sets
dataset = new_data.values
train = dataset[0:trainRows,:]
valid = dataset[trainRows:,:]
#converting dataset into x_train and y_train
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(dataset)
x_train, y_train = [], []
for i in range(60,len(train)):
x_train.append(scaled_data[i-60:i,0])
y_train.append(scaled_data[i,0])
x_train, y_train = np.array(x_train), np.array(y_train)
x_train = np.reshape(x_train, (x_train.shape[0],x_train.shape[1],1))
# create and fit the LSTM network
model = Sequential()
model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape[1],1)))
model.add(LSTM(units=50))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(x_train, y_train, epochs=1, batch_size=1, verbose=2)
# serialize model to JSON
model_json = model.to_json()
with open("temp.json", "w") as json_file:
json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("temp.h5")
print("Saved model to disk")
#predicting 246 values, using past 60 from the train data
inputs = new_data[len(new_data) - len(valid) - 60:].values
inputs = inputs.reshape(-1,1)
inputs = scaler.transform(inputs)
X_test = []
for i in range(60,inputs.shape[0]):
X_test.append(inputs[i-60:i,0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[1],1))
temp = model.predict(X_test)
temp = scaler.inverse_transform(temp)
rms = np.sqrt(np.mean(np.power((valid-temp),2)))
print("RMS = " + str(rms))
train = new_data[:trainRows]
valid = new_data[trainRows:]
valid['Predictions'] = temp
plt.plot(train['Temp'])
plt.plot(valid[['Temp','Predictions']])
plt.savefig('temp.png')
Это дает необходимые файлы модели и хороший файл png, чтобы быстро увидеть, как проходило обучение.
Часть прогнозирования должна быть довольно простой: загрузить последние 60 точек данных, загрузить модель, сделать прогноз. Но как мне преобразовать загруженную панду в model.predict?
sql_conn = pyodbc.connect(connStr)
query = 'SELECT TOP(60) Date, Temp FROM Temps ORDER BY [Date] DESC'
df = pd.read_sql(query, sql_conn)
json_file = open("temp.json", "r")
loaded_json = json_file.read()
json_file.close()
model = model_from_json(loaded_json)
model.load_weights("temp.h5")
model.compile(loss='mean_squared_error', optimizer='adam')
# how do I get to temp = model.predict(?)
Если я попытаюсь просто выбросить значения Temp в массив и выполнить прогнозирование, я получу массив:
x = []
for d in df['Temp']:
x.append(d)
prediction = model.predict(x)
Ошибка: ожидалось, что lstm_3_input будет иметь 3 измерения, но получил массив с формой (60, 1)
Я должен преобразовать свои значения?