代价敏感学习初探 - 有偏损失函数设计

1. 代价敏感学习简介

0x1:如何将业务场景中对FP和FN损失的不一样接受程度,调整咱们的损失函数

1. 什么场景下须要代码敏感学习

在不少真实业务场景中,包括笔者所在的网络安全领域,误报形成的损失经常比漏报来的要大,缘由很简单,若是一个IDS系统天天都在产生大量虚警,那么对事件响应处理人员的压力就会很是大,时间久了,你们对IDS的信任度就会降低,同时真实的有效告警也可能被淹没在海量的虚警中,反而致使更多和更严重的漏报。html

但另外一方面,可能有人会质疑说漏报的影响不是更恶劣吗?难道不该该秉着”宁肯错杀一千,不可放过一个可疑“的方针吗?算法

根据笔者目前的从业经验来看,没有必要这样。一个好的作法是构建多层次的纵深检测体系,大白话就是在一个KILLCHAIN的每个环节都有针对性地部署一个IDS,同时追求每一个IDS的精确度,对于单个IDS来讲,尽可能少误报,对于总体系统来讲,全部IDS综合起来构成了一个纵深体系,攻击者想要穿透这个体系而不引起任何的告警,就须要很是高超的技巧和当心翼翼的动做,而这有时候也反过来限制了攻击者所能作的动做,例如内网扫描这件事。安全

说完了代码敏感学习的应用场景,接下来的问题确定是:代价敏感函数是什么?简单的回答是:代价敏感学习是在原始标准代价损失函数的基础上,增长了一些约束和权重条件,使得最终代价的数值计算朝向一个特定的方向偏置(bias),而这个偏置就是具体业务场景更关注的部分网络

咱们先来看一下常规的代价函数是如何计算的。机器学习

2. 常规损失函数的数值计算

通常来讲,机器学习领域的检测分类算法所关注的仅仅是如何获得最高的正确率(acc),以2-class分类为例,咱们可使用一个二维矩阵来描述分类算法的预测结果,以下图所示:ide

表中的列表示实际数据所属类别,行表示分类算法的预测类别函数

无论使用了损失函数是何种形式,形式上,算法的预测错误的便是 FPFN 两部分所表示,即:Loss = Loss(FP)+ Loss(FN)性能

从损失函数的通用数学公式角度来看,损失函数的求导优化对 FP 和 FN 是没有任何偏置的。分类算法所关心的是如何使得 FP+FN 的值尽量的小,从而得到较高的分类准确率。对于 FP、FN 两部分各自在错误实例中所占的比重,传统损失函数并无加以任何的考虑和限制。学习

换句话说,传统损失函数其实是创建在下述假设的基础之上的:优化

在全部状况下,分类算法作出 FN 判断和作出 FP 判断对于实际结果的影响因子是彻底相同的。因此咱们能够不对两种误判所占的比例加以约束

3. 业务场景中的损失函数计算

然而在现实世界中,这一假设每每是并不成立的,在实际的业务场景中,FN 和 FN 所带来的实际损失每每是不一样的。一个被广为接受的上述假设的反例就是银行借贷问题。

  • 从机器学习算法的角度考虑,算法的分类结果应该使得错误分类率降到最低;

  • 而在实际应用中,算法的分类结果应该保证分类结果给银行形成的损失较小;

在实际状况中,银行作出 FP 判断(即没有将贷款贷给符合条件的申请人),所形成的损失要远小于其作出 FN 判断(即将贷款贷给不符合条件的申请人所形成的损失的)

若是咱们用下图来描述银行作出不一样决定所形成的不一样的代价的的cost matrix:

分类算法致使的实际损失等于:

Loss-real = FP * C01 + FN * C10

假设如今有两个分类已训练好的算法 A 和 B,对于 10 个贷款申请人进行分类。

咱们令:

loss(FN)c10 = 10;
loss(FP)c01 = 1

若 A/B 算法的分类结果为下图

