一、模型评估概述
1.什么是模型评估
模型评估是对训练好的模型性能进行评估, 模型评估是模型开发过程不可或缺的一部分。它有助于发现表达数据的最佳模型和所选模型将来工作的性能如何。
2.模型评估的类型
机器学习的任务有回归,分类和聚类,针对不同的任务有不同的评价指标。按照数据集的目标值不同,可以把模型评估分为分类模型评估和回归模型评估。
3.过拟合、欠拟合
3.1过拟合
什么是过拟合
过拟合其实就是为了得到一致假设而使得假设过于地严格。使得其在训练集上的表现非常地完美,但是在训练集以外的数据集却表现不好。
如上图所示,蓝线就是过拟合了,虽然它在训练集上将所有的点都放在了线上,但是如果再来一个点就会不起作用,这就是过拟合,而绿线的话也比较好地拟合了点集,但是它的泛化能力相较于蓝线来说是更好的
解决办法
1.增加训练数据数
2.使用正则化约束
3.减少特征值
4.调整超参数和参数
5.降低模型的复杂度
6.使用Dropout
7.提前结束训练
3.2欠拟合
什么是欠拟合
欠拟合(或称:拟合不足、欠配,英文:underfitting)是指模型在训练数据上没有获得充分小的误差.造成欠拟合的原因通常是模型学习能力过低,具体地说,就是模型参数过少或者结构过于简单,以至于无法学习到数据的内在结构和特征.例如,当用一个线性模型去拟合非线性数据时,会发生欠拟合.由此,可以通过增加模型参数和复杂度,提高学习能力,从而解决欠拟合问题.与欠拟合相对应的,是过度拟合.
解决办法
1.模型复杂化
2.增加更多特征,使输入具有更强的表达能力
3.调整参数和超参数
4.降低正则化约束
4.模型泛化能力
泛化能力(generalization ability)是指机器学习算法对新鲜样本的适应能力。
机器学习的目的是学到隐含在数据背后的规律,对具有同一规律的学习集以外的数据,经过训练的网络也能给出合适的输出,该能力称为泛化能力。
规律适用于现有数据,同样也适用于新鲜数据。
二、常见的分类模型评估
1. 混淆矩阵
混淆矩阵是监督学习中的一种可视化工具,主要用于模型的分类结果和实例的真实信息的比较 。
矩阵中的每一行代表实例的预测类别,每一列代表实例的真实类别。
真实值是positive,模型认为是positive的数量(True Positive=TP)
真实值是positive,模型认为是negative的数量(False Negative=FN):这就是统计学上的第一类错误(Type I Error)
真实值是negative,模型认为是positive的数量(False Positive=FP):这就是统计学上的第二类错误(Type II Error)
真实值是negative,模型认为是negative的数量(True Negative=TN)
将这四个指标一起呈现在表格中,就能得到如下这样一个矩阵,我们称它为混淆矩阵(Confusion Matrix):
注意:预测性分类模型,肯定是希望越准越好。那么,对应到混淆矩阵中,那肯定是希望TP与TN的数量大,而FP与FN的数量小。所以当我们得到了模型的混淆矩阵后,就需要去看有多少观测值在第二、四象限对应的位置,这里的数值越多越好;反之,在第一、三四象限对应位置出现的观测值肯定是越少越好。
2. 准确率Accuracy
准确率是最常用的分类性能指标。
Accuracy = (TP+TN)/(TP+FN+FP+TN)
预测正确的数占样本总数的比例,即正确预测的正反例数 /总数。
3. 精确率(Precision)
精确率容易和准确率被混为一谈。
其实,精确率只是针对预测正确的正样本而不是所有预测正确的样本。
表现为预测出是正的里面有多少真正是正的。可理解为查准率。
Precision = TP/(TP+FP)
即正确预测的正例数 /预测正例总数
4. 召回率recall
召回率表现出在实际正样本中,分类器能预测出多少。
与真正率相等,可理解为查全率。正确预测为正占全部正校本的比例
Recall = TP/(TP+FN),即正确预测的正例数 /实际正例总数
5. F1-score:主要用于评估模型的稳健性
F值是精确率和召回率的调和值,更接近于两个数较小的那个,所以精确率和召回率接近时,F值最大。很多推荐系统的评测指标就是用F值的。
2/F1 = 1/Precision + 1/Recall
6. AUC指标:主要用于评估样本不均衡的情况
逻辑回归里面,对于正负例的界定,通常会设一个阈值,大于阈值的为正类,小于阈值为负类。如果我们减小这个阀值,更多的样本会被识别为正类,提高正类的识别率,但同时也会使得更多的负类被错误识别为正类。为了直观表示这一现象,引入ROC。根据分类结果计算得到ROC空间中相应的点,连接这些点就形成ROC curve,横坐标为False Positive Rate(FPR假正率),纵坐标为True Positive Rate(TPR真正率)。一般情况下,这个曲线都应该处于(0,0)和(1,1)连线的上方,如图:
7. AUC
AUC(Area Under Curve)被定义为ROC曲线下的面积(ROC的积分),通常大于0.5小于1。随机挑选一个正样本以及一个负样本,分类器判定正样本的值高于负样本的概率就是 AUC 值。AUC值(面积)越大的分类器,性能越好,如图
8. PR曲线
PR曲线的横坐标是精确率P,纵坐标是召回率R。评价标准和ROC一样,先看平滑不平滑(蓝线明显好些)。一般来说,在同一测试集,上面的比下面的好(绿线比红线好)。当P和R的值接近时,F1值最大,此时画连接(0,0)和(1,1)的线,线和PRC重合的地方的F1是这条线最大的F1(光滑的情况下),此时的F1对于PRC就好像AUC对于ROC一样。一个数字比一条线更方便调型。
三、ROC 曲线与PR曲线的差异
1.ROC曲线的优势
相比P-R曲线,ROC曲线有个很好的特性:当测试集中的正负样本的分布发生变化的时候,ROC曲线能够保持稳定。在实际的数据集中经常会出现类不平衡现象,而且测试数据中的正负样本的分布也可能随着时间变化。下图是ROC曲线和Precision-Recall曲线的对比。
如下图:其中各图详情如下:
(a)和(c)为ROC曲线,
(b)和(d)为Precision-Recall曲线。
(a)和(b)展示的是分类器在原始测试集(正负样本分布平衡)的结果,
(c)和(d)是将测试集中负样本的数量增加到原来的10倍。(正负样本分布不均衡)
可以明显看出,ROC曲线基本保持原貌,而Precision-Recall曲线则变化较大。这个特点让ROC曲线能够尽量降低不同测试集带来的干扰,更加客观地衡量模型本身的性能。
PR曲线会面临一个问题,当需要获得更高recall时,model需要输出更多的样本,precision可能会伴随出现下降/不变/升高,得到的曲线会出现浮动差异(出现锯齿),无法像ROC一样保证单调性。所以,对于正负样本分布大致均匀的问题,ROC曲线作为性能指标更好。
2.PRC曲线的优势
在正负样本分布得极不均匀(highly skewed datasets),负例远大于正例时,并且这正是该问题正常的样本分布时,PRC比ROC能更有效地反应分类器的好坏,即PRC曲线在正负样本比例悬殊较大时更能反映分类的真实性能。例如上面的(c)(d)中正负样本比例为1:10,ROC效果依然看似很好,但是PR曲线则表现的比较差。举个例子,
单从图(a)看,这两个分类器都比较完美(非常接近左上角)。而从图(b)可以看出,这两个分类器仍有巨大的提升空间。那么原因是什么呢? 通过看Algorithm1的点 A,可以得出一些结论。首先图(a)和(b中)的点A是相同的点,因为TPR就是Recall,两者是一样的。
假设数据集有100个正样本。可以得到以下结论(反推样本个数):
由图(a)点A,可得:TPR=TP/(TP+FN)=TP/所有正样本 =TP/100=0.8,所以TP=80。
由图(b)点A,可得:Precision=TP/(TP+FP)=80/(80+FP)=0.05,所以FP=1520。
再由图(a)点A,可得:FPR=FP/(FP+TN)=FP/所有负样本=1520/所有负样本=0.1,所以负样本数量是15200。
由此,可以得出原数据集中只有100个正样本,却有15200个负样本!这就是极不均匀的数据集。直观地说,在点A处,分类器将1600 (1520+80)个样本预测为positive,而其中实际上只有80个是真正的positive。 我们凭直觉来看,其实这个分类器并不好。但由于真正negative instances的数量远远大约positive,ROC的结果却“看上去很美”,因为这时FPR因为负例基数大的缘故依然很小。所以,在这种情况下,PRC更能体现本质。
3.表现差异的原因
FPR 和 TPR (Recall) 只与真实的正例或负例中的一个相关(可以从他们的计算公式中看到),而其他指标如Precision则同时与真实的正例与负例都有关,即下面文字说的“both columns”,这可以结合混淆矩阵和各指标的计算公式明显看到。
4.实际应用
在很多实际问题中,正负样本数量往往很不均衡。比如,计算广告领域经常涉及转化率模型,正样本的数量往往是负样本数量的1/1000甚至1/10000。若选择不同的测试集,P-R曲线的变化就会非常大,而ROC曲线则能够更加稳定地反映模型本身的好坏。所以,ROC曲线的适用场景更多,被广泛用于排序、推荐、广告等领域。
需要注意的是,选择P-R曲线还是ROC曲线是因实际问题而异的,如果希望更多地看到模型在特定数据集上的表现,P-R曲线则能够更直观地反映其性能。”
四、具体实现
1.绘制PR曲线
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.font_manager import FontProperties
def plot(dict,lists):#画出函数图像
fig = plt.figure()
font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14)
plt.xlabel('查全率(R)',fontproperties=font)
plt.ylabel('查准率(P)',fontproperties=font)
x = np.arange(0,1.0,0.2)
y = np.arange(0,1.0,0.2)
plt.xticks(x)
plt.yticks(y)
plt.plot(dict,lists)
plt.show()
def caculate():
num_real = 0
#初始化样本标签,假设1为正例,0为负例
trainlabel = np.random.randint(0,2,size=100)
#产生100个概率值(置信度),即单个样本值为正例的概率
traindata = np.random.rand(100)
#将样本数据为正例概率从大到小排序返回索引值
sortedTraindata = traindata.argsort()[::-1]
k = []
v = []
#统计样本中实际正例的数量
num = np.sum(trainlabel==1)
for i in range(100):
num_guess = i+1#假设为真的数量
for j in range(0,i+1):
a = sortedTraindata[j]
if trainlabel[a] == 1:
num_real += 1#假设为真中实际也为真的数量
p = float(num_real/(num_guess))
r = float(num_real/(num))
v.append(p)
k.append(r)
num_real = 0
plot(k,v)
if __name__=='__main__':
caculate()
结果:
2.绘制ROC曲线
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.font_manager import FontProperties
def plot(tpr,fpr):#画出函数图像
fig = plt.figure()
font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14)
plt.xlabel('假正例率(FPR)',fontproperties=font)
plt.ylabel('真正例率(TPR)',fontproperties=font)
x = np.arange(0,1.1,0.2)
y = np.arange(0,1.1,0.2)
plt.xticks(x)
plt.yticks(y)
plt.plot(fpr,tpr)
x1 = np.arange(0, 1.0, 0.1)
plt.plot(x1, x1, color='blue', linewidth=2, linestyle='--')
plt.show()
def caculate():
tp = 0
#初始化样本标签,假设1为正例,0为负例
trainlabel = np.random.randint(0,2,size=100)
#产生100个概率值(置信度),即单个样本值为正例的概率
traindata = np.random.rand(100)
#将样本数据为正例概率从大到小排序返回索引值
sortedTraindata = traindata.argsort()[::-1]
k = []
v = []
#统计样本中实际正例的数量
num = np.sum(trainlabel==1)
num1 = 100 - num
for i in range(100):
num_guess = i+1#假设为真的数量
for j in range(0,i+1):
a = sortedTraindata[j]
if trainlabel[a] == 1:
tp += 1#假设为真中实际也为真的数量
fp = num_guess - tp
fpr = float(fp/(num1))
tpr = float(tp/(num))
v.append(fpr)
k.append(tpr)
tp = 0
plot(k,v)
if __name__=='__main__':
caculate()
结果: