来源:原始 Jupyter Notebook。内容已转换为网页阅读格式;下载原文件。
在上一节中我们学到,为了避免模型在数据集上过度训练导致过拟合,通常将数据集划分为训练集和测试集。
数据集划分方法
假设我们有一个包含 m 个样例的数据集 ,得想办法对数据集进行划分,分成训练和测试两类,训练集记为 ,测试集记为 。这样的划分方法有很多,常见的有:留出法(hold-out)、交叉验证法(cross validation)、自助法(bootstrapping)等。
留出法非常简单,直接将数据集划分成两个互斥的集合,分别作为训练集和测试集,,常见的做法是将大约 2/3 ~ 4/5 的数据用于训练,剩余的数据用于测试,注意划分的时候尽可能保持数据分布的一致性。
交叉验证法先将数据集划分成 k 个大小相似的互斥子集,,同样划分时尽可能保持数据分布的一致性。然后,用其中的 k-1 个子集的并集作为训练集,剩下的那个子集作为测试集,这样可以进行 k 次训练和测试,最终计算这 k 次测试结果的均值。交叉验证法又叫 k 折交叉验证(k-fold cross validation)。
自助法是以 自助采样(bootstrap sampling,也称为 可重复采样)为基础的样本划分方法,所谓自助采样,指的是从数据集 中随机挑选一个样本,将其拷贝放入一个新集合 中,然后将样本重新放回集合 中,重复 m 次,得到一个包含 m 个样本的数据集 。很显然, 中有些样本在 中会出现多次,还有一些样本不会出现,样本不会出现的概率是:
我们将 用作训练集, 中没有出现的样本 用作测试集,这样的测试结果也叫做 包外估计(out-of-bag estimate)。
模型评估方法
通过上面的方法,把样本数据分成训练集和测试集之后,就可以使用你的机器学习算法对训练集进行训练生成一个模型,然后再拿着这个模型在测试集上进行验证,评估这个模型的效果。
其实,在前面介绍损失函数时提到了两种损失函数,一种是 绝对损失(Absolute Loss),一种是 平方损失(Squared Loss)。
绝对损失函数:
平方损失函数:
这实际上也是两种评估模型的指标,分别是:平均绝对误差(Mean Absolute Error,MAE) 和 均方误差(Mean Squared Error,MSE)。
除此之外,从 MAE 还可以演变成一个新的指标,平均绝对百分误差(Mean Absolute Percentage Error,MAPE):
MAPE 通过计算绝对误差的百分比来表示预测效果,其取值越小越好,如果 MAPE = 10,这表明预测平均偏离真实值 10%。
从 MSE 也可以演变成一个新的指标,均方根误差(Root Mean Squared Error,RMSE),它就是对 MSE 求开方:
基于 RMSE 还有一个变种指标,叫均方根对数误差(Root Mean Squared Logarithmic Error,RMSLE),将上面公式中的 和 换成对数形式:
最后,(R-Square)也是一个常见的评估指标,它的公式如下:
用于度量因变量的变异中可由自变量解释部分所占的比例,一般取值范围是 0~1, 越接近 1,表明回归平方和占总平方和的比例越大,回归线与各观测点越接近,用 x 的变化来解释 y 值变差的部分就越多,回归的拟合程度就越好。
使用 sklearn 评估模型
sklearn 中的 metrics 模块提供了几个方法来计算模型评估的指标值,譬如 mean_absolute_error() 用于计算 MAE,mean_squared_error() 用于计算 MSE,r2_score() 用于计算 。
import numpy as np
from sklearn import metrics
expected = np.array([10,20,30,40,50,60,70,80,90,100])
predicted = np.array([10,21,33,41,49,55,70,82,90,102])
print('MAE = ', metrics.mean_absolute_error(expected, predicted))
print('MSE = ', metrics.mean_squared_error(expected, predicted))
print('R-Square = ', metrics.r2_score(expected, predicted))
运行结果
MSE = 4.5
MAE = 1.5
R-Square = 0.9945454545454545
模型选择
上面介绍了多种数据集划分的方法和模型评估的方法,看起来我们只要挑一个评估结果最好的模型就可以了,但是实际上,模型选择可能要比想象中复杂的多。这里面涉及几个重要因素:
- 首先,我们希望比较的是泛化性能,而我们通过评估方法得到的是测试集上的性能,两者的对比结果未必相同;
- 第二,测试集上的性能和测试集本身的选择有很大关系,使用大小不同的测试集,或者使用大小相同但数据不同的测试集,测试结果也会有不同;
- 第三,很多机器学习算法本身具有一定的随机性,即便相同的参数在相同的测试集上运行多次,测试结果也可能不同;
那么,有没有适当的方法对学习器的性能进行比较呢?统计学中的 假设检验(hypothesis test)为此提供了重要依据,根据假设检验,我们可以推断出,若在测试集上观察到学习器 A 比 B 好,则 A 的泛化性能是否在统计意义上优于 B,以及这个结论的把握有多大。
二项检验(binomial test)和 t 检验(t-test)是两种最基本的假设检验方法,可以对单个学习器泛化性能的假设进行检验;如果需要对多个学习器性能进行比较,可以使用 交叉验证 t 检验 和 McNemar 检验,这两个方法都是在同一个数据集上进行检验,Fredman 检验 和 Nemenyi 后续检验 可以在一组数据集上对学习器的性能进行检验。
参考
- 机器学习, 周志华
- 一份非常全面的机器学习分类与回归算法的评估指标汇总
TODO
- 为什么需要这么多的评估指标?
- 每一种评估指标的优缺点,举例说明
- 还有没有其他的评估指标?
- RMSE 代表的是预测值和真实值差值的样本标准差?