《机器学习》第2章
1、ROC曲线
ROC(Receiver Operating Characteristic,受试者工作特征),其主要分析工具是一个画在二维平面上的曲线——ROC 曲线,可衡量学习器的性能。ROC曲线的纵轴和横轴分别为TPR(Ture positive rare,真正例率)和FPR(False positive rare,假正例率)。两者定义为TPR=TP/(TP+FN),FPR=FP/(TN+FP) 。其中TP(True Positive,真正):被模型预测为正的正样本。FN(False Negative,假负):被模型预测为负的正样本。FP(False Positive,假正):被模型预测为正的负样本。TN(True Negative,真负):被模型预测为负的负样本。
调整这个分类器分类时候使用的阈值,我们就可以得到一个经过(0, 0),(1, 1)的曲线,这就是此分类器的ROC曲线。一般情况下,这个曲线都应该处于(0, 0)和(1, 1)连线的上方。如果很不幸,你得到一个位于此直线下方的分类器的话,一个直观的补救办法就是把所有的预测结果反向,即:分类器输出结果为正类,则最终分类的结果为负类,反之,则为正类。
若一个学习器的ROC曲线被另一个学习器的曲线包住,则可断言后者性能优于前者;若两个学习器的ROC曲线交叉,可以通过比较ROC曲线下的面积,即AUC来判断。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,AUC的值介于0.5到1.0之间,较大的AUC代表了较好的性能。
image在实际的数据集中经常会出现类不平衡(class imbalance)现象,即正负样本数量差别很大。而ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。而P-R曲线变化较大,这是ROC曲线的优势所在。
2、P-R曲线
以查准率为纵轴、查全率为横轴作图得到“P-R曲线”,用于衡量学习器的性能,其中查准率P=TP/(TP+FP);查全率R=TP/(TP+FN)
image如上图,若一个学习器的P-R曲线被另一个学习器的曲线完全包住,则可断言后者的性能优于前者。则学习器A的性能优于学习器C。如果两个学习器的P-R曲线发生了交叉,比较性能有三种办法:1.比较P-R曲线下面积的大小,它在一定程度下表示学习器在查准率和查全率取得相对“双高”的比例,但这个值不太容易估算2.平衡点(BEP)是一个综合考虑查准率和查全率的性能度量,它是查准率=查全率时的取值,基于BEP的比较,认为学习器A优于B
3、经验误差与过拟合
错误率:分类错误的样本数占样本总数的比例
精度=1-错误率
训练误差/经验误差:学习器在训练集上的误差
泛化误差:在新样本上的误差
为了得到在新样本上也能表现好的学习器,应该从训练样本中尽可能找出适合所有潜在样本的普遍规律。如果学习器把训练样本学的太好时,很可能已经把训练样本自身的一些特点当做了所有潜在样本都会具有的一般性质,使泛化功能下降,这叫过拟合。与其相对的是欠拟合,指训练样本的一般性质未学好。
image4、评估方法
我们通常使用测试集来测试学习器对新样本的判别能力,以测试集上的测试误差作为泛化误差的近似。注意测试集应该尽可能与训练集互斥。常见的做法有“留出法”、“交叉验证法”、“自助法”,将数据集划分为训练集和测试集,使用测试集的判别效果来估计学习器在新样本上的泛化能力。
4.1留出法
留出法将数据集D划分为两个互斥的训练集S和测试集T,因为存在多种划分的方式,所以要按给定比例进行若干次随机划分,在进行n次评估后,返回n次结果的均值。例如数据集D有500个正例和500反例,按70%训练集、30%测试集划分,得到了训练集包含350正例、350反例,测试集包含150正例、150反例。通常将2/3~4/5的样本用于训练,剩余用作测试。
# 留出法顺序分割 方法一:
def HoldOut(df, M):
test = df[:M]
train = df[M:]
return train , test
# 留出法 方法二:
from sklearn.model_selection import train_test_split
train_data, test_data = train_test_split(data, test_size=0.2)
4.2交叉验证法
交叉验证法,把数据集分成k个大小相似的互斥子集,每个子集尽可能数据分布一致。然后每次把k-1个子集当成训练集,剩下一个当成测试集,从而可进行k次训练和测试,最终返回k次结果的均值。显然,交叉验证法评估结果的稳定性和保真性很大程度取决于k,通常把交叉验证法称为k折交叉验证。
imagek折交叉验证通常要使用不同的划分重复p次,最终的评估结果是这p次k折交叉验证结果的均值,常见的有10次10折交叉验证。若数据集包含m个样本,令k=m,得到交叉验证法的特例:留一法。因为每个子集只包含一个样本,因此不受随机样本划分的影响。留一法的训练集比初始数据集只少了一个样本,因此评估结果往往被认为比较准确。但数据集很大时耗费资源也多
# K次交叉验证
from sklearn.model_selection import KFold
kf = KFold(n_splits=2) # 设置k的次数
for train_index, test_index in kf.split(df):
print("TRAIN:", train_index, "TEST:", test_index)
train_data_kf, test_data_kf = df[train_index], df[test_index]
4.3自助法
给定包含m个样本的数据集D,对它采样m次产生数据集D’:每次随机从D中挑选一个样本,将其拷贝放入D’,然后再将样本放回初始数据集D中,使得该样本在下次采样仍有可能被采到,这个过程重复执行m次,就得到包含m个样本的数据集D’,这就是自主采样的结果。显然,D中有一部分样本会在D’中多次出现,而另一部分不出现。通过自主采样,初始数据集D中约有36.8%的样本未出现在D’中。D’作为训练集,D/D'用作测试集来对学习器进行评估。
在初始数据量足够时,留出法和交叉验证法更常用,自助法在数据集较小,难以有效划分训练集/测试集有用。
# 自助法
def SplitData(df, M, k, seed):
test = []
train = []
random.seed(seed)
for users, items in df:
if random.randint(0, M) == k:
test.append([users, items])
else:
train.append([users, items])
return train , test
参考简书
完整代码请参考码云