## 解决方案：交叉验证

### Holdout 方法

# assume that we begin with two inputs:
#    features - a matrix of input features
#    target - an array of target variables
#       corresponding to those features

N = features.shape[0]
N_train = floor(0.7 * N)

# randomly select indices for the training subset
idx_train = random.sample(np.arange(N), N_train)

# break your data into training and testing subsets
features_train = features[idx_train,:]
target_train = target[idx_train]
features_test = features[~idx_train,:]
target_test = target[~idx_train]

# build a model on the training set
model = train(features_train, target_train)

# generate model predictions on the testing set
preds_test = predict(model, features_test)

# evaluate the accuracy of the predictions
accuracy = evaluate_acc(preds_test, target_test)

1. Holdout方法计算得到的误差估计非常接近模型在“新数据集”的误差。它们确实比用训练集数据得到的误差估计更接近（图3），尤其是对于窗口参数值较小的情况。

2. Holdout方法的误差估计有很多噪音。相比从新数据得到的光滑的误差曲线，其跳跃波动很厉害。

### K-Fold交叉验证

# assume that we begin with two inputs:
#    features - a matrix of input features
#    target - an array of target variables
#       corresponding to those features

N = features.shape[0]
K = 10 # number of folds

preds_kfold = np.empty(N)

folds = np.random.randint(0, K, size=N)

# loop through the cross-validation folds
for ii in np.arange(K):
# break your data into training and testing subsets
features_train = features[folds != ii,:]
target_train = target[folds != ii]
features_test = features[folds == ii,:]

# build a model on the training set
model = train(features_train, target_train)

# generate and store model predictions on the testing set
preds_kfold[folds == ii] = predict(model, features_test)

# evaluate the accuracy of the predictions
accuracy = evaluate_acc(preds_kfold, target)

## 使用交叉验证的几点注意事项

• 在K-fold方法交叉验证中K的值选的越大，误差估计的越好，但是程序运行的时间越长。

解决方法：尽可能选取K=10（或者更大）。对于训练和预测速度很快的模型，可以使用leave-one-out的教程验证方法（即K=数据样本个数）。

• 交叉验证方法（包括Holdout和K-fold方法）假设训练数据的分布能代表整体样本的分布。如果你计划部署模型来预测一些新数据，那么这些数据的分布应该和训练数据一致。如果不一致，那么交叉验证的误差估计可能会对新数据集的误差更加乐观。

解决方法：确保在训练数据中的任何潜在的偏差都得到处理和最小化。

• 一些数据集会用到时序相关的特征。例如，利用上个月的税收来预测本月的税收。如果你的数据集也属于这种情况，那你必须确保将来的特征不能用于预测过去的数值。

解决方法：你可以构造交叉验证的Holdout数据集或者K-fold，使得训练数据在时序上总是早于测试数据。

## 总结

• Holdout是最简单的交叉验证方法，为了更好地估计模型的通用性，分割一部分数据作为待预测的测试数据集。

• K-fold交叉验证 —— 每次保留K份数据中的一份 —— 能够更确定地估计模型的效果。这种改进的代价来自于更高的计算成本。如果条件允许，K等于样本数目时能得到最好的估计，也称为leave-one-out方法。

• 介绍了模型评价的基本流程。简单来说就是：

• 获取数据并做建模前的预处理（第二章），并且确定合适的机器学习模型和算法（第三章）。
• 构建模型，并根据计算资源选择使用Holdout或者K-fold交叉验证方法预测数据。
• 用所选取的指标评估预测结果。如果是分类的机器学习方法，在4.2节里会介绍常见的效果评价指标。同样，我们会在4.3小节介绍回归问题的常用评价指标。
• 不断调整数据和模型，直到取得理想的效果。在5~8章中，我们会介绍真实场景下用于提高模型效果的常用方法。
• 对于分类模型，我们介绍了几个用于上述流程中步骤3的模型性能指标。这些技术包括简单的准确率计算，混淆矩阵，ROC，ROC曲线和ROC曲线下面积。

• 在回归模型中，我们介绍了均方根误差（rMSE）与R平方估计（R-squared），我们讨论了简单的可视化，如预测与实际的散点图和残差图。

• 我们介绍了调整参数的概念，并展示了如何使用网格搜索算法的参数优化模型。

Under/over-fitting 欠拟合/过拟合 使用了过于简单/复杂的模型。
Evaluation metric 评价指标 一个衡量模型效果的数值。
Mean squared error 均方差 回归模型所使用的一种评价指标。
Cross-validation 交叉验证 为了更好地估计准确率，把训练数据分成2份（或者多份）独立的训练/测试数据集的方法。
Holdout method Holdout方法 一种交叉验证的方法，保留一份测试数据集用于模型测试。
K-fold cross-validation K折交叉验证 一种交叉验证的方法，数据集被分为K份独立的子集，每次取出一份作为测试集，其余数据用来训练模型。
Confusion matrix 混淆矩阵 用于比较分类结果和实际测得值的一种矩阵。
ROC - Receiver operator characteristic ROC 一种用于记录真阳性、假阳性、真阴性、假阴性的数值。
AUC - Area under the ROC curve ROC曲线下面积 ROC曲线下方的面积大小。
Tuning parameter 调整参数 机器学习算法的一个内部参数，比如内核平滑回归算法的窗宽参数。
Grid search 网格搜索 优化模型参数时采用的一种暴力搜索策略。

#### 机器学习算法 原理、实现与实战——模型评估与模型选择

2016-04-09 19:52:44

#### 机器学习常见评价指标：AUC、Precision、Recall、F-measure、Accuracy

2017-11-30 16:11:00

#### 机器学习性能评估指标（精确率、召回率、ROC、AUC）

2016-08-08 22:32:58

#### 机器学习模型评价(Evaluating Machine Learning Models)-主要概念与陷阱

2015-10-31 22:46:59

#### 机器学习评价指标

2016-04-28 10:52:42

#### 机器学习之分类器性能指标之ROC曲线、AUC值

2015-04-08 23:01:21

#### 机器学习模型的评价指标和方法

2016-09-18 15:04:55

#### 机器学习常用评价指标总结

2017-04-27 21:36:06

#### 机器学习评价指标大汇总

2016-12-05 16:35:03

#### 机器学习模型评价指标 -- 混淆矩阵

2016-11-04 17:50:40