模型校验-交叉验证


概述

一般在进行模型的测试是, 我们会将数据分为训练集合测试集. 在给定的样本空间中, 拿出大部分样本作为训练集来训练模型, 剩余的小部分样本使用刚建立的模型进行预测.

训练集与测试集

训练集与测试集的分割可以使用 cross_validation 中的 train_test_split 方法. 大部分的交叉验证迭代器都内建一个划分数据前进行数据索引打散的选项, train_test_split 方法内部使用的就是交叉验证迭代器. 默认不会进行打散, 包括设置 cv = some_integer (直接) k 折叠交叉验证的 cross_val_score 返回一个随机的划分. (如果数据具有时间性, 千万不要打散数据在划分)

sklearn.cross_validation.train_test_split

代码如下:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# 实例化
li = load_iris()
# 注意返回值: 训练集 train: x_train, y_train, 测试集 test: x_test, y_test
x_train, x_test, y_train, y_test = train_test_split(li.data, li.target, test_size=0.25)
# 调试输出
print("训练集特征值和目标值: ", x_train, y_train)
print("测试集特征值和目标值: ", x_test, y_test)

上面的方法也有局限. 应为只进行一次测试, 并不一定代表模型的真实准确率. 因为, 模型的准确率和数据的切分有关系, 在数据量不大的情况下, 影响尤其突出. 所以还是需要一个比较好的解决方案.

holdout method

评估模型泛化能力的典型方法是 holdout 交叉验证 (holdout cross vaildation). holdout 方法很简单, 我们只需要将袁术数据集分割为训练集和测试集, 前者用于训练模型, 后者用于评估模型的性能. 一般来说, Holdout 验证并非一种交叉验证, 因为数据并没有交叉使用. 随机从最初的样本中选出部分, 形成交叉验证数据, 而剩余的就当做训练数据. 一般来说, 少于原本样本三分之一的数据被选做验证数据, 所有这种方法得到的结果其实并不具有说服性.

k-折交叉验证

K 折交叉验证, 初始采样分割成 K 个样本, 一个单独的子样本被保留作为验证模型的数据, 其他 K-1 个样本用来训练. 交叉验证重复 K 次, 每个子样本验证异常, 平均 K 次的结果或者使用其它结合方式, 最终得到一个单一估测. 这个方法的优势在于, 同时复用运用随机产生的子样本进行训练和验证, 每次的结果验证一次, 10 折交叉验证是最常用的.

机器学习进阶 第一节 第九课_交叉验证

例如 5 折交叉验证, 全部可用数据集分成五个集合, 每次迭代都选用其中的 1 个集合数据作为验证即, 另外 4 个集合作为训练集, 经过 5 组的迭代过程, 交叉验证的好处在于, 可以保证所有数据都有机会被训练和验证, 也尽最大可能让优化的模型性能表现的更加可信.

使用交叉验证的最简单的方式是在估计器和数据集上使用 cross_val_score 函数.

sklearn.cross_validation.cross_val_score

代码如下:

from sklearn.cross_validation import cross_val_score
diabetes = datasets.load_diabetes()
X = diabetes.data[:150]
y = diabetes.target[:150]
lasso = linear_model.Lasso()
print(cross_val_score(lasso, X, y))

使用交叉验证方法的目的主要有 2 个:


  • 从有限的学习数据中获取尽可能多的有效信息
  • 可以在一定程度上避免过拟合问题

estimator 的工作流程

在 sklearn 中, 估计器 (estimator) 是一个重要的角色, 分类器和回归都属于 estimator. 在估计器中有两个重要的方法是 fit 和 transform.


  • fit 方法用于从训练集中学习模型参数
  • transform 用学习带的参数转换数据
    机器学习进阶 第一节 第九课_数据集_02