2

我目前正在根据我拥有的一些数据训练一个随机森林,我发现该模型在验证集上的表现比在训练集上的表现更好,甚至在测试集上的表现更好。以下是我正在做的一些细节 - 如果我错过了任何重要信息,请告诉我,我会添加它。

我的问题

我是否在做任何明显错误的事情,你对我应该如何改进我的方法有什么建议吗,因为当我的模型对看不见的数据的预测比训练数据好得多时,我简直不敢相信我做对了!

数据

我的基础数据由描述客户行为的特征表和二进制目标组成(所以这是一个二进制分类问题)。从技术上讲,我每个月都有一个这样的表,我倾向于使用几个月的数据进行训练,然后使用不同的月份进行预测(例如,在 4 月、5 月进行训练,在 6 月进行预测)

一般来说,这意味着我最终得到了一个大约 100k 行和 20 个特征的训练数据集(我之前研究过特征选择,发现一组 7 个似乎表现最好的特征,所以最近一直在使用这些特征)。我的预测集通常有大约 50k 行。

我的数据集严重不平衡(大约 2% 的目标特征发生率),所以我使用过采样技术 - 更多内容如下。

方法

我在网上搜索了很多,这导致我采用以下方法:

  • 在训练数据中获取可缩放(连续)特征并对其进行标准化(目前使用 sklearn StandardScaler)
  • 获取分类特征并使用 Pandas get_dummies 函数将它们编码为单独的二进制列(one-hot)
  • 删除 10% 的训练数据以形成验证集(我目前在此过程中使用随机种子来进行可比性,同时我改变了不同的东西,例如模型中的超参数)
  • 获取剩余 90% 的训练数据,并在 RandomForestClassifier() 的几个参数(当前为 min_samples_split、max_depth、n_estimators 和 max_features)上执行网格搜索
  • 在网格中的每个超参数组合中,我使用 5 折并使用随机状态执行 kfold 验证
  • 在每个折叠中,我仅对少数类进行过度采样以用于训练数据(有时使用不平衡学习的 RandomOverSampler(),有时使用同一包中的 SMOTE()),在训练数据上训练模型,然后将模型应用于第 k 折叠和记录性能指标(精度、召回率、F1 和 AUC)
  • 一旦我对每个超参数组合进行了 5 次折叠,我就会找到最好的 F1 分数(如果两个组合与 F1 分数相关,则可以找到最佳精度)并使用这些超参数在整个 90% 的训练数据上重新训练一个随机森林。在这一步中,我使用了与 kfold 过程中相同的过采样技术
  • 然后我使用这个模型对我之前作为验证集搁置的 10% 的训练数据进行预测,评估与上述相同的指标
  • 最后我有一个测试集,它实际上是基于另一个月的数据,我将已经训练好的模型应用于并评估相同的指标

结果

目前我发现我的训练集的 F1 分数约为 30%,而验证集的 F1 分数始终略高于 36% 左右(主要是由于比训练数据更好的精度,例如 60% vs. 30%)然后测试集的 F1 分数在 45% 到 50% 之间,这又是由更好的精度(大约 65%)驱动的

笔记

请询问我未提及的任何细节;我已经坚持了好几个星期了,所以无疑省略了一些细节

  • 我对 kfold 验证中折叠之间的指标稳定性进行了简要介绍(不是系统分析),看起来它们变化不大,所以我对这里模型的稳定性感到相当满意
  • 我实际上是手动执行网格搜索而不是使用 Python 管道,因为我可能无法让不平衡学习的管道函数与过采样函数一起使用,所以我运行一个包含超参数组合的循环,但是我我相信这不会以不利的方式影响我上面谈到的结果
  • 当我将最终模型应用于预测数据(并获得大约 45% 的 F1 分数)时,我也会出于兴趣将其应用回训练数据本身,并获得大约 90% - 100% 的 F1 分数。我想这是可以预料的,因为模型经过训练并预测几乎完全相同的数据(除了 10% 的保留验证集)
4

0 回答 0