从数值计算的角度,A 算法的分类正确性要优于 B 算法:Acc(A)= 80% > Acc(B)= 60%

可是从实际业务场景角度,银行实际损失,A 算法的性能却不如 B 算法:Loss(A)= 20 > Loss(B)= 4

这就是 cost-sensitive 分类算法所关注和研究的问题。

0x2:代价敏感学习公式

利用 cost matrix,咱们能够将 cost-sensitive 分类问题转化一个最优化问题,对于二分类分类算法来讲只有2种判断结果,因此优化目标为让下式 L(x, i)达到最小值:

  • 其中 x 是一个实例;

  • (x, i)表示将其分为 i 类;

  • P(j | x) 表示在算法 A 中得到的 x 属于类别 j 的后验几率,这个几率越小,反之 P(i | x) 就越大,这就是求对偶问题的反面;
  • c(i,j) 表示算法 A 将类别 i 的样本错判为类别 j 的实际损失(real-cost)

上述公式中,由于损失权重偏置因子c(i,j)的加入,使得咱们的目标使得模型再也不单纯关注如何得到 P(j|x)的最大值,而是要综合考虑预测结果P(j | x)以及不一样预测结果形成的损失c(i,j)。这两个因子互相牵制。

1. Cost-sensitive中cost的定义与表示

一般状况下,咱们使用 cost matrix 描述待分类数据集上的 cost 信息。Cost matrix C 是一个N × N的矩阵,其中 N 表明待分类数据集中的类别的数量。

C 中的条目 c(i, j)表示分类算法将实际属于 j 类获得实例分为 i 类所形成的 cost。当 i = j 时表明分类算法正确预测了实例的类别,而i ≠ j的条目对应于不正确的分类结果。

在对 c(i, j)进行赋值的过程当中,通常会遵循合理性原则:

  • 即错误分类的形成的 cost 确定要大于正确分类形成的 cost;

  • cost matrix 中的 c(i, j) = 0 , when i = j,而对于其余错误的分类结果对应的条目 c(i, j), 咱们赋其值为正数,用于表示其代价;

  • 而具体FN和FP如何赋值,取决于具体业务场景。例如若是咱们认为误报的损失大于漏报的损失,则赋值:cFN > cFP;

2. Cost-sensitive损失权重因子对损失函数的影响

从宏观角度来看,代价损失权重因子c(i, j)能够理解为一种先验知识。加入损失权重因子c(i, j)后,目标函数L(x,i)从最大似然估计转变为了最大后验估计。

笔者认为,cost sensitive的本质是“对不一样的后验预测结果,的条件几率 P(y|x) 赋予不一样的惩罚因子”。

在 2-class 分类中,cost-sensitive 分类算法将实例 x 分为 1 类的条件是当且仅当将 x 分为 1 类所形成的预期 cost,不大于将 x 分为 0 类的损失。即

当式子取等号时,这就是所谓的分类器最优决策面(auc曲线自己)。能够看到,cost matrix的不一样取值,影响了这个分类器最优决策面的位置,具体如何分析这种影响,咱们文章的后面会继续深刻讨论。

0x3:代价敏感损失的泛化讨论

笔者但愿和你们一块儿更深刻思考一下,代价敏感损失的本质是什么。

虽然大量的paper上都提出了cost-sensitive是对不一样的predict result给予不一样的损失因子,这是离散的范畴。可是笔者认为这个概念能够继续延展到连续无限的范畴,即对对数概率回归损失(sigmoid)这种损失函数也一样起做用,sigmoid本质上也体现了cost sensitive的思想。

一个标准的sigmoid函数以下:

sigmoid函数的输出表明了对发生概率的预测,目标y为 {1,0},即发生于不发生,而sigmoid的输出介于【0,1】之间。

