交叉验证

译者:flink.sojb.cn

描述

当使用机器学习算法时,一个普遍存在的问题是过度拟合,或者当算法“内存”训练数据但是在外推到样本案例之外做得很差。处理过度拟合问题的常用方法是阻止原始训练算法中的某些数据子集,然后测量拟合算法在该保持集上的性能。这通常称为交叉验证。在一个数据子集上训练模型,然后在另一组数据上进行验证

交叉验证策略

有几种保存数据的策略。FlinkML有方便的方法

  • 训练测试分裂
  • 训练 - 测试 - 保持分裂
  • K-Fold Splits
  • 多随机拆分

训练测试分裂

最简单的分裂方法是trainTestSplit。此拆分采用DataSet和参数分数。该分数表示应分配给所述训练集合中的数据集的部分。这种拆分还需要两个额外的可选参数,精确种子

默认情况下,通过随机决定是否使用probability = fraction为训练DataSet分配观察来完成拆分。当精确true然而,采取额外的步骤,以保证训练集是尽可能接近到DataSet的长度 交叉验证 - 图1 交叉验证 - 图2 <math xmlns=”http://www.w3.org/1998/Math/MathML"><mo>⋅</mo></math&gt; 分数

该方法返回一个新TrainTestDataSet对象,该对象具有.training包含训练DataSet的.testing属性和包含测试DataSet 的属性。

训练 - 测试 - 保持分裂

在某些情况下,已知算法“学习”测试集。为了解决这个问题,列车测试持币观望策略,引入了二次抵抗组,形象地称为抵抗集。

传统上,将进行训练和测试以正常训练算法,然后将对保持集上的算法进行最终测试。理想情况下,保持集中的预测误差/模型分数与测试集中观察到的预测误差/模型分数没有显着差异。

在训练 - 测试 - 保持策略中,我们牺牲了初始拟合算法的样本大小,以增加我们的模型不过度拟合的置信度。

使用trainTestHoldout分离器时,分数 Double由长度为3 的分数数组代替。第一个数据元对应于用于训练的部分,第二个数据元用于测试,第三个数据元用于保持。该阵列的权重是相对的,例如,阵列Array(3.0, 2.0, 1.0)将导致大约50%的观测值在训练集中,33%的观测值在测试集中,17%的观测值在保持集中。

K-Fold Splits

k折叠策略中,DataSet被分成k个相等的子集。然后,对于k个子集中的每一个TrainTestDataSet,创建a,其中子集是.trainingDataSet,并且剩余的子集是该.testing集合。

对于每个训练集,训练算法,然后基于基于相关测试集的预测来评估算法。当在所保持的数据集上具有一致等级(例如预测误差)的算法时,我们可以确信我们的方法(例如,算法/算法参数的选择/迭代次数)对于过度拟合是鲁棒的。

K-Cross交叉验证#k-fold_cross-validation)

多随机拆分

多随机策略可以看作是一个更一般的形式列车测试抵抗策略。实际上,它.trainTestHoldoutSplit是一个简单的打包器,multiRandomSplit它还将数据集打包到一个trainTestHoldoutDataSet对象中。

第一个主要区别是multiRandomSplit采用任意长度的分数数组。例如,可以创建多个保持集。或者,人们可以将其kFoldSplit视为multiRandomSplit(它是)的打包器,区别在于kFoldSplit创建大小相等的子集,其中multiRandomSplit将创建任何大小的子集。

第二个主要区别是multiRandomSplit返回一个DataSet 数组,其大小和比例与它作为参数传递的fraction数组相等。

参数

各种Splitter方法共享许多参数。

参数 类型 描述 由Method使用
input DataSet[Any] 要拆分的DataSet。 randomSplit

multiRandomSplit kFoldSplit trainTestSplit trainTestHoldoutSplit | | seed | Long | 用于播种将DataSet分类到其他DataSet中的随机数生成器。 | randomSplit multiRandomSplit kFoldSplit trainTestSplit trainTestHoldoutSplit | | precise | Boolean | 如果为true,请进一步努力使DataSet尽可能接近规定的比例。 | randomSplit trainTestSplit | | fraction | Double | input的一部分分配给第一个或.trainingDataSet。必须在范围(0,1) | randomSplit trainTestSplit | | fracArray | Array[Double] | 一个数组,规定了输出数据集的比例(比例不需要总和为1或者在范围(0,1)内) | multiRandomSplit trainTestHoldoutSplit | | kFolds | Int | 要将inputDataSet 分解为的子集数。 | kFoldSplit |

例子

  1. // An input dataset- does not have to be of type LabeledVector val data: DataSet[LabeledVector] = ...
  2. // A Simple Train-Test-Split val dataTrainTest: TrainTestDataSet = Splitter.trainTestSplit(data, 0.6, true)
  3. // Create a train test holdout DataSet val dataTrainTestHO: trainTestHoldoutDataSet = Splitter.trainTestHoldoutSplit(data, Array(6.0, 3.0, 1.0))
  4. // Create an Array of K TrainTestDataSets val dataKFolded: Array[TrainTestDataSet] = Splitter.kFoldSplit(data, 10)
  5. // create an array of 5 datasets val dataMultiRandom: Array[DataSet[T]] = Splitter.multiRandomSplit(data, Array(0.5, 0.1, 0.1, 0.1, 0.1))