LSTM 应该是捕获时间序列数据中路径依赖性的正确工具。
我决定进行一个简单的实验(模拟)来评估 LSTM 能够在多大程度上更好地理解路径依赖。
设置非常简单。我只是模拟来自 4 个不同数据生成过程的一堆 (N=100) 路径。其中两个过程代表真实增加和真实减少,而另外两个假趋势最终恢复为零。
下图显示了每个类别的模拟路径:
候选机器学习算法将被给予路径的前 8 个值([1,8] 中的 t),并将被训练以预测最后 2 个步骤的后续运动。
换句话说:
特征向量为
X = (p1, p2, p3, p4, p5, p6, p7, p8)
目标是
y = p10 - p8
我将 LSTM 与具有 20 个估计器的简单随机森林模型进行了比较。以下是使用 Keras 和 scikit-learn 的两个模型的定义和训练:
# LSTM
model = Sequential()
model.add(LSTM((1), batch_input_shape=(None, H, 1), return_sequences=True))
model.add(LSTM((1), return_sequences=False))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
history = model.fit(train_X_LS, train_y_LS, epochs=100, validation_data=(vali_X_LS, vali_y_LS), verbose=0)
# Random Forest
RF = RandomForestRegressor(random_state=0, n_estimators=20)
RF.fit(train_X_RF, train_y_RF);
样本外结果总结为以下散点图:
正如您所看到的,随机森林模型明显优于 LSTM。后者似乎无法区分真实趋势和假趋势。
您有什么想法可以解释为什么会发生这种情况吗?
您将如何修改 LSTM 模型以使其更好地解决这个问题?
一些评论:
- 数据点除以 100 以确保梯度不会爆炸
- 我尝试增加样本量,但没有发现任何差异
- 我尝试增加 LSTM 训练的纪元数,但我发现没有差异(在一堆纪元后损失变得停滞)
- 你可以找到我用来运行实验的代码 here
更新:
感谢SaTa
的回复,我改变了模型并获得了更好的结果:
# Updated LSTM Model
model = Sequential()
model.add(LSTM((8), batch_input_shape=(None, H, 1), return_sequences=False))
model.add(Dense(4))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
不过,随机森林模型的表现更好。关键是 RF 似乎理解
,以类别为条件,较高的 p8
预测较低的结果 p10-p8
,反之亦然,因为添加噪声的方式。 LSTM 似乎在这方面失败了,因此它对类别的预测相当好,但我们在最终的散点图中看到了类别内向下倾斜的模式。
有什么改进建议吗?
最佳答案
我并不指望 LSTM 在与传统方法的所有战斗中获胜,但我确实希望它能够很好地解决您提出的问题。您可以尝试以下几件事:
1)增加第一层隐藏单元的数量。
model.add(LSTM((32), batch_input_shape=(None, H, 1), return_sequences=True))
2) LSTM 层的输出默认为 tanh,这将输出限制为 (-1, 1),如右图所示。我建议添加一个 Dense 层或使用 LSTM 在输出上进行线性激活。像这样:
model.add(LSTM((1), return_sequences=False, activation='linear'))
或者
model.add(LSTM((16), return_sequences=False))
model.add(Dense(1))
使用您拥有的 10K 样本尝试上述操作。
关于python - 实验表明 LSTM 的性能比随机森林差……为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54597093/