从函数曲线上能够很容易看出:

  • 对于靠近【0,1】两侧的预测值,预测值和实际值的差值是比位于中间几率的差值要小的,所以这个区域中的1阶导数相对就较低,这进而致使了例如GD算法的最终损失较低;

  • 而位于【0,1】中间位置的地方,1阶导数相对较高,进而致使最终损失较高;

经过这种函数特性,sigmoid函数会“驱使”模型将预测结果向靠近 0 或者靠近 1 的方向前进,或者说sigmoid函数不喜欢模糊地带,而偏心(bias)肯定性的结果。

0x4:Cost-Sensitive的几何意义

若是咱们画出ROC曲线,横轴和纵轴分别是 acc 和 recall,能够现象,曲线是一个形以下图的曲线:

损失函数的极值点就是最终的决策分界面ROC曲线的“切线点”(图中的绿点)。

咱们能够作一个直观的想象:cost() 函数起到的做用是“拉伸”原始的ROC曲线,使其向acc或者recall的方向拉伸,拉伸的结果会致使超分界面“提前”和 acc 或者 recall 方面相切。

  • 对误报的惩罚加大:cost()对FN的因子比例增大,则使roc曲线朝上图中 true positive rate 方向拉伸,即向上,则相切点会更靠下,最终的效果是得到更低的 true positive rate;

  • 对漏报的惩罚加大:cost()对FP的因子比例增大,则使roc曲线朝上图中 false positive rate 方向拉伸,即向左,则相切点会更靠右,最终的效果是得到更低的 false positive rate;

以上的函数几何视角,启发咱们一点:

cost-sensitive Loss Function 的做用本质上是经过“拉伸”损失函数的函数形式,进而影响模型的最优决策面。对 acc 和 recall 的不一样权重因子,最终影响了 roc 曲线中向 acc 和 recall 方向的偏离程度

固然,cost-sensitive只是影响了模型最优决策面的位置,最优决策面并非最终的决策函数。

若是将auc函数当作是【x,y】坐标系的话,不一样的x,y取值表明了最终决策不一样的偏向,例如咱们取x=0.1,即追求低误报,则相对的,y值确定也低,即召回也低了。若是咱们稍微放低一些对低误报的追求,则召回也能对应提升。在实际的tensorflow开发中,这经过对最终模型预测的p的threshold来实现。

那cost-sensitive在这里又扮演了什么角色呢?

简单来讲能够这么理解,在相同的threshold前提下,误报敏感损失函数会使得模型得到更低的误报,漏报敏感损失函数会使得模型会的更低的漏报。

可是要始终牢记的是:最终的模型效果是两部分组成的,AUC函数的形式+认为设定的threshold决策策略

0x5:实现cost sensitive思想的不一样方式

解决 cost-sensitive 分类问题的核心在于解决的优化问题,即如何使得分类算法的结果可以得到有倾向性的L值。 

目前,在如何得到有倾向性的分类算法这一问题上,目前有几种比较主流的方法:

1. Train set sample rescaling

经过有意调整,将训练数据集的正负例呈现不一样数量比,以提升分类算法对于某些分类结果的敏感性。

例如若是想得到更高的acc,更低的误报,咱们在训练集中,调整反例的数量是正例的数倍。相关的讨论,能够参阅另外一篇blog

2. Class membership probability - cost matrix reweighted

经过修改不一样分类在算法中的 class membership probability,以得到具备必定数据倾向性的分类算法。这种算法被称为reweighted。这种方法也是本文主要讨论的。

0x6:代价敏感函数在不一样机器学习算法中的应用

目前,分类决策树、神经网络、支持向量机(SVM)、boosting等经常使用学习算法都有其对应的代价敏感扩展算法。

各个方法在具体形式上各不相同,但其核心思想是一致的,这里以AdaCost为例举例说明。

AdaCost 算法由 AdaBoost 分类算法改进而来,也是一种经过 reweighted 方式获取 cost-sensitive 分类算法的方法。

AdaCost 的基本思想是使用若干个较弱的分类器以投票方式集成出一个分类器,各个分类器的权值由评价函数调整肯定。在 AdaBoost 算法中,评价函数仅和算法的分类准确性相关。W.Fan 等人在 AdaBoost 的评价函数中引入了 cost 的元素,使得分类算法可以有效下降分类结果的 cost 值。

具体来讲 AdaCost 算法添加了一个评价分类结果的 cost 性能的函数β:y × X × c → ℝ+,使得训练出来的弱分类器的权值集合可以符合 cost-sensitive 的要求。下面给出其伪码:

Relevant Link:   

http://202.119.32.195/cache/4/03/lamda.nju.edu.cn/d2623fb33f624a2a05033bb5d0e23d45/qiny.pdf
http://lamda.nju.edu.cn/huangsj/dm11/files/qiny.pdf 
https://homes.cs.washington.edu/~pedrod/papers/kdd99.pdf 
https://cling.csd.uwo.ca/papers/cost_sensitive.pdf 

 

2. 在贝叶斯Bayes最优决策理论下,代价敏感损失函数设计准则

上个章节中,咱们谈到了一个词,”分类器最优决策面“,这个东西是什么呢?这个章节咱们来详细讨论。

0x1:贝叶斯最优决策理论

1. 贝叶斯最优分类(Bayes optimal classification)

对于二分类问题, 定义2级代价矩阵(cost matrix):

,其中是将b类样本预测为a类样本的分类代价。

Bayes决策理论,最优决策的目标是最小化指望分类代价(最大后验几率估计),即给定样本x,若下式成立,则预测其类别为正;不然,预测其类别为负。

,其中 p(x)为后验几率,p(x) = P(y = +1|x),1 − p(x) = P(y = −1|x)。

上式的意思是:当,Loss(正例判对+负例误报为正例)<= Loss(正例漏报,负例判对)时,模型预测最终结果为正。

将上式移项后可重写为:

其中:

  • :表示正样本的分类代价;

  • :表示负样本的分类代价;

所以贝叶斯最优分类器输出的分类器函数为(这里不考虑人为设定的threshold决策函数):

所以,Bayes分类器也可写做:

当正负类别分类代价相等时,即c+ = c−,Bayes分类器退化为普通的无偏损失函数;而当c+和c-存在不对称偏置时,Bayes分类器也成为有偏损失函数。

2. 贝叶斯决策错误理论上界

cost matrix本质上是改变了Bayes分类器的损失理论上界。

0x2:代价敏感损失设计准则(Design criterions of cost-sensitive loss)

1. 准则一

代价敏感损失函数需知足Bayes一致性,即单调性

新设计的代价敏感损失函数知足下述特性:

2. 准则二

对应的条件代价敏感风险在Bayes分类边界(分类器最优决策面)处取得最大值。

Bayes分类器的指望分类代价为:

在分类边界处,将样本x判为正、负类别的分类代价相等并达到最大值,此时最难预测样本类别。 

Relevant Link:   

https://www.cnblogs.com/Determined22/p/6347778.html
http://jcta.cnjournals.com/cta_cn/ch/reader/view_abstract.aspx?doi=10.7641/CTA.2015.40519 
https://www.bilibili.com/read/cv112928/
https://www.zhihu.com/question/27670909
《统计决策论及贝叶斯分析》- J.O.伯杰

  

3. 代价敏感损失函数的函数特性分析

这个章节,咱们来真正进入代价敏感函数的内部原理,探究一下cost matrix是如何影响原始损失函数的形态,进而影响原始损失函数的性质的。

0x1:原始无偏损失函数函数性质

咱们前面说过,当正负类别分类代价相等时,即c+ = c−,Bayes分类器退化为普通的无偏损失函数;而当c+和c-存在不对称偏置时,Bayes分类器也成为有偏损失函数。

因此这里先来看下咱们熟悉的原始无偏损失函数的函数性质。

具体探讨如下损失函数:平方损失、指数损失、对数损失、SVM损失。这几种损失函数都可表示为间隔yF(x)的函数, 即,以下图所示:

