机器学习-sklearn第十天——笔记

本文深入探讨了SVM中的二分类SVC,解析了参数C如何影响决策边界和处理样本不均衡问题,介绍了class_weight参数的应用。此外,文章详细阐述了模型评估指标,包括混淆矩阵、ROC曲线、AUC面积,并展示了如何通过ROC曲线确定最佳阈值。最后,讨论了在实际应用中如何根据业务需求平衡精确度、召回率和成本。
摘要由CSDN通过智能技术生成

sklearn中的支持向量机SVM(下)

1 二分类SVC的进阶

1.1 SVC用于二分类的原理复习

支持向量机分类器,是在数据空间中找出一个超平面作为决策边界,利用这个决策边界来对数据进行分类,并使分类误差尽量小的模型。

1.2 参数C的理解进阶

有一些数据,可能是线性可分,但在线性可分状况下训练准确率不能达到100%,即无法让训练误差为0,这样的数据被我们称为“存在软间隔的数据”。此时此刻,我们需要让我们决策边界能够忍受一小部分训练误差,我们就不能单纯地寻求最大边际了。
因为对于软间隔地数据来说,边际越大被分错的样本也就会越多,因此我们需要找出一个”最大边际“与”被分错的样本数量“之间的平衡。因此,我们引入松弛系数 和松弛系数的系数C作为一个惩罚项,来惩罚我们对最大边际的追求。
那我们的参数C如何影响我们的决策边界呢?在硬间隔的时候,我们的决策边界完全由两个支持向量和最小化损失函数(最大化边际)来决定,而我们的支持向量是两个标签类别不一致的点,即分别是正样本和负样本。然而在软间隔情况下我们的边际依然由支持向量决定,但此时此刻的支持向量可能就不再是来自两种标签类别的点了,而是分布在决策边界两边的,同类别的点软间隔让决定两条虚线超平面的支持向量可能是来自于同一个类别的样本点,而硬间隔的时候两条虚线超平面必须是由来自两个不同类别的支持向量决定的。

1.3 二分类SVC中的样本不均衡问题

重要参数class_weight
对于分类问题,永远都逃不过的一个痛点就是样本不均衡问题。样本不均衡是指在一组数据集中,标签的一类天生占有很大的比例,但我们有着捕捉出某种特定的分类的需求的状况。比如,我们现在要对潜在犯罪者和普通人进行分类,潜在犯罪者占总人口的比例是相当低的,也许只有2%左右,98%的人都是普通人,而我们的目标是要捕获出潜在犯罪者。这样的标签分布会带来许多问题。
首先,分类模型天生会倾向于多数的类,让多数类更容易被判断正确,少数类被牺牲掉。因为对于模型而言,样本量越大的标签可以学习的信息越多,算法就会更加依赖于从多数类中学到的信息来进行判断。如果我们希望捕获少数类,模型就会失败。其次,模型评估指标会失去意义。这种分类状况下,即便模型什么也不做,全把所有人都当成不会犯罪的人,准确率也能非常高,这使得模型评估指标accuracy变得毫无意义,根本无法达到我们的“要识别出会犯罪的人”的建模目的。所以现在,我们首先要让算法意识到数据的标签是不均衡的,通过施加一些惩罚或者改变样本本身,来让模型向着捕获少数类的方向建模。然后,我们要改进我们的模型评估指标,使用更加针对于少数类的指标来优化模型。要解决第一个问题,我们在逻辑回归中已经介绍了一些基本方法,比如上采样下采样。但这些采样方法会增加样本的总数,对于支持向量机这个样本总是对计算速度影响巨大的算法来说,我们完全不想轻易地增加样本数量。况且,支持向量机中地决策仅仅决策边界的影响,而决策边界又仅仅受到参数C和支持向量的影响,单纯地增加样本数量不仅会增加计算时间,可能还会增加无数对决策边界无影响的样本点。因此在支持向量机中,我们要大力依赖
我们调节样本均衡的参数:SVC类中的class_weight和接口fit中可以设定的sample_weight。在逻辑回归中,参数class_weight默认None,此模式表示假设数据集中的所有标签是均衡的,即自动认为标签的
比例是1:1。所以当样本不均衡的时候,我们可以使用形如{“标签的值1”:权重1,“标签的值2”:权重2}的字典来输入真实的样本标签比例,来让算法意识到样本是不平衡的。或者使用”balanced“模式,直接使用n_samples/(n_classes * np.bincount(y))作为权重,可以比较好地修正我们的样本不均衡情况。但在SVM中,我们的分类判断是基于决策边界的,而最终决定究竟使用怎样的支持向量和决策边界的参数是参数C,所以所有的样本均衡都是通过参数C来调整的。

  1. 导入需要的库和模块
    在这里插入图片描述

  2. 创建样本不均衡的数据集
    在这里插入图片描述

  3. 在数据集上分别建模
    在这里插入图片描述

  4. 绘制两个模型下数据的决策边界
    在这里插入图片描述
    在这里插入图片描述

可以看出,从准确率的角度来看,不做样本平衡的时候准确率反而更高,做了样本平衡准确率反而变低了,这是因为做了样本平衡后,为了要更有效地捕捉出少数类,模型误伤了许多多数类样本,而多数类被分错的样本数量 > 少数类被分类正确的样本数量,使得模型整体的精确性下降。现在,如果我们的目的是模型整体的准确率,那我们就要拒绝样本平衡,使用class_weight被设置之前的模型。然而在现实中,我们往往都在追求捕捉少数类,因为在很多情况下,将少数类判断错的代价是巨大的。比如我们之前提到的,判断潜在犯罪者和普通人的例子,如果我们没有能够识别出潜在犯罪者,那么这些人就可能去危害社会,造成恶劣影响,但如果我们把普通人错认为是潜在犯罪者,我们也许只是需要增加一些监控和人为甄别的成本。所以对我们来说,我们宁愿把普通人判错,也不想放过任何一个潜在犯罪者。我们希望不惜一切代价来捕获少数类,或者希望捕捉出尽量多的少数类,那我们就必须使用class_weight设置后的模型。

2 SVC的模型评估指标

从上一节的例子中可以看出,如果我们的目标是希望尽量捕获少数类,那准确率这个模型评估逐渐失效,所以我们需要新的模型评估指标来帮助我们。如果简单来看,其实我们只需要查看模型在少数类上的准确率就好了,只要能够将少数类尽量捕捉出来,就能够达到我们的目的。但此时,新问题又出现了,我们对多数类判断错误后,会需要人工甄别或者更多的业务上的措施来一一排除我们判断错误的多数类,这种行为往往伴随着很高的成本。比如银行在判断”一个申请信用卡的客户是否会出现违约行为“的时候,如果一个客户被判断为”会违约“,这个客户的信用卡申请就会被驳回,如果为了捕捉出”会违约“的人,大量地将”不会违约“的客户判断为”会违约“的客户,就会有许多无辜的客户的申请被驳回。信用卡对银行来说意味着利息收入,而拒绝了许多本来不会违约的客户,对银行来说就是巨大的损失。同理,大众在召回不符合欧盟标准的汽车时,如果为了找到所有不符合标准的汽车,而将一堆本来符合标准了的汽车召回,这个成本是不可估量的。也就是说,单纯地追求捕捉出少数类,就会成本太高,而不顾及少数类,又会无法达成模型的效果。所以在现实中,我们往往在寻找捕获少数类的能力和将多数类判错后需要付出的成本的平衡。如果一个模型在能够尽量捕获少数类的情况下,还能够尽量对多数类判断正确,则这个模型就非常优秀了。为了评估这样的能力,我们将引入新的模型评估指标:混淆矩阵和ROC曲线来帮助我们。

2.1 混淆矩阵(Confusion Matrix)

混淆矩阵是二分类问题的多维衡量指标体系,在样本不平衡时极其有用。在混淆矩阵中,我们将少数类认为是正例,多数类认为是负例。在决策树,随机森林这些普通的分类算法里,即是说少数类是1,多数类是0。在SVM里,就是说少数类是1,多数类是-1。普通的混淆矩阵,一般使用{0,1}来表示。混淆矩阵阵如其名,十分容易让人混淆,在许多教材中,混淆矩阵中各种各样的名称和定义让大家难以理解难以记忆。我为大家找出了一种简化的方式来显示标准二分类的混淆矩阵,如图所示:
在这里插入图片描述

