时间序列 - 模型似乎没有学习

数据挖掘 机器学习 深度学习 神经网络 时间序列
2022-02-16 21:27:45

我正在写关于时间序列预测的本科论文,并使用各种模型(线性/岭回归、AR(2)、随机森林、SVR 和 4 种神经网络变体)来尝试和“预测”(仅出于学术原因)每日回报数据,使用滞后回报和基于这些回报构建的 SMA - RSI 特征(使用 TA - Lib)作为输入。但是,我注意到我的 NN 没有学到任何东西,并且在检查损失图和预测向量时,我注意到它只预测一个值,对于 Ridge 和 AR 回归同样适用。

此外,当我尝试计算标签和(NN 的)预测之间的相关性时,无论我尝试什么,我都会得到“nan”,我怀疑这与预测有关。每次重新运行时,我的 r2 分数也会大不相同(即使我在 Tensorflow 后端和 numpy 上设置了多个种子)并且总是负数,即使我在互联网上搜索和 sklearn 的文档,我也无法理解说它可能是负面的,我的教授坚持认为不可能,我真的很困惑。

我能做些什么呢?整个 NN 只预测一个值不是很明显是错误的吗?下面我包括 ridge / AR 回归的代码以及“Vanilla NN”和一些有用的图表。数据本身非常大,所以如果没有特别要求,我不知道是否有很多意义包含它,因为下面没有算法错误。

def vanillaNN(X_train, y_train,X_test,y_test):
    n_cols = X_train.shape[1]
    model = Sequential()
    model.add(Dense(100,activation='relu', input_shape=(n_cols, )))
    model.add(Dropout(0.3))
    model.add(Dense(150, activation='relu'))
    model.add(Dense(50, activation='relu'))
    model.add(Dropout(0.1))
    model.add(Dense(1))

    model.compile(optimizer='adam', loss='mse', metrics=['mse'])

    history = model.fit(X_train,y_train,epochs=100,verbose=0,
        shuffle=False, validation_split=0.1)  

    # Use the last loss as the title
    plt.plot(history.history['loss'])
    plt.title('last loss:' + str(round(history.history['loss'][-1], 6)))
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.show()

    # Calculate R^2 score and MSE
    # .... Omitted Code ......

    # it returns those for testing purposes in the IPython shell
    return (train_scores, test_scores, y_pred_train, y_pred_test, y_train, y_test)
    VNN_results = vanillaNN(
        train_features,train_targets,
        test_features,test_targets)

神经网络损失历史 - 100 个时期

def AR(X_train, order=2):
    arma_train = np.array(X_train['returns'])
    armodel = ARMA(arma_train, order=(order,0))
    armodel_results = armodel.fit()
    print(armodel_results.summary())
    armodel_results.plot_predict(start=8670, end=8698)
    plt.show()
    ar_pred = armodel_results.predict(start=8699, end=9665)

    # ...r2 and MSE scores omitted code...

    return [mse_ar2, r2_ar2, ar_pred]

AR(2) 模型外样本预测

def Elastic(X_train, y_train, X_test, y_test):
    elastic = ElasticNet()
    param_grid_elastic = {'alpha': [0.001,  0.01, 0.1, 0.5],
        'l1_ratio': [0.001, 0.01, 0.1, 0.5]
                              }
    grid_elastic = GridSearchCV(elastic, param_grid_elastic, 
        cv=tscv.split(X_train),scoring='neg_mean_squared_error')

    grid_elastic.fit(X_train, y_train)

    y_pred_train = grid_elastic.predict(X_train) 
    train_scores = scores(y_train, y_pred_train)

    y_pred_test = grid_elastic.predict(X_test)

    # ...Omitted Code...
    return [train_scores, test_scores, y_pred_train, y_pred_test]

AR(2) 样本测试和训练预测: 测试集预测 训练集预测

SAMPLE DATA: Train features and Train Targets (future_returns) 

看起来一团糟,但只需将粘贴复制到 excel 文件中就可以了!)

