基于keras实现线性回归模型,多步预测问题实质上是多输入单输出的神经网络模型
最近实验中由于自己之前没有学习过tensorflow、pytorch等,无论是自己的实验代码还是对比方法的复现都一头雾水,此篇博客简单记录一下实验的一个小模块线性回归的实现,我的需求是对于输入的训练数据(多维数据)的每一维数据分别用其历史的多步时间数据去预测下个时间戳的数据,并将每一维数据训练所得的模型保存。以下是具体的代码:
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
import pandas as pd
import scipy as sp
from sklearn.metrics import mean_squared_error,mean_absolute_error
# 滑动窗口的实现
def seq2instance(data, P, Q):
num_step = len(data)
num_sample = num_step - P - Q + 1
x = np.zeros(shape = (num_sample, P))
y = np.zeros(shape = (num_sample, Q))
for i in range(num_sample):
x[i] = data[i : i + P]
y[i] = data[i + P : i + P + Q]
return x, y
# 线性回归实现
def LinearRegression(model_saver_path='/home/qjy/pythonProj/TP/Model/',
data_file='/home/qjy/pythonProj/TP/data/Trajectory.csv',
outputData_path='/home/qjy/pythonProj/TP/data/',
train_ratio=0.7, val_ratio=0.1, test_ratio=0.2, TIME_STEPS=10, INPUT_SIZE=200, LR_epochs=10, LR_batchSize=128):# default parameter
# Loading & processing data
col_dict = {'time_stamps': object}
for i in range(0, INPUT_SIZE):
col_dict[str(i)] = int
dataset = pd.read_csv(data_file + '', header=0, index_col=0, dtype=col_dict)
values = dataset.values
# Training set
train_step = int(values.shape[0] * train_ratio)
train = np.array(values[:train_step,:])
# validation set
valid_step = int(values.shape[0] * val_ratio)
valid = np.array(values[train_step:train_step + valid_step,:])
# test set
test_step = int(values.shape[0] * test_ratio)
test = np.array(values[-test_step:,:])
# timeStamps
idx = dataset.index.values[-test_step + TIME_STEPS:]
# save prediction
col_titles = []
col_titles.append('time_stamps')
for i in range(0, INPUT_SIZE):
col_titles.append(str(i))
df = pd.DataFrame(columns=col_titles)
df['time_stamps'] = idx
df.fillna(0, inplace=True)
# traverse all dims
for i in range(0, INPUT_SIZE):
# split into input and outputs
train_X, train_y = seq2instance(train[:,i], TIME_STEPS, 1)
train_y = np.squeeze(train_y)
valid_X, valid_y = seq2instance(valid[:,i], TIME_STEPS, 1)
valid_y = np.squeeze(valid_y)
test_X, test_y = seq2instance(test[:,i], TIME_STEPS, 1)
test_y = np.squeeze(test_y)
# build model
model = Sequential()
model.add(Dense(units=1, input_dim=TIME_STEPS, activation='sigmoid'))
# select loss function and optimizer
model.compile(loss='mae', optimizer='sgd', metrics=['accuracy'])
# train: epcoch, batch_size
model.fit(train_X, train_y, epochs=LR_epochs, batch_size=LR_batchSize, validation_data=(valid_X, valid_y), verbose=1, shuffle=True)
# model evaluate
score = model.evaluate(test_X, test_y, batch_size=LR_batchSize, verbose=1)
print(score)
# W, b = model.layers[0].get_weights()
# print('Weights=', W, '\n biases=', b)
# save model
model_file = model_saver_path + 'epoch' + str(LR_epochs) + '_batchSize' + str(LR_batchSize) \
+ '_windowSize' + str(TIME_STEPS) + '_model.h5'
model.save(model_file)
#predict
Y_pred = model.predict(test_X).astype(int)
# inverse transform of prediction
inv_yhat = np.concatenate(Y_pred)
# inverse transform of real value
inv_y = test_y
# metric
rmse = sp.sqrt(mean_squared_error(inv_y, inv_yhat))
print('The RMSE:', rmse)
mae = mean_absolute_error(inv_y, inv_yhat)
print('The MAE:', mae)
for t in range(0, len(idx)):
curTime = idx[t]
df.loc[df['time_stamps'] == curTime, str(i)] = inv_yhat[t]
outputData_file = outputData_path + 'LR_predResult.csv'
df.to_csv(outputData_file, index=False, header=True)
if __name__ == '__main__':
LinearRegression()