(13-4)黄金价格预测系统:构建机器学习模型

文章描述了一个使用LGBMRegressor进行金价预测的方法,通过特征工程生成滞后期、滚动统计和L-矩等特征,然后进行超参数调优。通过预测Low和High列的实例,展示模型性能和交易策略评估,包括均方误差和均方根误差等指标。
摘要由CSDN通过智能技术生成

13.4  机器学习模型

在本项目中,选择使用LGBMRegressor作为预测价格的机器学习模型,并使用verstack进行调优处理。

(1)函数prediction 用于预测金价,并评估预测性能。首先,它创建一个数据集 data,包含目标列(col)的原始数据。然后,通过调用 Prepare_Data 函数,为目标列添加了滞后期、滚动统计和L-矩等特征。接着,对 'Open'、'Close'、'Volume' 以及与目标列互补的 'Low' 或 'High' 列进行同样的特征工程,最后将所有数据集合并成一个完整的数据集。随后,删除了因为滞后期特征引起的缺失值。接下来,定义训练数据并使用 LGBMTuner 进行超参数调整,最后对数据的最后90天进行预测,并输出预测结果、评估指标和模型调整的超参数。该函数可用于实现金价的时间序列预测和交易策略的评估。

def prediction(Data, col, Lag_list, Roll_window, Lmoment_window):

    data = pd.DataFrame({col: Data[col]}, index=Data.index)
    
    # 准备要预测的目标列
    data = Prepare_Data(data, col, Lag_list, Roll_window, Lmoment_window)
    
    # 这三列及其新特征添加到最终数据集,无论目标列是什么。
    Open = Prepare_Data(pd.DataFrame(Gold['Open']), 'Open', Lag_list, Roll_window, Lmoment_window)
    Close = Prepare_Data(pd.DataFrame(Gold['Close']), 'Close', Lag_list, Roll_window, Lmoment_window)
    Volume = Prepare_Data(pd.DataFrame(Gold['Volume']), 'Volume', Lag_list, Roll_window, Lmoment_window)
    
    # 由于创建包含所有特征的完整数据集,如果目标是 "High",我们添加 Low 特征,反之亦然。
    if col == 'High':
        df = Prepare_Data(pd.DataFrame(Gold['Low']), 'Low', Lag_list, Roll_window, Lmoment_window)
        
    elif col == 'Low':
        df = Prepare_Data(pd.DataFrame(Gold['High']), 'High', Lag_list, Roll_window, Lmoment_window)
        
    # 现在我们将上面创建的所有数据集合并在一起,以获得完整的数据集
    data = pd.concat([Open, Close, Volume, df, data], axis=1)
    
    # 由于使用滞后期会导致存在缺失值的行,因此将这些行删除
    tail = data.shape[0] - max(Roll_window, len(Lag_list))
    data = data.tail(tail)
    
    # 定义训练数据
    X = data.values[:-90, :-1]
    Y = data.values[:-90, -1]

    # 使用 LGBMTuner 进行超参数调整
    tuner = LGBMTuner(metric='rmse', trials=50)  # <- the only required argument

    # 调整器需要 X 和 Y 的这些数据类型
    X = pd.DataFrame(X)
    Y = pd.Series(Y)
    
    # 拟合调整后的模型并对数据的最后90天进行预测
    tuner.fit(X, Y)
    x_test = data.values[-90:, :-1]
    x_test = pd.DataFrame(x_test)
    predict = tuner.predict(x_test)
    
    y_test = pd.Series(data.values[-90:, -1])
    
    mae = mean_absolute_error(y_test, predict)
    rmse = sqrt(mean_squared_error(y_test, predict))
    
    """以下两者的差异最小,是最佳情况,表明预测准确,交易策略可行。"""
    
    diff_low = [] 
    if col == 'Low':
        
        for i in range(len(predict)):
            
            diff = predict[i] - y_test[i]
        
            diff_low.append(diff)
            
        print ('Mean:', mean(diff_low), 'Variance:', statistics.variance(diff_low))

            
    diff_high = [] 
    if col == 'High':
        
        for i in range(len(predict)):
            
            diff =  y_test[i] - predict[i]
        
            diff_high.append(diff)
        
        print ('Mean:', mean(diff_high), 'Variance:', statistics.variance(diff_high))
    
    print('MAE: %f' % mae)
    print('RMSE: %f' % rmse)
    print('======Summary======')
    print('Lag_list:', '===>', Lag_list)
    print('Roll_window:', '===>', Roll_window)
    print('Lmoment_window:', '===>', Lmoment_window)
    print('==============================')
    print('predict:\n', ['%.1f' % y for y in predict])
    print('Actual:\n', y_test.tolist())

    return predict.tolist(), y_test.tolist()

