交叉验证法

 

什么是交叉验证法?

基本思想就是将原始数据(dataset)进行分组,一部分作为训练集来训练模型,另一部分作为测试集来评价模型。


为什么用交叉验证法?

1、交叉验证用于评估模型的预测能力。尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合。

2、还可以从有限的数据中获取尽可能多的有效信息。


主要有哪些方法?

列举两个:

1、holdout cross validation

在机器学习任务中,拿到数据后,我们首先将原始数据集分为三部分:训练集、验证集和测试集。

训练集用于训练模型,验证集用于模型的参数选择配置,测试集对于模型来说是未知数据,用于评估模型的泛化能力

交叉验证法_第1张图片

这个方法操作简单,只需要随机把原始数据分为3组即可。

不过只做一次分割,它对训练集、验证集和测试集的样本数比例,还有分割后数据的分布是否和原始数据集的分布相同等因素比较敏感,不同的划分会得到不同的最优模型,而且分成三个集合后,用于训练的数据更少了。所以做了如下的改进:

 

2、k-fold cross validation 交叉验证

交叉验证法_第2张图片

通过对 k 个不同分组训练的结果进行平均来减少方差,因此模型的性能对数据的划分就不那么敏感。

 

  1. 不重复抽样将原始数据随机分为 k 份
  2. 每一次挑选其中 1 份作为测试集,剩余的 k-1 份作为训练集用于模型训练。
  3. 重复第2步 k 次,这样每个子集都有一次机会作为测试集,其余机会作为训练集。 在每个训练集上训练后得到一个模型,用这个模型在相应的测试集上测试,计算并保存模型的评估指标。(每次取k-1份训练,得到一个模型,在1份测试集上测试,计算并保存该模型的性能指标。
  4. 计算 k 组测试结果的平均值作为模型精度的估计,并作为当前 k 折交叉验证下模型的性能指标。(平均值作为整个模型的最后的指标

 

k 一般取 10。

数据小的时候,k可以大一点,这样训练集占整体比例会比较大,但同时训练模型的个数也增多。

数据大的时候,k可以小一点。

 

摘自  https://www.cnblogs.com/sddai/p/8379452.html

举例:使用knn算法对cifar10数据集进行分类,采用交叉验证选取最佳的k值。交叉验证代码如下:

num_folds = 5
k_choices = [1, 3,5,8,10,12,15,20,50,100]
x_train_folds = []
y_train_folds = []

y_train = y_train.reshape(-1,1)
x_train_folds = np.array_split(x_train, num_folds)
y_train_folds = np.array_split(y_train, num_folds)


k_to_accuracies = {}

for k in k_choices:
    k_to_accuracies.setdefault(k, [])
for i in range(num_folds):
    classifier = KNearestNeighbor()
    x_val_train = np.vstack(x_train_folds[0:i] + x_train_folds[i+1:])
    y_val_train = np.vstack(y_train_folds[0:i] + y_train_folds[i + 1:])
    y_val_train = y_val_train[:, 0]
    # x_val_test = x_train_folds[i]
    # y_val_test = y_train_folds[i]
    classifier.train(x_val_train, y_val_train)
    for k in k_choices:
        y_val_pred = classifier.predict(x_train_folds[i], k=k)
        num_correct = np.sum(y_val_pred == y_train_folds[i][:, 0])
        accuracy = float(num_correct) / len(y_val_pred)
        k_to_accuracies[k] = k_to_accuracies[k] + [accuracy]
for k in sorted(k_to_accuracies):
    sum_accuracy = 0
    for accuracy in k_to_accuracies[k]:
        print('k=%d, accuracy=%f' % (k, accuracy))
        sum_accuracy += accuracy
    print('the average accuracy is :%f' % (sum_accuracy / 5))

 

 

 

 

 

 

 

你可能感兴趣的:(机器学习)