大家好
我是JMP Japan的测试员小野裕介。
在我看来,当使用k倍验证时,预测值有时会变得非常嘈杂。请参见下面的屏幕截图。这是具有一个X变量的模型的预测值的曲线图。使用5折验证。

我建议我们预测值的计算方法如下。
(0 + :Name( "y Predictor FoldA==1" ) + :Name( "y Predictor FoldA==2" ) +
:Name( "y Predictor FoldA==3" ) + :Name( "y Predictor FoldA==4" ) +
:Name( "y Predictor FoldA==5" )) / 5
当前的预测公式如下。
If( :N Val > 0,
(0 + :Name( "FoldA==1" ) * :Name( "y Predictor FoldA==1" ) + :Name( "FoldA==2" )
* :Name( "y Predictor FoldA==2" ) + :Name( "FoldA==3" ) *
:Name( "y Predictor FoldA==3" ) + :Name( "FoldA==4" ) *
:Name( "y Predictor FoldA==4" ) + :Name( "FoldA==5" ) *
:Name( "y Predictor FoldA==5" )) / :N Val,
(0 + (1 - :Name( "FoldA==1" )) * :Name( "y Predictor FoldA==1" ) + (1 -
:Name( "FoldA==2" )) * :Name( "y Predictor FoldA==2" ) + (1 -
:Name( "FoldA==3" )) * :Name( "y Predictor FoldA==3" ) + (1 -
:Name( "FoldA==4" )) * :Name( "y Predictor FoldA==4" ) + (1 -
:Name( "FoldA==5" )) * :Name( "y Predictor FoldA==5" )) / :N Trn
);
你能告诉我你的意见吗?
重现此现象的步骤
(1) 运行以下脚本以创建样本数据集。
Names Default To Here(1);
Random Reset(111111111);
n = 10000;
x = J(n, 1, Random Uniform(-10, 10));
y = Sin(x) + J(n, 1, Random Normal());
As Table(x||y,<<COLUMN names=""></COLUMN>
(2) 选择 [加载项] > [XGBoost] > [制作K栏折叠] 。
2-1。输入“ 1” [要创建的K折列数] 。
2-2。指定“ y”为 [是,回复] 。
2-3。请点击 [走] 。
(3) 运行以下脚本。
XGBoost(
Y( :y ), X( :x ),
Validation( :FoldA ),
Fit( max_depth( 3 ), alpha( 10 ), lambda( 10 ), iterations( 50 ) ),
);
(4) 选择 [保存预测公式] 在“模型1”轮廓的红色三角形菜单中。
(5) 运行以下脚本以查看保存的预测值。
Graph Builder(
Size( 1209, 478 ),
Show Control Panel( 0 ),
Variables( X( :x ), Y( :y Predictor ) ),
Elements( Line( X, Y, Legend( 5 ) ) ),
SendToReport(
Dispatch( {}, "x", ScaleBox,
{Format( "Fixed Dec", 12, 1 ), Min( -3 ), Max( 3 ), Inc( 1 ),
Minor Ticks( 1 )}
)
)
);
(6) 运行下面的脚本以查看我的建议。
New Column( "My Suggestion",
Formula(
(:Name( "y Predictor FoldA==1" ) +
:Name( "y Predictor FoldA==2" ) +
:Name( "y Predictor FoldA==3" ) +
:Name( "y Predictor FoldA==4" ) +
:Name( "y Predictor FoldA==5" )) / 5
)
);
Graph Builder(
Size( 1209, 478 ),
Show Control Panel( 0 ),
Variables( X( :x ), Y( :My Suggestion ) ),
Elements( Line( X, Y, Legend( 5 ) ) ),
SendToReport(
Dispatch( {}, "x", ScaleBox,
{Format( "Fixed Dec", 12, 1 ), Min( -3 ), Max( 3 ), Inc( 1 ),
Minor Ticks( 1 )}
)
)
);
附带的数据表具有这些结果。请运行表脚本以查看图。
预先感谢您的意见。
这些是问佑介的好问题。 如果我们将整个过程分为两个主要步骤,首先是确定一个或多个合理的XGBoost模型。 对于这种k折交叉验证或类似的方法,是无价的。 其次是进行预测,让我们将其分为对当前训练数据和新测试数据进行预测。 对于训练数据的预测,使用在相同数据上训练的任何模型都将导致预测通常过拟合且不切实际地好,因此,不合时宜的预测最有意义。 对于新的测试数据,对所有未看到数据的模型进行平均预测即可,如您所建议的那样。 (实际上,外接程序已经为缺少Y的所有行执行了此操作。)也可以使用交叉验证确定的参数,无需验证即可对完整数据执行后续最终拟合。 我的经验是,平均k倍(“装袋”)的预测与来自全数据拟合的预测趋于非常相似,尽管您甚至可以将它们平均,例如0.5 *(袋装k倍预测)+ 0.5 *(根据完全数据拟合得出的预测)。 我不认为尝试在k折模型拟合中找到“最佳”是值得尝试的,因为它们在操作上是等效的,您冒着过度选择这种选择的风险。
谢谢您的答复,拉斯。
我现在知道,JMP的XGBoost的这些不正确的预测可以用于评估模型,检测异常值和创建集成模型。
我认为当我们使用k交叉验证时,它们是创建最终预测模型的几种方法。
- 使用为所有数据选择的调整参数重新拟合模型。(<这是您的建议。)
- 平均k个模型。(<这是我的建议。)
- 在k个模型中仅使用“最佳”模型。
您是否认为第一种方法通常比第二种和第三种方法更好,以获得最终的预测模型?
谢谢Yusuke提出的问题,以及如何使用JSL复制它的很好的描述。 与JMP中的其他预测建模平台相比,您在计算预测值时外接程序的工作方式之间有着重要的区别。 来自加载项的预测是“不合时宜”的,也就是说,每个预测值仅根据排除该观察值的模型拟合计算得出。
以基本5折为例,并假设数据的第一行分配给3折。 加载项可拟合五个模型,依次折叠,但第一行的预测值仅基于不包含褶皱3的第三拟合。 所有行都使用类似的逻辑。 为什么这样几个原因:
1。不合时宜的预测为模型在未来看不见的数据上的表现提供了现实的评估。 实际上,所有标有“ Validation”(验证)的输出统计信息和图形均基于折衷预测。 您已经注意到,这些预测的可变性可能比使用“内折”数据计算的预测大得多,也就是说,当相同的数据用于训练和预测时。
2。失叠预测列是查找模型在整个训练集中可能产生的异常值和错误的好方法。 K折叠的好处在于,每个观察值仅精确地保留一次,因此,我们对每一行都有不合预期的预测。
3。折衷预测列可用于与从其他良好模型创建的相似列合在一起。 这可以通过简单的平均或在通常称为“堆栈”的技术中,将折合的列用作第二级模型中的新预测变量来完成。 第二层模型通常比第一层模型更简单,例如,来自广义回归的套索模型,甚至另一个深度较浅的XGBoost模型。 堆叠集成模型往往比任何一级模型具有更好的预测性能。
为了获得您建议的基于训练的直接预测,一种好方法是在未指定“验证”列的情况下拟合新的XGBoost模型。 另一种相关的方法是制作数据表的副本,将所有Y值都设置为missing,然后将其连接为原始数据。 在这种情况下,对于Y缺失的行的预测将是所有拟合模型中预测的平均值,该技术称为“装袋”。
最后,要提及的是,您显示的复杂公式是涵盖所有情况的结果。 例如,如果原始数据中的某行缺少Y,则我们希望对所有模型使用袋装预测。