(2)调用上面定义的函数 prediction,对金价数据中的 'Low' 列进行预测。使用滞后期列表 [2, 3, 4, 5],滚动窗口大小为 2,L-矩计算窗口大小为 5 进行特征工程。

low_prediction = prediction(Gold,'Low',[i for i in range(2,6)],2,5)

执行后返回了对 'Low' 列的预测结果、实际值以及评估指标(均方误差、均方根误差等),这个过程有助于了解模型在 'Low' 列上的预测性能和交易策略评估。执行后会输出:

* Initiating LGBMTuner.fit
     . Settings:
     .. Trying 50 trials
     .. Evaluation metric: rmse 
     .. Study direction: minimize rmse

     . Trial number: 0 finished
     .. Optimization score (lower-better): rmse: 5.998330355838334
 ...........................................................................
     . Trial number: 1 finished
     .. Optimization score (lower-better): rmse: 6.626333981231204
 ...........................................................................
     . Trial number: 2 finished
     .. Optimization score (lower-better): rmse: 6.065461698552595
 ...........................................................................
     . Trial number: 3 finished
     .. Optimization score (lower-better): rmse: 7.588808362697567
 ...........................................................................
     . Trial number: 4 finished
     .. Optimization score (lower-better): rmse: 6.333486651352738
 ...........................................................................
     . Trial number: 20 finished
     .. Optimization score (lower-better): rmse: 5.995384306717045
 ...........................................................................
     . Trial number: 23 finished
     .. Optimization score (lower-better): rmse: 6.184332265001647
 ...........................................................................

   - Tune n_estimators with early_stopping
Training until validation scores don't improve for 200 rounds
[100]	train's lgb_rmse: 183.879	valid's lgb_rmse: 184.244
[200]	train's lgb_rmse: 67.4405	valid's lgb_rmse: 67.6122
[300]	train's lgb_rmse: 24.9382	valid's lgb_rmse: 25.3642
[400]	train's lgb_rmse: 9.60396	valid's lgb_rmse: 10.9218
[500]	train's lgb_rmse: 4.33871	valid's lgb_rmse: 7.03234
[600]	train's lgb_rmse: 2.70026	valid's lgb_rmse: 6.33645
[700]	train's lgb_rmse: 2.14305	valid's lgb_rmse: 6.24522
[800]	train's lgb_rmse: 1.85119	valid's lgb_rmse: 6.22872
[900]	train's lgb_rmse: 1.64197	valid's lgb_rmse: 6.22763
[1000]	train's lgb_rmse: 1.48015	valid's lgb_rmse: 6.23446
Early stopping, best iteration is:
[857]	train's lgb_rmse: 1.72606	valid's lgb_rmse: 6.22481

   - Fitting optimized model with the follwing params:
learning_rate                    : 0.01
num_leaves                       : 252
colsample_bytree                 : 0.9442916144154508
subsample                        : 0.7802802926046664
verbosity                        : -1
random_state                     : 42
objective                        : regression
metric                           : rmse
num_threads                      : 2
reg_alpha                        : 0.0030242975914927706
min_sum_hessian_in_leaf          : 1.4637072426767108
reg_lambda                       : 4.869621409735013e-06
n_estimators                     : 857

