使用Keras进行LSTM预测

我正在根据过去的X值预测Y。我们格式化的CSV数据集有三列(时间戳、X和Y – 其中Y是实际值),其样本格式如下:

time,X,Y0.000561,0,100.000584,0,100.040411,5,100.040437,10,100.041638,12,100.041668,14,100.041895,15,100.041906,19,10 ... ... ...

在训练预测模型之前,以下是X和Y的图表分别呈现的效果。

enter image description here

enter image description here

以下是我使用Keras在Python中通过LSTM循环神经网络解决这个问题的步骤。

import numpy as npfrom keras.models import Sequentialfrom keras.layers import LSTM, Densefrom sklearn.preprocessing import MinMaxScalerimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.metrics import mean_squared_errornp.random.seed(7)# 加载数据df = pd.read_csv('test32_C_data.csv')n_features = 100def create_sequences(data, window=15, step=1, prediction_distance=15):    x = []    y = []    for i in range(0, len(data) - window - prediction_distance, step):        x.append(data[i:i + window])        y.append(data[i + window + prediction_distance][1])    x, y = np.asarray(x), np.asarray(y)    return x, y# 在分割前进行缩放scaler = MinMaxScaler(feature_range=(0.01, 0.99))scaled_data = scaler.fit_transform(df.loc[:, ["X", "Y"]].values)# 构建序列x_sequence, y_sequence = create_sequences(scaled_data)# 创建测试/训练分割test_len = int(len(x_sequence) * 0.90)valid_len = int(len(x_sequence) * 0.90)train_end = len(x_sequence) - (test_len + valid_len)x_train, y_train = x_sequence[:train_end], y_sequence[:train_end]x_valid, y_valid = x_sequence[train_end:train_end + valid_len], y_sequence[train_end:train_end + valid_len]x_test, y_test = x_sequence[train_end + valid_len:], y_sequence[train_end + valid_len:]# 初始化RNNmodel = Sequential()# 添加输入层和LSTM层model.add(LSTM(15, input_shape=(15, 2)))# 添加输出层model.add(Dense(1))# 编译RNNmodel.compile(loss='mse', optimizer='rmsprop')# 训练RNNmodel.fit(x_train, y_train, epochs=5)# 获取预测值y_pred = model.predict(x_test)#y_pred = scaler.inverse_transform(y_pred)plot_colors = ['#332288', '#3cb44b']# 绘制结果pd.DataFrame({"实际值": y_test, "预测值": np.squeeze(y_pred)}).plot(color=plot_colors)plt.xlabel('时间[索引]')plt.ylabel('值')

最后,当我运行代码时,神经模型似乎很好地捕捉到了信号的模式,如下图所示。

enter image description here

然而,我在这个输出中遇到的问题是Y的范围。正如前两个图表所示,范围应该是0-400,如上所示。为了解决这个问题,我尝试使用scaler进行inverse_transform,如y_pred = scaler.inverse_transform(y_pred),但这会抛出错误:ValueError: non-broadcastable output operand with shape (7625,1) doesn't match the broadcast shape (7625,2)。我们如何解决这个broadcast shape错误?


回答:

基本上,scaler记住了它被输入了2个特征(/列)。所以它期望有2个特征来反转变换。

这里有两个选项。

1) 你可以创建两个不同的scaler:scaler_xscaler_y,如下所示:

# 在分割前进行缩放scaler_x = MinMaxScaler(feature_range=(0.01, 0.99))scaler_y = MinMaxScaler(feature_range=(0.01, 0.99))scaled_x = scaler_x.fit_transform(df.loc[:, "X"].reshape([-1, 1]))scaled_y = scaler_y.fit_transform(df.loc[:, "Y"].reshape([-1, 1]))scaled_data = np.column_stack((scaled_x, scaled_y))

然后你就可以这样做:

y_pred = scaler_y.inverse_transform(y_pred)

2) 你可以在输出中伪造X列,如下所示:

y_pred_reshaped = np.zeros((len(y_pred), 2))y_pred_reshaped[:,1] = y_predy_pred = scaler.inverse_transform(y_pred_reshaped)[:,1]

这有帮助吗?

编辑

这里是所需的完整代码

import numpy as npfrom keras.models import Sequentialfrom keras.layers import LSTM, Densefrom sklearn.preprocessing import MinMaxScalerimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.metrics import mean_squared_errornp.random.seed(7)# 加载数据#df = pd.read_csv('test32_C_data.csv')df = pd.DataFrame(np.random.randint(0,100, size=(100,3)), columns = ['time', 'X', 'Y'])n_features = 100def create_sequences(data, window=15, step=1, prediction_distance=15):    x = []    y = []    for i in range(0, len(data) - window - prediction_distance, step):        x.append(data[i:i + window])        y.append(data[i + window + prediction_distance][1])    x, y = np.asarray(x), np.asarray(y)    return x, y# 在分割前进行缩放scaler_x = MinMaxScaler(feature_range=(0.01, 0.99))scaler_y = MinMaxScaler(feature_range=(0.01, 0.99))scaled_x = scaler_x.fit_transform(df.loc[:, "X"].reshape([-1,1]))scaled_y = scaler_y.fit_transform(df.loc[:, "Y"].reshape([-1,1]))scaled_data = np.column_stack((scaled_x, scaled_y))# 构建序列x_sequence, y_sequence = create_sequences(scaled_data)test_len = int(len(x_sequence) * 0.90)valid_len = int(len(x_sequence) * 0.90)train_end = len(x_sequence) - (test_len + valid_len)x_train, y_train = x_sequence[:train_end], y_sequence[:train_end]x_valid, y_valid = x_sequence[train_end:train_end + valid_len], y_sequence[train_end:train_end + valid_len]x_test, y_test = x_sequence[train_end + valid_len:], y_sequence[train_end + valid_len:]# 初始化RNNmodel = Sequential()# 添加输入层和LSTM层model.add(LSTM(15, input_shape=(15, 2)))# 添加输出层model.add(Dense(1))# 编译RNNmodel.compile(loss='mse', optimizer='rmsprop')# 训练RNNmodel.fit(x_train, y_train, epochs=5)# 获取预测值y_pred = model.predict(x_test)y_pred = scaler_y.inverse_transform(y_pred)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注