1 二分类SVC中的样本不均衡问题:重要参数class_weight
可输入字典或者"balanced”,可不填,默认None 对SVC,将类i的参数C设置为class_weight [i] * C。如果没有给出 具体的class_weight,则所有类都被假设为占有相同的权重1,模型会根据数据原本的状况去训练。如果希望改善 样本不均衡状况,请输入形如{"标签的值1":权重1,"标签的值2":权重2}的字典,则参数C将会自动被设为: 标签的值1的C:权重1 * C,标签的值2的C:权重2*C 或者,可以使用“balanced”模式,这个模式使用y的值自动调整与输入数据中的类频率成反比的权重为 n_samples/(n_classes * np.bincount(y))。
SVC的接口fit的参数:sample_weight
数组,结构为 (n_samples, ),必须对应输入fit中的特征矩阵的每个样本 每个样本在fit时的权重,让权重 * 每个样本对应的C值来迫使分类器强调设定的权重更大的样本。通常,较大的权 重加在少数类的样本上,以迫使模型向着少数类的方向建模 通常来说,这两个参数我们只选取一个来设置。如果我们同时设置了两个参数,则C会同时受到两个参数的影响, 即 class_weight中设定的权重 * sample_weight中设定的权重 * C。
首先,我们来自建一组样本不平衡的数据集。我们在这组数据集上建两个SVC模型,一个设置有class_weight参 数,一个不设置class_weight参数。我们对两个模型分别进行评估并画出他们的决策边界,以此来观察 class_weight带来的效果。
从准确率的角度来看,不做样本平衡的时候准确率反而更高,做了样本平衡准确率反而变低了,这是因 为做了样本平衡后,为了要更有效地捕捉出少数类,模型误伤了许多多数类样本,而多数类被分错的样本数量 > 少 数类被分类正确的样本数量,使得模型整体的精确性下降。现在,如果我们的目的是模型整体的准确率,那我们就 要拒绝样本平衡,使用class_weight被设置之前的模型。
2 SVC的模型评估指标
单纯地追求捕捉出少数类,就会成本太高,而不顾及少数类,又会无法达成模型的效果。所以在现实 中,我们往往在寻找捕获少数类的能力和将多数类判错后需要付出的成本的平衡。如果一个模型在能够尽量捕获少 数类的情况下,还能够尽量对多数类判断正确,则这个模型就非常优秀了。为了评估这样的能力,我们将引入新的 模型评估指标:混淆矩阵和ROC曲线来帮助我们。
混淆矩阵(Confusion Matrix)
混淆矩阵是二分类问题的多维衡量指标体系,在样本不平衡时极其有用。在混淆矩阵中,我们将少数类认为是正 例,多数类认为是负例。在决策树,随机森林这些普通的分类算法里,即是说少数类是1,多数类是0。在SVM里, 就是说少数类是1,多数类是-1。普通的混淆矩阵,一般使用{0,1}来表示。混淆矩阵阵如其名,十分容易让人混 淆,在许多教材中,混淆矩阵中各种各样的名称和定义让大家难以理解难以记忆。我为大家找出了一种简化的方式 来显示标准二分类的混淆矩阵,如图所示:
混淆矩阵中,永远是真实值在前,预测值在后。其实可以很容易看出,11和00的对角线就是全部预测正确的,01 和10的对角线就是全部预测错误的。基于混淆矩阵,我们有六个不同的模型评估指标,这些评估指标的范围都在 [0,1]之间,所有以11和00为分子的指标都是越接近1越好,所以以01和10为分子的指标都是越接近0越好。对于所 有的指标,我们用橙色表示分母,用绿色表示分子,则我们有:
模型整体效果:准确率
准确率Accuracy就是所有预测正确的所有样本除以总样本,通常来说越接近1越好。
捕捉少数类的艺术:精确度,召回率和F1 score
精确度Precision,又叫查准率,表示所有被我们预测为是少数类的样本中,真正的少数类所占的比例。在支持向 量机中,精确度可以被形象地表示为决策边界上方的所有点中,红色点所占的比例。精确度越高,代表我们捕捉正 确的红色点越多,对少数类的预测越精确。精确度越低,则代表我们误伤了过多的多数类。精确度是”将多数类判 错后所需付出成本“的衡量。
#所有判断正确并确实为1的样本 / 所有被判断为1的样本
#对于没有class_weight,没有做样本平衡的灰色决策边界来说:
(y[y == clf.predict(X)] == 1).sum()/(clf.predict(X) == 1).sum()
#对于有class_weight,做了样本平衡的红色决策边界来说:
(y[y == wclf.predict(X)] == 1).sum()/(wclf.predict(X) == 1).sum()
召回率Recall,又被称为敏感度(sensitivity),真正率,查全率,表示所有真实为1的样本中,被我们预测正确的样 本所占的比例。在支持向量机中,召回率可以被表示为,决策边界上方的所有红色点占全部样本中的红色点的比 例。召回率越高,代表我们尽量捕捉出了越多的少数类,召回率越低,代表我们没有捕捉出足够的少数类。
#所有predict为1的点 / 全部为1的点的比例
#对于没有class_weight,没有做样本平衡的灰色决策边界来说:
(y[y == clf.predict(X)] == 1).sum()/(y == 1).sum()
#对于有class_weight,做了样本平衡的红色决策边界来说:
(y[y == wclf.predict(X)] == 1).sum()/(y == 1).sum()
召回率可以帮助我们判断,我们是否捕捉除了全部的少数类,所以又叫做查全率。
如果我们希望不计一切代价,找出少数类(比如找出潜在犯罪者的例子),那我们就会追求高召回率,相反如果我 们的目标不是尽量捕获少数类,那我们就不需要在意召回率。
注意召回率和精确度的分子是相同的(都是11),只是分母不同。而召回率和精确度是此消彼长的,两者之间的平 衡代表了捕捉少数类的需求和尽量不要误伤多数类的需求的平衡。究竟要偏向于哪一方,取决于我们的业务需求: 究竟是误伤多数类的成本更高,还是无法捕捉少数类的代价更高。
为了同时兼顾精确度和召回率,我们创造了两者的调和平均数作为考量两者平衡的综合性指标,称之为F1 measure。两个数之间的调和平均倾向于靠近两个数中比较小的那一个数,因此我们追求尽量高的F1 measure, 能够保证我们的精确度和召回率都比较高。F1 measure在[0,1]之间分布,越接近1越好。
判错多数类的考量:特异度与假正率
特异度(Specificity)表示所有真实为0的样本中,被正确预测为0的样本所占的比例。在支持向量机中,可以形象地 表示为,决策边界下方的点占所有紫色点的比例。
#所有被正确预测为0的样本 / 所有的0样本
#对于没有class_weight,没有做样本平衡的灰色决策边界来说:
(y[y == clf.predict(X)] == 0).sum()/(y == 0).sum()
#对于有class_weight,做了样本平衡的红色决策边界来说:
(y[y == wclf.predict(X)] == 0).sum()/(y == 0).sum()
特异度衡量了一个模型将多数类判断正确的能力,而1 - specificity就是一个模型将多数类判断错误的能力,这种 能力被计算如下,并叫做假正率(False Positive Rate):
在支持向量机中,假正率就是决策边界上方的紫色点(所有被判断错误的多数类)占所有紫色点的比例。根据我们 之前在precision处的分析,其实可以看得出来,当样本均衡过后,假正率会更高,因为有更多紫色点被判断错误, 而样本均衡之前,假正率比较低,被判错的紫色点比较少。所以假正率其实类似于Precision的反向指标, Precision衡量有多少少数点被判断正确,而假正率FPR衡量有多少多数点被判断错误,性质是十分类似的。
sklearn中的混淆矩阵
3 ROC曲线以及其相关问题
基于混淆矩阵,我们学习了总共六个指标:准确率Accuracy,精确度Precision,召回率Recall,精确度和召回度的 平衡指标F measure,特异度Specificity,以及假正率FPR。
我们可以使用Recall和FPR之间的平 衡,来替代Recall和Precision之间的平衡,让我们衡量模型在尽量捕捉少数类的时候,误伤多数类的情况如何变 化,这就是我们的ROC曲线衡量的平衡。
ROC曲线,全称The Receiver Operating Characteristic Curve,译为受试者操作特性曲线。这是一条以不同阈值 下的假正率FPR为横坐标,不同阈值下的召回率Recall为纵坐标的曲线。
SVM实现概率预测:重要参数probability,接口predict_proba以及 decision_function
到超平面的距 离一定程度上反应了样本归属于某个标签类的可能性。接口decision_function返回的值也因此被我们认为是SVM 中的置信度(confidence)。
AUC面积代表了ROC曲线下方的面积, 这个面积越大,代表ROC曲线越接近左上角,模型就越好。AUC面积的计算比较繁琐,因此,我们使用sklearn来帮助我们。接下来我们来看看,在sklearn当中,如何绘制我们的ROC曲线,找出我们的的AUC面积。
如此就得到了我们的ROC曲线和AUC面积,可以看到,SVM在这个简单数据集上的效果还是非常好的。并且大家可 以通过观察我们使用decision_function画出的ROC曲线,对比一下我们之前强行使用概率画出来的曲线,两者非常 相似,所以在无法获取模型概率的情况下,其实不必强行使用概率,如果有置信度,那也使可以完成我们的ROC曲 线的。
利用ROC曲线找出最佳阈值
有了ROC曲线,了解了模型的分类效力,以及面对样本不均衡问题时的效力,那我们如何求解我们最佳的阈 值呢?我们想要了解,什么样的状况下我们的模型的效果才是最好的。回到我们对ROC曲线的理解来:ROC曲线反 应的是recall增加的时候FPR如何变化,也就是当模型捕获少数类的能力变强的时候,会误伤多数类的情况是否严重。我们的希望是,模型在捕获少数类的能力变强的时候,尽量不误伤多数类,也就是说,随着recall的变大,FPR 的大小越小越好。所以我们希望找到的最优点,其实是Recall和FPR差距最大的点。这个点,又叫做约登指数。
对应的最佳阈值
最佳阈值就这样选取出来了,由于现在我们是使用decision_function来画ROC曲线,所以我们选择出来的最佳阈值 其实是最佳距离。如果我们使用的是概率,我们选取的最佳阈值就会是一个概率值了。只要我们让这个距离/概率 以上的点,都为正类,让这个距离/概率以下的点都为负类,模型就是最好的:即能够捕捉出少数类,又能够尽量不误伤多数类,整体的精确性和对少数类的捕捉都得到了保证。 而从找出的最优阈值点来看,这个点,其实是图像上离左上角最近的点,离中间的虚线最远的点,也是ROC曲线的 转折点。如果没有时间进行计算,或者横坐标比较清晰的时候,我们就可以观察转折点来找到我们的最佳阈值。