机器学习之模型评估

本文详细介绍了模型评估的基本概念、过拟合和欠拟合的解决方法,以及常见的分类模型评估指标如混淆矩阵、准确率、精确率、召回率、F1-score、AUC和ROC曲线与PR曲线的区别。强调了在不同数据分布情况下的选择和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、模型评估概述

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()

结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值