不论是回归模型还是分类模型,机器学习要达到的都是好的泛化能力.而泛化能力是由测试误差估计的泛化误差来评判的.
其中测试误差是测试集的预测值和真实值的统计量,也就是以上谈到的各种指标.
我们不妨设 $\mu$ 为测试误差的均值, $\sigma $为测试误差的标准差, $\alpha$ 为显著性水平,一般是5%.
假设测试误差和泛化误差服从正态分布,置信度95%的区间为
$( \mu - Z_{0.025} * \sigma, \mu + Z_{0.025} * \sigma) $,
其中$Z_{\alpha}$表示符合标准正态分布的X变量$\alpha$上分位点,也就是$P(X>Z_{\alpha}) = \alpha$
不妨假设有n个样例
最常用的方法被称之为k-折交叉验证
.k-折交叉验证
将数据集划分为k个较小的集合,成为子集,其验证流程是:
将k-1份子集作为训练集训练模型
将剩余的1份子集作为测试集用于估计该模型的泛化误差.
一共可以重复k次
除了将数据集按份平分,还可以每次留下P样例作为测试集,剩下的作为训练集.
一共可以重复$\frac{!n}{!{n-p}!p}$次,其中$!n$表示n的阶乘.
当P=1时,留P交叉验证就称为留一交叉验证.当然,也是k=n时的k-折交叉验证.
留一交叉验证获得的泛化误差往往方差比较大.
作为一般规则,大多数作者和经验证据表明, 5- 或者 10-折交叉验证应该优于 LOO.
与交叉验证相关的接口包括:
model_selection.KFold([n_splits, shuffle, …])
|K折交叉验证model_selection.LeaveOneOut()
|留一交叉验证model_selection.LeavePOut(p)
|留P交叉验证model_selection.TimeSeriesSplit([n_splits, …])
|时间序列交叉验证model_selection.cross_validate(estimator, X)
|通过交叉验证来评估度量,并记录适合度/评分时间model_selection.cross_val_predict(estimator, X)
|为每个输入数据点生成交叉验证估计model_selection.cross_val_score(estimator, X)
|通过交叉验证评估分数model_selection.validation_curve(estimator, …)
|验证曲线
In [15]:
import numpy as np
from sklearn import datasets
from sklearn import svm
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_val_predict
from sklearn import metrics
In [10]:
iris = datasets.load_iris()
In [11]:
clf = svm.SVC(kernel='linear', C=1)
scores = cross_val_score(clf, iris.data, iris.target, cv=5)
scores
Out[11]:
In [12]:
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
In [14]:
predicted = cross_val_predict(clf, iris.data, iris.target, cv=10)
In [16]:
metrics.accuracy_score(iris.target, predicted)
Out[16]:
In [17]:
from sklearn.model_selection import KFold
In [21]:
kf = KFold(n_splits=20)
In [22]:
scores = cross_val_score(clf, iris.data, iris.target, cv=kf)
In [23]:
scores
Out[23]: