机器学习的一般流程包括:数据集的准备与预处理、搭建模型、模型训练、模型评估与应用。
在现实任务中,我们往往有多种学习算法可供选择,甚至对同一个学习算法,当使用不同的参数配置时,也会产生不同的模型。那么,我们该选用哪一个学习算法、使用哪一种参数配置呢?这就是机器学习中的“模型选择”(model selection)问题。
选定模型算法,然后再对这个算法模型进行参数配置,而我们就可以通过两个阶段的“预实验”来选定算法和调参。
理想的解决方案当然是对候选模型的泛化误差进行评估,然后选择泛化误差最小的那个模型。
误差:训练集
测试集:测试误差
新样本:泛化误差
过拟合(Overfitting)是指机器学习模型在训练数据上表现很好,但在测试数据上表现较差的情况。过拟合通常发生在模型过度复杂或者训练数据量太少的情况下。
欠拟合 (underfitting),这是指对训练样本的一般性质尚未学好。图2.1给出了关于过拟合与欠拟合的一个便于直观理解的类比。
通常我们可以通过实验测试来对学习器的泛化误差进行评估并进而选出合适的模型。为此需使用一个测试集来测试学习器对新样本的判别能力,然后以测试集上的测试误差作为泛化误差的近似。
数据集D={(x1,y1),(x2,y2),...,(xm,ym)}
训练集S 测试集T
数据集的处理方法
留出法
直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T
即D=S∪T , S ∩ T=
- 分层取样:训练/测试集的划分要尽可能保持数据分布的一致性,避免因数据划分过程引入额外的偏差而对最终结果产生影响;
- 弊端:测试集小时,评估结果的方差较大;训练集小时,评估结果的偏差较大;
- 一般而言,测试集至少应含30个样例,若令训练集S包含绝大多数样本,则训练出的模型可能更接近于用D训练出的模型,但由于T比较小,评估结果可能不够稳定准确;若令测试集T多包含一些样本,则训练集S与D差别更大了,被评估的模型与用D训练出的模型相比可能有较大差别,从而降低了评估结果的保真性(fidelity)。
- 这个问题没有完美的解决方案,常见做法是将大约2/3~4/5的样本用于训练,剩余样本用于测试。
from sklearn.model_selection import train_test_split
# 导入模块
X_train,X_test, y_train, y_test =train_test_split(train_data,train_target,test_size=0.25, random_state=0,stratify=y)
# train_data:所要划分的样本特征集
# train_target:所要划分的样本结果
# test_size:样本占比,如果是整数的话就是样本的数量
# random_state:是随机数的种子。
# 随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
交叉验证法
先将数据集D划分为k个大小相似的互斥子集,即D=D1∪D2∪...∪Dk,Di∩Dj= (i≠j)。每个子集Di都尽可能保持数据分布的一致性,即从D中通过分层采样得到。然后,每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集;这样就可获得k组训练/测试集,从而可进行k次训练和测试,最终返回的是这k个测试结果的均值。
- 与留出法相似,将数据集D划分为k个子集同样存在多种划分方式。为减小因样本划分不同而引入的差别,k折交叉验证通常要随机使用不同的划分重复p次,最终的评估结果是这p次k折交叉验证结果的均值,例如常见的有“10次10折交叉验证”。
- 假定数据集D中包含m个样本,若令k=m,则得到了交叉验证法的一个特例:留一法(Leave-One-Out,简称LOO)。显然,留一法不受随机样本划分方式的影响,因为m个样本只有唯一的方式划分为m个子集――每个子集包含一个样本;留一法使用的训练集与初始数据集相比只少了一个样本,这就使得在绝大多数情况下,留一法中被实际评估的模型与期望评估的用D训练出的模型很相似。
- 留一法缺陷:在数据集比较大时,训练m个模型的计算开销可能是难以忍受的(例如数据集包含1百万个样本,则需训练1百万个模型)
- 由于保留了一部分样本用于测试,因此实际评估的模型所使用的训练集比D小,这必然会引入一些因训练样本规模不同而导致的估计偏差。
import numpy as np
from sklearn.model_selection import KFold
# 导入模块
KFold(n_splits=3, shuffle=False, random_state=None)
# n_splits:表示划分几等份
# shuffle:在每次划分时,是否进行洗牌
# ①若为Falses时,其效果等同于random_state等于整数,每次划分的结果相同
# ②若为True时,每次划分的结果都不一样,表示经过洗牌,随机取样的
# random_state:随机种子数,如果设置了具体数值比如42(随便一个具体数值),那么每次运行结果都是一样的,不会随机产生结果,即每次运行结果都可以复现
自助法
给定包含m个样本的数据集D,我们对它进行采样产生数据集D′:每次随机从D中挑选一个样本,将其拷贝放入D′,然后再将该样本放回初始数据集D中,使得该样本在下次采样时仍有可能被采到;这个过程重复执行m次后,我们就得到了包含m个样本的数据集D′,这就是自助采样的结果。
- 显然,D中有一部分样本会在D′中多次出现,而另一部分样本不出现。
- 可以做一个简单的估计,样本在m次采样中始终不被采到的概率是[插图],取极限得到
- 通过自助采样,初始数据集D中约有36.8%的样本未出现在采样数据集D中。于是我们可将D′用作训练集,D\D′用作测试集;这样,实际评估的模型与期望评估的模型都使用m个训练样本,而我们仍有数据总量约1/3的、没在训练集中出现的样本用于测试。这样的测试结果,亦称“包外估计”(out-of-bag estimate)。
- 自助法产生的数据集改变了初始数据集的分布,这会引入估计偏差。
from sklearn.utils import resample
resample(*arrays, replace=True, n_samples=None, random_state=None, stratify=None)
*arrays:形状(n_个样本)或(n_个样本,n_个输出)的类似数组的序列
# 可索引数据结构可以是数组、列表、数据帧或具有一致第一维度的scipy稀疏矩阵
#replace:bool, default=True
# 使用替换实现重采样。如果为False,这将实现(切片)随机排列。
#n_samples:int, default=None 要生成的样本数
#random_state:int, RandomState instance or None, default=None 确定随机数的生成,以洗牌数据
#stratify:类似数组的形状(n_个样本)或(n_个样本,n_个输出),默认无
总结
自助法的数据集较小、难以有效划分训练集合测试计时很有用,但他拷贝产生的新集合改变了初始数据集的分布,这也会引入估计偏差。因此在初始数据规模足够时,我们更多采用流出法和交叉验证法。
性能度量
错误率与精度
错误率是分类错误的样本数占样本总数的比例。
精度则是分类正确的样本数占样本总数的比例。
查准率、查全率与F1
真正例(true positive)、假正例(false positive)、真反例(true negative)、假反例(false negative)
查准率和查全率是一对矛盾的度量。
一般来说,查准率高时,查全率往往偏低;而查全率高时,查准率往往偏低。
以查准率为纵轴、查全率为横轴作图,就得到了查准率-查全率曲线,简称“P-R曲线”,显示该曲线的图称为“P-R图”。
- 为绘图方便和美观,示意图显示出单调平滑曲线;但现实任务中的P-R曲线常是非单调、不平滑的,在很多局部有上下波动。
- 在进行比较时,若一个学习器的P-R曲线被另一个学习器的曲线完全“包住”,则可断言后者的性能优于前者。如果两个学习器的P-R曲线发生了交叉,例如图2.3中的A与B,则难以一般性地断言两者孰优孰劣,只能在具体的查准率或查全率条件下进行比较。
- 一个比较合理的判据是比较P-R曲线下面积的大小,它在一定程度上表征了学习器在查准率和查全率上取得相对“双高”的比例。
- 这个值不太容易估算,因此,人们设计了一些综合考虑查准率、查全率的性能度量。“平衡点”(Break-Even Point,简称BEP)就是这样一个度量,它是“查准率=查全率”时的取值
- F1:
在一些应用中,对查准率和查全率的重视程度有所不同。
β=1时退化为标准的F1;β>1时查全率有更大影响;β<1时查准率有更大影响。
很多时候我们有多个二分类混淆矩阵,例如进行多次训练/测试,每次得到一个混淆矩阵;或是在多个数据集上进行训练/测试,希望估计算法的“全局”性能;甚或是执行多分类任务,每两两类别的组合都对应一个混淆矩阵;总之,我们希望在n个二分类混淆矩阵上综合考察查准率和查全率。
一种直接的做法是先在各混淆矩阵上分别计算出查准率和查全率,记为(P1,R1),(P2,R2),...,(Pn,Rn),再计算平均值,这样就得到“宏查准率”(macro-P)、“宏查全率”(macro-R),以及相应的“宏F1”(macro-F1):
还可先将各混淆矩阵的对应元素进行平均,得到TP、FP、TN、FN的平均值,再基于这些平均值计算出“微查准率”(micro-P)、“微查全率”(micro-R)和“微F1”(micro-F1):
ROC与AUC
很多学习器是为测试样本产生一个实值或概率预测,然后将这个预测值与一个分类阈值(threshold)进行比较,若大于阈值则分为正类,否则为反类。
ROC全称是“受试者工作特征”(Receiver Operating Characteristic)曲线。我们根据学习器的预测结果对样例进行排序,按此顺序逐个把样本作为正例进行预测,每次计算出两个重要量的值,分别以它们为横、纵坐标作图,就得到了“ROC曲线”。
ROC曲线的纵轴是“真正例率”(True Positive Rate,简称TPR),横轴是“假正例率”(False Positive Rate,简称FPR),基于表2.1中的符号,两者分别定义为
显示ROC曲线的图称为“ROC图”
对角线对应于“随机猜测”模型,而点(0,1)则对应于将所有正例排在所有反例之前的“理想模型”。
基于有限个测试样例绘制P-R图时有同样问题。
现实任务中通常是利用有限个测试样例来绘制ROC图,此时仅能获得有限个(真正例率,假正例率)坐标对,无法产生图2.4(a)中的光滑ROC曲线,只能绘制出如图2.4(b)所示的近似ROC曲线。绘图过程很简单:给定m+个正例和m-个反例,根据学习器预测结果对样例进行排序,然后把分类阈值设为最大,即把所有样例均预测为反例,此时真正例率和假正例率均为0,在坐标(0,0)处标记一个点。然后,将分类阈值依次设为每个样例的预测值,即依次将每个样例划分为正例。设前一个标记点坐标为(x,y)
当前若为真正例,则对应标记点的坐标为
当前若为假正例,则对应标记点的坐标为
然后用线段连接相邻点即得。
进行学习器的比较时,与P-R图相似,若一个学习器的ROC曲线被另一个学习器的曲线完全“包住”,则可断言后者的性能优于前者;若两个学习器的ROC曲线发生交叉,则难以一般性地断言两者孰优孰劣。此时如果一定要进行比较,则较为合理的判据是比较ROC曲线下的面积,即AUC(Area UnderROC Curve)
从定义可知,AUC可通过对ROC曲线下各部分的面积求和而得。假定ROC曲线是由坐标为{(x1,y1),(x2,y2),...,(xm,ym)}的点按序连接而形成(x1=0,xm=1),参见图2.4(b),则AUC可估算为
形式化地看,AUC考虑的是样本预测的排序质量,因此它与排序误差有紧密联系。给定m+个正例和m-个反例,令D+和D-分别表示正、反例集合,则排序“损失”(loss)定义为
即考虑每一对正、反例,若正例的预测值小于反例,则记一个“罚分”,若相等,则记0.5个“罚分”。容易看出,[插图]rank对应的是ROC曲线之上的面积:若一个正例在ROC曲线上对应标记点的坐标为(x,y),则x恰是排序在其之前的反例所占的比例,即假正例率。因此有
代价敏感错误率与代价曲线
为权衡不同类型错误所造成的不同损失,可为错误赋予“非均等代价”(unequal cost)。
一般情况下,重要的是代价比值而非绝对值,例如cost01:cost10=5:1与50:10所起效果相当。以二分类任务为例,我们可根据任务的领域知识设定一个“代价矩阵”(cost matrix),如表2.2所示,其中costij表示将第i类样本预测为第j类样本的代价。一般来说,costij=0;若将第0类判别为第1类所造成的损失更则cost01>cost10;损失程度相差越大,cost01与cost10值的差别越大。
在非均等代价下,我们所希望的不再是简单地最小化错误次数,而是希望最小化“总体代价”(total cost)。若将表2.2中的第0类作为正类、第1类作为反类,令D+与D-分别代表样例集D的正例子集和反例子集,则“代价敏感”(cost-sensitive)错误率为
在非均等代价下,ROC曲线不能直接反映出学习器的期望总体代价,而“代价曲线”(cost curve)则可达到该目的。代价曲线图的横轴是取值为[0,1]的正例概率代价
“规范化”(normaliza-tion)是将不同变化范围的值映射到相同的固定范围中,常见的是[0,1],此时亦称“归一化”。参见习题(2.8 Min-max规范化和z-score规范化是两种常用的规范化方法。令x和x′分别表示变量在规范化前后的取值,相应的,令xmin和xmax表示规范化前的最小值和最大值,x′min和x′max表示规范化后的最小值和最大值,[插图]和σx分别表示规范化前的均值和标准差,则min-max规范化、z-score规范化分别如式
其中p是样例为正例的概率;纵轴是取值为[0,1]的归一化代价
其中FPR是式(2.19)定义的假正例率,FNR=1-TPR是假反例率。代价曲线的绘制很简单:ROC曲线上每一点对应了代价平面上的一条线段,设ROC曲线上点的坐标为(FPR,TPR),则可相应计算出FNR,然后在代价平面上绘制一条从(0,FPR)到(1,FNR)的线段,线段下的面积即表示了该条件下的期望总体代价;如此将ROC曲线上的每个点转化为代价平面上的一条线段,然后取所有线段的下界,围成的面积即为在所有条件下学习器的期望总体代价。
偏差与方差
“偏差-方差分解”(bias-variance decomposition)是解释学习算法泛化性能的一种重要工具。
偏差-方差分解
泛化误差可分解为偏差、方差与噪声之和。
回顾偏差、方差、噪声的含义:
偏差(2.40)度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力;
方差(2.38)度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响;
噪声(2.39)则表达了在当前任务上任何学习算法所能达到的期望泛化误差的下界,即刻画了学习问题本身的难度。
偏差-方差分解说明,泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度所共同决定的。给定学习任务,为了取得好的泛化性能,则需使偏差较小,即能够充分拟合数据,并且使方差较小,即使得数据扰动产生的影响小。
很多学习算法都可控制训练程度,例如决策树可控制层数,神经网络可控制训练轮数,集成学习方法可控制基学习器个数。