下标给出了各个损失函数对应最优决策函数及其条件风险

下图给出了各个损失函数的最优解和最优解处的条件风险:

能够看到,在无偏损失状况下,与贝叶斯分类器等价,最优解处的条件风险与最小分类偏差一致,即在p(x) = 1/2 处取得最大值。

这和咱们的认识是一致的,怎么理解呢?简单来讲能够这么理解。

若是咱们使用逻辑斯蒂回归训练一个二分类器,那么咱们能够设定预测的阈值p为0.5,当>=0.5时,预测结果为正例,当<0.5时预测结果为负例。这是最优的阈值,任何偏离0.5的阈值p都会增长损失:

  • 决策阈值向0.5左偏:总体损失的增长主要来自误报增长。

  • 决策阈值向0.5右偏:总体损失的增长主要来自漏报增长,固然在某些状况下,漏报多是咱们能够接受的,由于这换取了必定的误报下降。

讨论完了原始的无偏损失函数,接下来咱们要开始讨论有偏的代价损失函数,现有算法有如下两类经常使用分类代价引入策略:

1) 分类代价在损失函数外:cyL(yF(x));
2) 分类代价在损 函数内:L(ycyF(x));

0x2:分类代价在损失函数外(Classification cost outside of loss function)

这种类型的代价敏感损失将分类代价与原始损失相乘。

下表给出了各个代价敏感损失此时的最优决策和最优决策处的条件代价敏感风险

咱们取c+ = 1.5,c− = 0.5这种偏置组合,此时,Bayes分类器为

绘制各个损失函数的最优解和最优解处的条件风险:

能够看出,4种代价敏感损失均知足准则1,即最优分类器为Bayes分类器。

另外一方面,除代价敏感SVM损失外,其他损失均不知足准则2, 最优解处的条件代价敏感风险没有在Bayes分类边界处取得最大值,而是有不一样程度的偏移。

0x3:分类代价在损失函数内(Classification cost inside of loss function)

这种类型的代价敏感损失将分类代价引入损失函数内部,将其与判决函数F相乘。

下表列出了各个代价敏感损失此时的最优决策和最优决策处的条件代价敏感风险

咱们取c+ = 1.5,c− = 0.5这种偏置组合,绘制各个损失函数的最优解和最优解处的条件风险:

可看出,4种代价敏感损失均知足准则1和准则2,即最优分类器为Bayes分类器,最优解处的条件代价敏感风险在Bayes分类边界处取得最大值。

这种损失偏置条件下,模型的漏报会倾向于低漏报。 

综上,虽然这4种损失函数代价敏感化以后并未都严格知足准则1/2,可是整体上,cost sensitive实际上扭曲了原始损失函数的函数曲线,使其发生了偏置。

Relevant Link:    

http://jcta.cnjournals.com/cta_cn/ch/reader/create_pdf.aspx?file_no=CCTA140519&flag=1&journal_id=cta_cn&year_id=2015

 

4. 在Keras中开发适合业务场景的代价敏感函数 

在具体工程项目中,由于TensorFlow/Keras并没提供原生的代价敏感函数,咱们能够经过继承和重写原有的损失函数的方式,对原始的经典损失函数进行改造(函数内/函数外)

# 方式一
def vae_loss(x, x_decoded_mean):
    xent_loss = objectives.binary_crossentropy(x, x_decoded_mean)
    kl_loss = - 0.5 * K.mean(1 + z_log_sigma - K.square(z_mean) - K.exp(z_log_sigma), axis=-1)
    return xent_loss + kl_loss
 
vae.compile(optimizer='rmsprop', loss=vae_loss)

Relevant Link:    

https://stackoverflow.com/questions/45961428/make-a-custom-loss-function-in-keras
https://blog.csdn.net/A_a_ron/article/details/79050204
https://blog.csdn.net/xiaojiajia007/article/details/73274669
相关文章
相关标签/搜索