返回日期MA14 MA30 rsi14 rsi30 MA50 MA200 rsi50 rsi200 future_returns 1980年10月14日3.49E-05 42.76324407 49.21625218 66.6250545 49.69881565 49.45368438 49.93538688 37.78942977 50.51223405 0.013277481 1980年10月15日0.013277481 0.239711734 53.45799196 0.16387242 51.78260494 0.140801819 51.19194274 0.10545251 50.79944024 -0.011855382 1980年10月16日-0.011855382 -0.306338818 45.66265303 -0.159676722 47.88773425 -0.115851283 48.81901884 -0.107808537 50.24325364 -0.00414208 1980年10月17日-0.00414208 -1.154286743 48.16105108 -0.451328445 49.1031414 -0.3083074 49.55134428 -0.299669528 50.4107189 0.007939494 1980年10月20日0.007939494 0.548806765 51.89223141 0.338253188 50.95654204 0.15403304 50.679274 0.145277255 50.67207082 -0.0050544 10/21/1980 -0.0050544 -0.580692978 47.89906352 -0.443621598 48。97241743 -0.250429072 49.46553614 -0.227539737 50.38503757 -2.93E-05 1980年10月22日-2.93E-05 -85.38681662 49.51695915 -69.94007273 49.7551065 -46.09189634 49.93866124 -37.61970911 50.49403171 -0.018135363 1980年10月23日-0.018135363 -0.020087358 44.19203763 -0.067897836 47.0643223 - 0.037135977 48.27685366 -0.05615813 50.09551572 0.000415381 1980年10月24日0.000415381 -2.422576075 50.11149401 3.125882141 49.93407273 1.480210269 50.01580668 2.418672772 50.49781053 -0.013535864 1980年10月27日-0.013535864 0.12834969 46.14718747 -0.056014904 47.91325905 -0.053384853 48.75782925 -0.065375964 50.19198915 0.00337859 1980年10月28日0.00337859 -0.566993349 51.18890074 0.168834456 50.4293269 0.275579337 50.30416736 0.265200747 50.55684672 -0.003396646 1980年10月29日-0.003396646 0.522213275 49.20187924 0.045438303 49。43972414 -0.207144904 49.69125655 -0.266487054 50.40819543 -0.011421006一九八○年十月三十〇日-0.011421006 0.185961701 46.88078737 0.029632441 48.27895767 -0.018832701 48.97017418 -0.073584097 50.23238873 0.013350935 1980年10月31日0.013350935 -0.156079209 54.08231943 -0.003988301 51.88647852 0.031510014 51.2008709 0.064478565 50.76515097 0.01758565 1980年11月3日0.01758565 -0.047207787 55.20045808 0.011243586 52.47271385 0.048876357 51.57016088 0.055301429 50.85553721 0.025052611 1980年11月5日0.025052611 0.000435129 57.18044487 0.053812694 53.50605621 0.05421219 52.22072289 0.039977524 51.01490125 -0.017722306 1980年11月6日-0.017722306 0.023031138 44.92992843 -0.03124573 47.39891281 -0.070442975 48.41875471 -0.050855544 50.07992286 0.000581639 1980年11月7日0.000581639 -0.121650134 49.87840955 1.580058713 49.92880444 2。604518867 50.0080164 1.580277943 50.47031631 0.002508371 1980年11月10日0.002508371 -0.182865195 50.38381628 0.640792927 50.18967587 0.608670831 50.17291603 0.34700777 50.51126003 0.012129939一九八〇年十一月一十一日0.012129939 0.063376989 52.93601236 0.221445976 51.49515928 0.145866445 50.99656886 0.079352102 50.71573089 0.024926655

1个回答

感谢您提供示例数据。我真的不认为有任何严重的问题可以确定问题的确切原因,但我可以给你一些改进的建议,这可能会有所帮助。

标准化和缩放

您的某些功能具有较大的值,而某些功能具有较小的值。如果您不对特征和目标进行标准化和缩放,则会导致 NN 内部的“不平衡”权重,从而导致模型不稳定。因此,在将数据拆分为训练数据集和测试数据集后,可以使用StandardScaler之类的工具对其进行标准化和缩放。

激活功能

尝试使用不同的激活函数总是值得的。与其他激活函数相比,ReLu 非常简单且计算成本低,但在糟糕的设置中,它会导致许多神经元死亡。所以我建议尝试其他激活函数,如 Tanh 或 Leaky Relu。注意:这并不意味着 ReLu 是一个糟糕的激活函数。由于许多原因,它实际上是一个非常受欢迎的。

学习率

特别是如果您坚持使用 ReLu,请检查如果您降低学习率和/或设置学习率衰减会产生什么不同。

神经网络架构

由于您使用的是时间序列,因此使用为GRULSTM等时间序列数据设计的循环神经网络是有意义的

其他

防止您落入与我相同的陷阱的一个附注:如果您使用 TA-Lib,请在计算任何特征之前缩放您的值。如果输入值太小,TA-Lib 的 Github 上有一个未解决的问题会计算错误的特征。我看到你的目标也有相当小的值,所以也许要注意这一点。