使用 PyCaret 预测黄金价格崩盘
上次更新时间
这有帮助吗?
上次更新时间
这有帮助吗?
在这一部分,我们将尝试预测黄金价格在未来 22 天内是否会发生“急剧下跌”或“崩盘”。我们将使用分类技术进行此实验。我们还将学习如何使用训练好的模型每天对新数据进行预测。本练习的步骤将是:
定义 “急剧下跌” 在黄金价格中。“急剧”不是一个绝对衡量标准。我们将尝试客观地定义 “急剧下跌”
创建标签 — 根据 “急剧下跌” 的定义,我们将在历史数据上创建标签
训练模型预测 “急剧下跌” 并使用训练好的模型对新数据进行预测
任何分类问题都需要标签。在这里,我们需要通过定义和量化 “急剧下跌” 来创建标签。
为了定义“急剧”,我定义了一个阈值,使得在任何窗口(此处为 22 天,此处为 14 天)内收益低于该阈值的概率为 15%(基本上是正态分布左尾,p=0.15)。为此,我需要假设收益分布是正态分布。从收益分布来看,这是一个非常合理的假设。
为了得出两个窗口(14 天和 22 天)的阈值收益水平,我首先会定义分布左尾的 p 值,在此案例中为 15%。使用此 p 值,我们从标准正态分布中获得 z 值为 -1.0364。以下代码将为我们完成此操作。
现在,基于上述 z 值和每个窗口的收益均值和标准差,我们将获得阈值收益水平。数据中“Gold-T+14”和“Gold-T+22”列显示了 14 天和 22 天期限的远期收益。
因此,14 天窗口的阈值收益水平为 -0.0373 或 -3.73%,22 天窗口的阈值收益水平为 -0.0463 或 -4.63%。这意味着,14 天收益低于 -3.73% 的概率只有 15%,22 天收益低于 -4.63% 的概率也只有 15%。这与计算风险价值 (VAR) 中使用的概念相似。
我们将使用上述阈值水平创建标签。两个窗口中任何低于各自阈值的收益都将标记为 1,否则标记为 0。
在总共 2,379 个实例中,有 338 个实例的 14 天收益低于 -3.73% 的阈值,有 356 个实例的 22 天收益低于 -4.63% 的阈值。
一旦我们有了这些标签,我们实际上就不需要收益列了,因此我们删除实际的收益列。
我们将从这里的 22 天窗口开始。我将在这里使用 PyCaret 的分类模块进行实验。
我们从 PyCaret 中导入上述模块,然后删除 14 天的标签,因为我们正在处理 22 天窗口。就像回归一样,要开始分类实验,我们需要运行 setup() 命令来指定数据和目标列。请记住,所有基本的预处理都由 PyCaret 在后台处理。
为了评估所有模型集,我们将运行 *compare_models() *命令,并将 turbo 设置为 False,因为我想评估库中当前可用的所有模型。
在继续选择模型之前,我们需要了解哪个指标对我们最有价值。在分类实验中选择哪个指标取决于业务问题。精确度 (Precision) 和召回率 (Recall) 之间总是存在权衡。这意味着我们必须在真阳性 (True Positives) 和假阴性 (False Negatives) 之间选择并倾向于一个平衡。
在这里,最终模型将用于创建一个标记,警告投资者/分析师可能即将发生崩盘。然后,投资者将决定对冲其头寸以防范可能的下跌。因此,模型能够预测所有/大多数剧烈下跌至关重要。换句话说,我们希望选择一个具有更好能力获得真阳性(更好的召回率)的模型,即使这会带来一些假阳性(较低的精确度)的代价。换句话说,我们不希望模型错过 “急剧下跌” 的可能性。我们可以承受一些假阳性,因为如果模型预测会有急剧下跌,并且投资者对冲了他的头寸,但下跌没有发生,投资者会损失剩余投资的机会成本或最多损失对冲成本(比如他购买了价外看跌期权)。这个成本会低于假阴性的成本,即模型预测没有 “急剧下跌”,但却发生了大幅下跌。然而,我们需要关注 精确度 (Precision) 和 AUC 的权衡。
我们将继续创建四个模型,即 MLP 分类器 (mlp)、Extra-Tree 分类器 (et)、Cat Boost 分类器 (catb) 和 Light Gradient Boosting Machine (lgbm),它们具有最佳的 召回率 (Recall) 和合理的 AUC/精确度 (Precision)。
根据我们的结果,MLP 分类器似乎是最佳选择,具有最高的召回率和非常不错的 94.7% 的 AUC。
超参数调优
一旦我们确定了要进一步研究的排名前四的模型,我们就需要找到模型的最佳超参数。PyCaret 提供了一个非常方便的函数 ***tune_model() ***,它通过预定义的超参数网格进行循环,通过 10 折交叉验证找到我们模型的最佳参数。PyCaret 使用标准的 随机网格 (Randomized-Grid) 搜索来迭代参数。可以根据计算能力和时间限制将迭代次数 (n_iter) 指定为一个较大的数字。在 tune_function() 中,PyCaret 还允许我们指定要优化的指标。默认为准确率 (Accuracy),但我们也可以选择其他指标。例如,我们将在这里选择 召回率 (Recall),因为它是我们想要提高/优化的指标。
所以目前我们的前 4 个模型是
在继续之前,让我们评估模型性能。我们将利用 PyCaret 的 evaluate_model() 函数来评估并突出显示获胜模型的重要方面。
混淆矩阵
特征重要性
由于 mlp 和 catb_tuned 不提供特征重要性,我们将使用 *lgbm *来查看哪些特征在我们的预测中最重要
我们可以看到,黄金在过去 180 天的收益是这里最重要的因素。这也很直观,因为如果黄金价格过去大幅上涨,其下跌/回调的可能性更高,反之亦然。接下来的 3 个特征是白银在 250 天、60 天和 180 天的收益。同样,白银和黄金是两种交易最广泛且高度相关的贵金属,因此这种关系非常直观。
模型融合 (Blending)
模型融合基本上是在估计器之上构建一个投票分类器。对于提供预测概率的模型,我们可以使用软投票(使用它们的概率),而对于其他模型,我们将使用硬投票。blend_model() 函数默认为使用硬投票,这可以手动更改。我构建了两种融合模型,以查看是否可以提取一些额外的性能。
虽然没有一个模型能够取代 ‘mlp’ 的第一名位置,但看到第二种融合模型 ‘blend2’ 非常有趣,它是 ‘lgbm’ 和 ‘et’ 的软组合。其在 召回率 (Recall) 和 AUC 上的性能分别为 62.25% 和 97.43%,高于 ‘lgbm’ 和 ‘et’ 单个模型的性能。这展示了融合模型的优势。现在我们的获胜模型将减少到 3 个。
在第一个堆叠模型 ‘stack1’ 中,我在第一层使用了表现较差的模型 catb_tuned 和 blend2,将它们的预测传递给领先模型 mlp,这有助于它进行预测,而 mlp 的预测则被元模型(此处默认为 逻辑回归 (LR))使用来做出最终预测。由于 LR 在完整数据上的表现不佳(参见模型比较结果),我使用了 restack=False,这意味着只有前一层模型的预测会传递给后续的估计器,而不是原始特征。我们在这里看到的是奇迹般的结果。召回率 (Recall) 从我们最佳模型 ‘mlp’ 的 66.63% 大幅跃升至 77.8%,AUC 和 精确度 (Precision) 也同样提高。‘stack1’ 绝对远远优于我们之前构建的所有模型。显然,我也尝试了其他配置,看看是否可以获得更好的性能。我确实找到了更好的配置
上述堆叠模型 ‘stack3 取得了最显著的成功,召回率 (Recall) 平均达到 80.7%,比我们的获胜模型 ‘mlp’ 高出 14%,并且在 准确率 (Accuracy)(95%,提高 3%)、AUC(97.34%,提高 2.5%)或 精确度 (Precision)(86.28%,大幅提高 7.7%)方面没有牺牲。
我们可以使用此模型对我们在 setup 阶段分离的测试数据(占总观测值的 30%)进行预测。我们可以通过使用 predict_model() 来完成此操作
我们可以看到模型在测试数据上的性能甚至更好,召回率 (Recall) 达到 86.9%。
由于我们选择了 ‘stack3’ 作为领先模型,我们将在整个数据(包括测试数据)上拟合该模型,并保存该模型以便在新数据上进行预测。
我们将跳过数据导入和准备部分(详细信息请查看笔记本),直接看预测过程。
使用 predict_model(),我们可以将加载的模型应用于新数据集,以生成预测(1 或 0)和得分(与预测相关的概率)。‘prediction’ 数据框还将包含我们提取的所有特征。
查看预测结果的标签 (Label) 和得分 (Score) 列,模型没有预测任何一天会发生显著下跌。例如,根据截至 4 月 29 日的历史收益数据,模型预测黄金价格在未来 22 天内不太可能发生显著下跌,因此 标签 (Label) = 0,概率仅为微不足道的 9.19%。
在之前两部分的系列文章中,我们讨论了如何从免费的 yahoofinancials API 导入数据,并构建一个回归模型来预测黄金在两个时间范围内的收益,即 14 天和 22 天。
导入并整理数据 — 这与第一部分中解释的类似。你也可以从我的 git 下载最终数据集.
这一部分与我们在第一部分中所做的完全相同。包含用于数据导入和操作的整个代码块,或者你可以直接通过链接加载数据集,链接如下.
上面的代码对 Cat-Boost 分类器进行调优,通过对定义的网格迭代 50 次来优化 “召回率 (Recall)”,并显示每个折叠的 6 个指标。我们看到,基础 Cat-Boost 的平均召回率 (Mean Recall)从 58.2% 提高到这里的 62.6%。这是一个巨大的飞跃,在调优阶段并不常见。然而,它仍然低于我们之前创建的基础 “mlp” 模型的 66.6%。对于其他三个模型,我们没有看到通过调优带来的性能提升(例如在)。原因在于遍历参数的随机性。然而,确实存在可以达到或超过基础模型性能的参数,但这需要我们进一步增加 n_iter,这意味着需要更多的计算时间。
对模型的超参数进行调优后,我们可以尝试集成方法来提高性能。我们可以尝试两种集成方法:。不提供概率估计的模型不能用于 Boosting。因此,我们只能对 ‘lgbm’ 和 ‘et’ 使用 Boosting。对于其他模型,我们尝试了 bagging,看看性能是否有任何提高。以下是代码截图和 10 折交叉验证结果。
如上所示,这两种模型的性能并未提升。对于其他模型,性能也出现了下降(请查看)。因此,我们的获胜模型保持不变。
**
是一种方法,我们允许一层(或一组)模型的预测作为后续层的一个特征,最后,元模型被允许根据前几层的预测和原始特征(如果 restack=True)进行训练,以做出最终预测。PyCaret 提供了非常简单的实现,我们可以使用 stack_model() 构建一个包含一层和一个元模型的堆叠模型,或者使用 create_stacknet() 构建包含多层和一个元模型的堆叠模型。我使用了不同的组合来构建不同的堆叠模型并评估性能。
上面的代码在整个数据上拟合模型,并使用 save_model() 函数,我将训练好的模型和预处理管道保存到我的活动目录下的 pkl 文件中,文件名为。这个保存好的模型可以并且将被调用来对新数据进行预测。
为了进行预测,我们需要像本练习开始时那样导入原始价格数据来提取特征,然后加载模型进行预测。唯一的区别在于,我们将导入截至最后一个交易日的数据,以便对最新数据进行预测,就像我们在现实生活中会做的那样。仓库中标题为“的笔记本展示了数据导入、准备和预测代码。
因此,我在这里逐步介绍了如何创建一个分类器,以预测黄金价格在未来 22 天内可能发生的显著下跌。笔记本中也包含 14 天模型的代码。你可以尝试创建标签,并以类似的方式预测在不同时间窗口内发生的类似下跌。到目前为止,我们已经创建了一个和一个分类模型。将来,我们将尝试使用分类模型的预测作为回归问题中的特征,看看是否能提高回归性能。
***
***
***
***