在遗传算法中使用交叉验证时如何避免过度拟合

机器算法验证 机器学习 数据挖掘 特征选择 遗传算法
2022-03-30 02:31:24

这是一个漫长的设置,但纯粹的智力挑战会让我保证它是值得的;-)

我有营销数据,其中有治疗和控制(即客户没有得到治疗)。感兴趣的事件(获得贷款)相对较少(<1%)。我的目标是模拟治疗和对照组的反应率(治疗组预订率 - 对照组预订率)之间的增量提升,并使用该模型来决定未来向谁推广。

治疗组很大(600,000 条记录),对照组的大小约为 15%。

这是一项营销活动,我们希望针对那些需要有针对性地采取感兴趣的行动的人,而不是将资金浪费在那些“无论如何都会这样做”的人身上。

我有数百个变量,并尝试了各种形式的Uplift 建模 AKA Net Lift Models我已经尝试了文献和常用实践中的许多最先进的方法。不幸的是,在这个数据集上没有一个非常稳定。

我知道(理论上和经过一些实验)有一些变量可能会影响增量提升。因此,我创建了一个矩阵,其中包含这些变量的水平以及治疗组中的记录数、对照组中的记录数以及每个变量中感兴趣的事件数。因此,可以从矩阵中的每一行计算增量提升。矩阵中有 84 行。

在此处输入图像描述

我曾考虑使用 beta 回归对这个(差异)比例进行建模,但某些行中的计数非常多余(可能控件中没有记录,更常见的是,没有感兴趣的事件)。这可以在上面示例数据的前几行中看到。

我开始考虑寻找最佳解决方案来选择矩阵的哪一行。被选中的行与控件一起具有总处理的 HH 和处理的贷款的数量。我正在寻求最大化利润,这可以从这些数字中估算出来。

我通过遗传算法推送数据以确定要保留哪些行。我得到了一个解决方案,结果比包括每个人都好(这是基本情况)。但是,当我在我划分的验证样本上运行该选择时,结果并非如此。

我的问题:有没有办法在这个适应度函数中设计交叉验证,这样解决方案就不会过度拟合——我认为这发生在我的第一次尝试中。

这是我使用的适应度函数:

calcProfit<-function(selectVec=c())
{

    TreatLoans<-sum(selectVec*dat$TreatedLoans)
	ControLoans<-sum(selectVec*dat$ControlLoans)
    TreatHH<-sum(selectVec*dat$treatedHH)
	ControlHH<-sum(selectVec*dat$controlHH)


    Incre.RR<-(TreatLoans/TreatHH)-(ControLoans/ControlHH)
    Incre.Loans<- Incre.RR * TreatHH
    Incre.Rev <- Incre.Loans*1400
    Incre.Profit<- (-1)*(Incre.Rev - (0.48*TreatHH))

    Incre.Profit


}

和 R 中的调用:rbga.results = rbga.bin(size=84, zeroToOneRatio=3,evalFunc=calcProfit,iters=5000)

3个回答

交叉验证也不会消除过拟合,只会(希望)减少它。如果在有限的数据样本上评估非零方差的任何统计量最小化,则存在过度拟合的风险。你做的选择越多,过拟合的机会就越大。您尝试最小化统计数据的难度越大,过度拟合的可能性就越大,这是使用 GA 的问题之一——它非常努力地寻找最低的最小值。

如果预测性能很重要,正则化可能是一种更好的方法,因为它涉及的选择更少。

本质上在统计学中,优化是所有过拟合的根源,所以避免过拟合的最好方法是尽量减少你所做的优化量。

只有一种范式可以避免模型在未来数据上过度拟合,这当然是 VC 绑定的。许多研究人员说 VC 绑定是一个悲观的案例,但我不明白。如果空间中只有一个女人,是否可以评论唯一一个女性的美丽......

除了最小二乘之外,没有什么可以阻止您在优化循环中加入正则化惩罚以最小化。我已经这样做了,效果很好。我同意 Dikran 的观点,除非采取此类步骤,否则优化仍会导致回归模型(甚至是交叉验证模型)的过度拟合。