另外,还会绘制出对应的可视化图,如图7-8所示。

优化历史图

超参数重要性图

中间值曲线图

功能重要性统计图(总计1)

图7-8   'Low' 列的模型预测可视化图

另外,还会输出展示了 LGBMTuner 在超参数优化过程中的相关信息,包括 Optuna 优化结束后的最佳试验号、最佳迭代次数、RMSE 等信息。接下来,输出了预测结果和实际值,并计算了 MAE(平均绝对误差)和 RMSE(均方根误差)。在 'Low' 列的情况下,还输出了差异的均值和方差。

总之,这些输出信息提供了对模型预测结果和性能评估的全面概览,对于评估模型性能和调整参数提供了重要参考。整

(3)请看下面的这段代码,使用 Matplotlib 绘制了 'Low' 列的预测值(蓝色虚线)和实际值(橙色实心点)曲线图。首先,通过 data[-90:].index 获取最后90天的日期索引,然后通过 pd.DataFrame(Gold.index[-90:]).values 将其转换为 DataFrame 格式。接下来,使用 plt.plot() 分别绘制预测值和实际值,并通过 plt.xticks(rotation=90) 使 x 轴标签旋转90度以提高可读性。最后,通过 plt.legend() 添加图例,通过 plt.show() 显示图表。

x = data[-90:].index
x = pd.DataFrame(Gold.index[-90:]).values
# plot Low prediction and actual price
plt.plot(x, low_prediction[0],'--bo', label = "predict",linestyle = 'dashed')
plt.plot(x, low_prediction[1],marker='o', label = "Actual")
plt.xticks(rotation = 90)
plt.legend()
plt.show()

执行效果如图7-8所示,这个图有助于直观地比较模型的预测结果与实际情况。

图7-8  'Low' 列的预测值(蓝色虚线)和实际值(橙色实心点)曲线图

(3)调用函数prediction,对金价数据中的 'High' 列进行预测。使用滞后期列表 [2, 3, 4, 5],滚动窗口大小为 2,L-矩计算窗口大小为 5 进行特征工程。函数返回了对 'High' 列的预测结果、实际值以及评估指标(均方误差、均方根误差等)。此过程有助于了解模型在 'High' 列上的预测性能和交易策略评估。

high_prediction = prediction(Gold,'High',[i for i in range(2,6)],2,5)

上面的代码类似于前面对 'Low' 列的预测代码,会执行 函数prediction对 'High' 列进行预测时,也会输出与模型性能相关的信息,包括 Optuna 优化结果、MAE、RMSE、差异均值和方差等。同时,预测结果和实际值的可视化图表也会被绘制,以便直观地比较模型的预测效果。如图7-8所示。

优化历史图

超参数重要性图

中间值曲线图

功能重要性统计图(总计1)

图7-8  'High'列的模型预测可视化图

这种输出和可视化的方式有助于全面评估模型在不同列上的表现,为金价预测和交易策略的分析提供参考。

(4)使用Matplotlib 绘制'High' 列的预测值(蓝色虚线)和实际值(橙色实心点)的时间序列图。通过 plt.plot() 分别绘制了预测值和实际值,并通过 plt.xticks(rotation=90) 使 x 轴标签旋转90度以提高可读性。最后,通过 plt.legend() 添加图例,通过 plt.show() 显示图表。

plt.plot(x, high_prediction[0],'--bo', label = "predict",linestyle = 'dashed')
plt.plot(x, high_prediction[1],marker='o', label = "Actual")
plt.xticks(rotation = 90)
plt.legend()
plt.show()

执行效果如图7-8所示,这个可视化图直观地展示了模型对 'High' 列的预测效果,方便比较预测结果与实际情况。

图7-8  'High' 列的预测值和实际值的时间序列图

未完待续

  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值