混淆矩阵中,永远是真实值在前,预测值在后。其实可以很容易看出,11和00的对角线就是全部预测正确的,01和10的对角线就是全部预测错误的。基于混淆矩阵,我们有六个不同的模型评估指标,这些评估指标的范围都在[0,1]之间,所有以11和00为分子的指标都是越接近1越好,所以以01和10为分子的指标都是越接近0越好。对于所有的指标,我们用橙色表示分母,用绿色表示分子,则我们有:

2.1.1 模型整体效果:准确率

在这里插入图片描述

2.1.2 捕捉少数类的艺术:精确度,召回率和F1 score

精确度Precision,又叫查准率,表示所有被我们预测为是少数类的样本中,真正的少数类所占的比例。在支持向量机中,精确度可以被形象地表示为决策边界上方的所有点中,红色点所占的比例。精确度越高,代表我们捕捉正确的红色点越多,对少数类的预测越精确。精确度越低,则代表我们误伤了过多的多数类。精确度是”将多数类判错后所需付出成本“的衡量。在现实的样本不平衡例子中,当每一次将多数类判断错误的成本非常高昂的时候(比如大众召回车辆的例子),我们会追求高精确度。精确度越低,我们对多数类的判断就会越错误。当然了,如果我们的目标是不计一切代价捕获少数类,那我们并不在意精确度。
在这里插入图片描述

召回率Recall,又被称为敏感度(sensitivity),真正率,查全率,表示所有真实为1的样本中,被我们预测正确的样本所占的比例。在支持向量机中,召回率可以被表示为,决策边界上方的所有红色点占全部样本中的红色点的比例。召回率越高,代表我们尽量捕捉出了越多的少数类,召回率越低,代表我们没有捕捉出足够的少数类.
如果我们希望不计一切代价,找出少数类(比如找出潜在犯罪者的例子),那我们就会追求高召回率,相反如果我们的目标不是尽量捕获少数类,那我们就不需要在意召回率。注意召回率和精确度的分子是相同的(都是11),只是分母不同。而召回率和精确度是此消彼长的,两者之间的平衡代表了捕捉少数类的需求和尽量不要误伤多数类的需求的平衡。究竟要偏向于哪一方,取决于我们的业务需求:究竟是误伤多数类的成本更高,还是无法捕捉少数类的代价更高。

2.1.3 判错多数类的考量:特异度与假正率

在这里插入图片描述

特异度衡量了一个模型将多数类判断正确的能力,而1 - specificity就是一个模型将多数类判断错误的能力,这种能力被计算如下,并叫做假正率(False Positive Rate):
在这里插入图片描述

在支持向量机中,假正率就是决策边界上方的紫色点(所有被判断错误的多数类)占所有紫色点的比例。根据我们之前在precision处的分析,其实可以看得出来,当样本均衡过后,假正率会更高,因为有更多紫色点被判断错误,而样本均衡之前,假正率比较低,被判错的紫色点比较少。所以假正率其实类似于Precision的反向指标,Precision衡量有多少少数点被判断正确,而假正率FPR衡量有多少多数点被判断错误,性质是十分类似的。

2.1.4 sklearn中的混淆矩阵

sklearn当中提供了大量的类来帮助我们了解和使用混淆矩阵。
在这里插入图片描述

2.2 ROC曲线以及其相关问题

