测试数据集的成本,即Jtest(θ)是评估模型准确性的最直观的指标,Jtest(θ)值越小说明模型预测出来的值与真实值差异越小,对新数据的预测准确性就越好。需要特别注意,用来测试模型准确性的测试数据集,必须是模型“没见过”的数据。
这就是为什么,要把数据集分成训练数据集和测试数据集。一般原则是按照8:2或7:3来划分,然后用训练数据集来训练模型,训练出模型参数后再使用测试数据集来测试模型的准确性,根据模型的准确性来评价模型的性能。
可以思考一个问题:为什么要确保模型没有见过测试数据集?
那么,我们要如何计算测试数据集的误差呢?简单地说,就是用测试数据集和训练出来的模型参数代入相应的成本函数里,计算测试数据集的成本。
针对前面介绍的线性回归算法,可以使用下面的公式计算测试数据集的误差,其中m是测试数据集的个数:
Jtest(θ)=2m1∑i=0m(hθ(x(i))−y(i))2
1.模型性能的不同表达式
在scikit-learn里,不使用成本函数来表达模型的性能。而使用分数来表达,这个分数总是在[0,1]之间,数值越大说明模型的准确性越好。当模型训练完成后,调用模型的score(X_test,y_test)即可算法模型的分数值,其中X_test和y_test是测试数据集样本。
模型分数(准确性)与成本成反比。即分数越大,准确性越高,误差越小,成本越低;反之,分数越小,准确性越低,误差越大,成本越高。
2.交叉验证数据集
另外一个更科学的方法是把数据集分成3份,分别是训练数据集、交叉验证数据集和测试数据集,推荐比例是6:2:2。
为什么需要交叉验证数据集呢?以多项式模型选择为例。假设我们用一阶多项式、二阶多项式、三阶多项式……十阶多项式来拟合数据,多项式的阶数记为d。我们把数据集分成训练数据集和测试数据集。先用训练数据集训练处机器学习算法的参数θ(1),θ(2),θ(3),……,θ(10),这些参数分别代表从一阶到十阶多项式的模型参数。这10个模型里,哪个模型更好呢?这个时候我们会用测试数据集算出针对测试数据集的成本Jtest(θ),看哪个模型的测试数据集成本最低,我们就选择这个多项式来拟合数据,但实际上,这是有问题的。测试数据集的最主要功能是测试模型的准确性,需要确保模型没见过这些数据。现在我们用测试数据集来选择多项式的阶数d,相当于把测试数据集提前让模型见过了。这样选择出来的多项式阶数d本身就是对训练数据集最友好的一个,这样模型的准确性测试就失去了意义。
为了解决这个问题,我们把数据分成3份,随机选择60%的数据作为训练数据集,其成本记为J(θ),随机选择20%的数据作为交叉验证数据集(Cross Validation),其成本记为Jcv(θ),剩下的20%作为测试数据集,其成本记为Jtest(θ)。
在模型选择时,我们使用训练数据集来训练算法参数,用交叉验证数据集来验证参数。选择交叉验证数据集的成本Jcv(θ)最小的多项式来作为数据拟合模型,最后再用测试数据集来测试选择出来的模型针对测试数据集的准确性。
因为在模型选择过程中,我们使用了交叉验证数据集,所以筛选模型多项式阶数d的过程中,实际上并没有使用测试数据集。这样保证了使用测试数据集来计算成本衡量模型的准确性,我们选择出来的模型是没有见过测试数据,即测试数据集没有参与模型选择的过程。
当然,在实践过程中,很多人直接把数据集分成训练数据集和测试数据集,而没有分出交叉验证数据集。这是因为很多时候并不需要横向去对比不同的模型。在工程上,大多数时候我们最主要的工作不是选择模型,而是获取更多数据、分析数据、挖掘数据。