基于混淆矩阵,我们学习了总共六个指标:准确率Accuracy,精确度Precision,召回率Recall,精确度和召回度的平衡指标F measure,特异度Specificity,以及假正率FPR。其中,假正率有一个非常重要的应用:我们在追求较高的Recall的时候,Precision会下降,就是说随着更多的少数类被捕捉出来,会有更多的多数类被判断错误,但我们很好奇,随着Recall的逐渐增加,模型将多数类判断错误的能力如何变化呢?我们希望理解,我每判断正确一个少数类,就有多少个多数类会被判断错误。假正率正好可以帮助我们衡量这个能力的变化。相对的,Precision无法判断这些判断错误的多数类在全部多数类中究竟占多大的比例,所以无法在提升Recall的过程中也顾及到模型整体的Accuracy。因此,我们可以使用Recall和FPR之间的平衡,来替代Recall和Precision之间的平衡,让我们衡量模型在尽量捕捉少数类的时候,误伤多数类的情况如何变化,这就是我们的ROC曲线衡量的平衡。ROC曲线,全称The Receiver Operating Characteristic Curve,译为受试者操作特性曲线。这是一条以不同阈值下的假正率FPR为横坐标,不同阈值下的召回率Recall为纵坐标的曲线。让我们先从概率和阈值开始讲起。

2.2.1 概率(probability)与阈值(threshold)
  1. 自建数据集
    在这里插入图片描述

  2. 建模,调用概率
    在这里插入图片描述

  3. 使用阈值0.5,大于0.5的样本被预测为1,小于0.5的样本被预测为0
    在这里插入图片描述

  4. 使用混淆矩阵查看结果
    在这里插入图片描述

  5. 假如我们使用0.4作为阈值呢?
    在这里插入图片描述

可见,在不同阈值下,我们的模型评估指标会发生变化,我们正利用这一点来观察Recall和FPR之间如何互相影响。但是注意,并不是升高阈值,就一定能够增加或者减少Recall,一切要根据数据的实际分布来进行判断。而要体现阈值的影响,首先必须的得到分类器在少数类下的预测概率。对于逻辑回归这样天生生成似然的算法和朴素贝叶斯这样就是在计算概率的算法,自然非常容易得到概率,但对于一些其他的分类算法,比如决策树,比如SVM,他们的分类方式和概率并不相关。那在他们身上,我们就无法画ROC曲线了吗?并非如此。决策树有叶子节点,一个叶子节点上可能包含着不同类的样本。假设一个样本被包含在叶子节点a中,节点a包含10个样本,其中6个为1,4个为0,则1这个正类在这个叶子节点中的出现概率就是60%,类别0在这个叶子节点中的出现概率就是40%。对于所有在这个叶子节点中的样本而言,节点上的1和0出现的概率,就是这个样本对应的取到1和0的概率,大家可以去自己验证一下。但是思考一个问题,由于决策树可以被画得很深,在足够深的情况下,决策树的每个叶子节点上可能都不包含多个类别的标签了,可能一片叶子中只有唯一的一个标签,即叶子节点的不纯度为0,此时此刻,对于每个样本而言,他们所对应的“概率”就是0或者1了。这个时候,我们就无法调节阈值来调
节我们的Recall和FPR了。对于随机森林,也是如此。所以,如果我们有概率需求,我们还是会优先追求逻辑回归或者朴素贝叶斯。不过其实,SVM也可以生成概率,我们一起来看看,它是怎么做的。

2.2.2 SVM实现概率预测

重要参数probability,接口predict_proba以及
decision_function
我们在画等高线,也就是决策边界的时候曾经使用SVC的接口decision_function,它返回我们输入的特征矩阵中每个样本到划分数据集的超平面的距离。我们在SVM中利用超平面来判断我们的样本,本质上来说,当两个点的距离是相同的符号的时候,越远离超平面的样本点归属于某个标签类的概率就很大。比如说,一个距离超平面0.1的点,和一个距离超平面100的点,明显是距离为0.1的点更有可能是负类别的点混入了边界。同理,一个距离超平面距离为-0.1的点,和一个离超平面距离为-100的点,明显是-100的点的标签更有可能是负类。所以,到超平面的距离一定程度上反应了样本归属于某个标签类的可能性。接口decision_function返回的值也因此被我们认为是SVM中的置信度(confidence)。probCM(prob.loc[:,“y_true”],prob.loc[:,“pred”],labels=[1,0])
P(prob.loc[:,“y_true”],prob.loc[:,“pred”],labels=[1,0])
R(prob.loc[:,“y_true”],prob.loc[:,“pred”],labels=[1,0])
#注意,降低或者升高阈值并不一定能够让模型的效果变好,一切都基于我们要追求怎样的模型效果
在这里插入图片描述

2.2.3 绘制SVM的ROC曲线

现在,我们理解了什么是阈值(threshold),了解了不同阈值会让混淆矩阵产生变化,也了解了如何从我们的分类算法中获取概率。现在,我们就可以开始画我们的ROC曲线了。ROC是一条以不同阈值下的假正率FPR为横坐标,不同阈值下的召回率Recall为纵坐标的曲线。简单地来说,只要我们有数据和模型,我们就可以在python中绘制出我们的ROC曲线。思考一下,我们要绘制ROC曲线,就必须在我们的数据中去不断调节阈值,不断求解混淆矩阵,然后不断获得我们的横坐标和纵坐标,最后才能够将曲线绘制出来。接下来,我们就来执行这个过程:
在这里插入图片描述

2.2.4 sklearn中的ROC曲线和AUC面积

在sklearn中,我们有帮助我们计算ROC曲线的横坐标假正率FPR,纵坐标Recall和对应的阈值的类sklearn.metrics.roc_curve。同时,我们还有帮助我们计算AUC面积的类sklearn.metrics.roc_auc_score。在一些比较老旧的sklearn版本中,我们使用sklearn.metrics.auc这个类来计算AUC面积,但这个类即将在0.22版本中被放弃,因此建议大家都使用roc_auc_score。来看看我们的这两个类:
sklearn.metrics.roc_curve (y_true, y_score, pos_label=None, sample_weight=None, drop_intermediate=True)
y_true : 数组,形状 = [n_samples],真实标签
y_score : 数组,形状 = [n_samples],置信度分数,可以是正类样本的概率值,或置信度分数,或者decision_function返回的距离pos_label : 整数或者字符串, 默认None,表示被认为是正类样本的类别sample_weight : 形如 [n_samples]的类数组结构,可不填,表示样本的权重drop_intermediate : 布尔值,默认True,如果设置为True,表示会舍弃一些ROC曲线上不显示的阈值点,这对于计算一个比较轻量的ROC曲线来说非常有用这个类以此返回:FPR,Recall以及阈值。

在这里插入图片描述
在这里插入图片描述

如此就得到了我们的ROC曲线和AUC面积,可以看到,SVM在这个简单数据集上的效果还是非常好的。并且大家可以通过观察我们使用decision_function画出的ROC曲线,对比一下我们之前强行使用概率画出来的曲线,两者非常相似,所以在无法获取模型概率的情况下,其实不必强行使用概率,如果有置信度,那也使可以完成我们的ROC曲线的。感兴趣的小伙伴可以画一下如果带上class_weight这个参数,模型的效果会变得如何。

2.2.5 利用ROC曲线找出最佳阈值

现在,有了ROC曲线,了解了模型的分类效力,以及面对样本不均衡问题时的效力,那我们如何求解我们最佳的阈值呢?我们想要了解,什么样的状况下我们的模型的效果才是最好的。回到我们对ROC曲线的理解来:ROC曲线反应的是recall增加的时候FPR如何变化,也就是当模型捕获少数类的能力变强的时候,会误伤多数类的情况是否严重。我们的希望是,模型在捕获少数类的能力变强的时候,尽量不误伤多数类,也就是说,随着recall的变大,FPR的大小越小越好。所以我们希望找到的最有点,其实是Recall和FPR差距最大的点。这个点,又叫做约登指数。
在这里插入图片描述
在这里插入图片描述

最佳阈值就这样选取出来了,由于现在我们是使用decision_function来画ROC曲线,所以我们选择出来的最佳阈值其实是最佳距离。如果我们使用的是概率,我们选取的最佳阈值就会使一个概率值了。只要我们让这个距离/概率以上的点,都为正类,让这个距离/概率以下的点都为负类,模型就是最好的:即能够捕捉出少数类,又能够尽量不误伤多数类,整体的精确性和对少数类的捕捉都得到了保证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值