0
点赞
收藏
分享

微信扫一扫

机器学习实战之AdaBoost元算法(四)非均衡分类问题及小结

IT影子 2022-04-14 阅读 62

转载请注明作者和出处:https://blog.csdn.net/weixin_45814668
知乎:https://www.zhihu.com/people/qiongjian0427
Git:https://github.com/qiongjian/Machine-learning/
运行环境:anaconda—jupyter notebook
Python版本: Python3.x

更多精彩内容,尽在微信公众号,欢迎您的关注:
在这里插入图片描述

目录

其他分类性能度量指标:正确率、召回率及ROC曲线

错误率指的是在所有测试样例中错分的样例比例。实际上,这样的度量错误掩盖了样例如何被分错的事实。在机器学习中,有一个普遍适用的称为混淆矩阵(confusion matrix)的工具,它可以帮助人们更好地了解分类中的错误。有这样一个关于在房子周围可能发现的动物类型的预测,这个预测的三类问题的混淆矩阵如下表所示:
在这里插入图片描述
利用混淆矩阵就可以更好地理解分类中的错误了。 如果矩阵中的非对角元素均为0,就会得到一个完美的分类器。

考虑另外一个混淆矩阵,这次的矩阵只针对一个简单的二类问题。下表中给出了该混淆矩阵,在这个二类问题中,如果将一个正例判为正例,那么就可以认为产生了一个真正例(True Positive,TP,也称真阳);如果对一个反例正确地判为反例,则认为产生了一个真反例(True Negative,TN,也称真阴)。相应地,另外两种情况则分别称为伪反例(False Negative,FN,也称假阴)和伪正例(False Positive,FP,也称假阳)。如下表所示:

在分类中,当某个类别的重要性高于其他类别时,我们就可以利用上述定义来定义出多个比错误率更好的新指标。第一个指标是正确率(precision),它等于TP/(TP+FP),给出的是预测为正例的样本中的真正正例的比例。第二个指标是召回率(recall),它等于TP/(TP+FN),给出的是预测为正例的真实正例占所有真实正例的比例。在召回率很大的分类器中,真正判错的正例的数目并不多。
在这里插入图片描述
我们可以很容易构造一个高正确率或高召回率的分类器,但是很难同时保证两者成立。如果将任何样本都判为正例,那么召回率达到百分之百而此时正确率很低。构建一个同时使正确率和召回率最大的分类器是具有挑战性的。

另一个用于度量分类中的非均衡性的工具是ROC曲线(ROC curve),ROC代表接收者操作特征(receiver operating characteristic),它最早在二战期间由电气工程师构建雷达系统时使用过。下图给出了一条ROC曲线的例子。是利用10个单层决策树的AdaBoost马疝病检测系统的ROC曲线。
在这里插入图片描述
图中有一条虚线一条实线。图中的横轴是伪正例的比例(假阳率=FP/(FP+TN)),而纵轴是真正例的比例(真阳率=TP/(TP+FN))。ROC曲线给出的是当阈值变化时假阳率和真阳率的变化情况。左下角的点对应的是将所有样例判为反例的情况,而右上角的点对应的则是将所有样例判为正例的情况。虚线给出的是随机猜测的结果曲线。

ROC曲线不但可以用于比较分类器,还可以基于成本效益(cost-versus-benefit)分析来做出决策。

在理想的情况下,最佳的分类器应该尽可能地处于左上角,这就意味着分类器在假阳率很低的同时获得了很高的真阳率。例如在垃圾邮件的过滤中,这就相当于过滤了所有的垃圾邮件,但没有将任何合法邮件误实为垃圾邮件而放入垃圾邮件的文件夹中。

对不同的ROC曲线进行比较的一个指标是曲线下的面积(Area Unser the Curve,AUC)。AUC给出的是分类器的平均性能值,当然它并不能完全代替对整条曲线的观察。一个完美分类器的AUC为1.0,而随机猜测的AUC则为0.5。

#ROC曲线的绘制及AUC计算函数
def plotROC(predStrengths,classLabels):
    cur=(1.0,1.0)
    ySum=0.0
    numPosClas=np.sum(np.array(classLabels)==1.0)
    yStep=1/float(numPosClas)
    xStep=1/float(len(classLabels)-numPosClas)
    sortedIndicies=predStrengths.argsort()
    fig=plt.figure()
    ax=plt.subplot(111)
    for index in sortedIndicies.tolist()[0]:
        if classLabels[index]==1.0:
            delX=0;delY=yStep;
        else:
            delX=xStep;delY=0;
        ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY],c='b')
        cur=(cur[0]-delX,cur[1]-delY)
    ax.plot([0,1],[0,1],"b--")
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title("ROC curve for AdaBoost Horse Colic Detection System")
    ax.axis([0,1,0,1])
    plt.show()
    print('the area under the curve is:',ySum*xStep)

上述程序中的函数有两个输入参数,第一个参数是一个numpy数组或者一个行向量组成的矩阵。该参数代表的则是分类器的预测强度。在分类器和训练函数将这些数值应用到sign()函数之前,它们就已经产生了。尽管很快就可以看到该函数的实际执行效果,但是我们还是要先讨论一下这段代码。

函数的第二个输入参数是先前使用过的classLabels。我们首先构建一个浮点数二元组,并将它初始化为(1.0,1.0)。该元组保留的是绘制光标的位置,变量ySum则用于计算AUC的值。接下来,通过数组过滤方式计算正例的数目,并将该值赋给numPosClass。该值先是确定了在y坐标轴上的步进数目,接着在x轴和y轴的0.0到1.0区间上绘点,因此y轴上的步长是1.0/numPosCla。类似地,就可以得到x轴的步长了。

接下来,我们得到了排序索引,但是这些索引是按照最小到最大的排序排列的,因此需要从点<1.0,1.0>开始绘,一直到<0,0>。跟着的三行代码则是用于构建画笔,并在所有排序值上进行循环。这些值在一个numpy数组或者矩阵中进行排序,python则需要一个表来进行迭代循环,因此需要调用tolist()方法。当遍历表时,每得到一个标签为1.0的类,则要沿着y轴的方向下降一个步长,即不断降低真阳率。类似地,对于每个其它类别的标签,则是在x轴方向上倒退了一个步长(假阴率方向)。上述代码只关注1这个类别标签,因此就无所谓是采用1/0标签还是+1/-1标签。

为了计算AUC,需要对多个小矩形的面积进行累加。这些小矩形的宽度时xStep,因此先对所有矩形的高度进行累加,然后再乘以xStep得到其总面积。所有高度的和(ySum)随着x轴的每次移动而渐次增加。一旦决定了是在x轴还是y轴方向上进行移动的,就可以在当前点和新点之间画出一条线段。然后,当前点cur更新了。最后就会得到一个像样的绘图并将AUC打印到终端输出。

为了解实际运行效果,需要将adaboostTrainDS()的最后一行代码替换成:

return weakClassArr,aggClassEst

以得到aggClassEst的值。然后,输入以下命令:

dataArr, LabelArr = loadDataSet('horseColicTraining2.txt')
classifierArray, aggClassEst = adaBoostTrainDS(dataArr, LabelArr,10)
plotROC(aggClassEst.T, LabelArr)

结果:
在这里插入图片描述

基于代价函数的分类器决策控制

除了调节分类器的阈值之外,还有一些其他可以用于处理非均匀分类代价问题的方法,其中的一种称为代价敏感的学习(cost-sensitive learning)。

下面第一张表给出的是目前为止分类器的代价矩阵(代价不是0就是1)。可以基于该代价矩阵计算其总代价:TP0+FN1+FP1+TN0。
基于第二张表中代价矩阵的分类代价的计算公式为:TP*(-5)+FN1+FP50+TN*0。
采用第二张表作为代价矩阵时,两种分类错误的代价是不一样的。正确分类所得到的收益也不一样。

在这里插入图片描述

处理非均衡问题的数据抽样方法

另外一种针对非均衡问题调节分类器的方法,就是对分类器的训练数据进行改造。这可以通过欠抽样(undersampling)或者过抽样(oversampling)来实现。过抽样意味着复制样例,而欠抽样意味着剔除样例。不管采用哪种方式,数据都会从原始形式改造成新形式。抽样过程则可以通过随机方式或者某个预定方式来实现。

本章小结

多个分类器组合可能会进一步凸显出单分类器的不足,比如过拟合问题。如果分类器之间差异显著,那么多个分类器组合就可能会缓解这一问题。分类器之间的差异可以是算法本身或者是应用于算法上的数据的不同。

本章介绍的两种集成方法是bagging和boosting。在bagging中,是通过随机抽样的替换方法,得到了与原始数据集规模一样的数据集。而boosting在bagging的思路上更近了一步,它在数据集上顺序应用了多个不同的分类器。另一个成功的集成方法就是随机森林。

本章介绍了boosting方法中最流行的一个称为AdaBoost的算法。AdaBoost以弱学习器作为基学习器,并且输入数据,使其通过权重向量进行加权。在第一次迭代当中,所有数据都等权重。但是在后续的迭代当中,前次迭代中分错的数据的权重会增大。这种针对错误的调节能力正是AdaBoost的长处。

本章以单层决策树作为弱学习器构建了Adaboost分类器。实际上,AdaBoost函数可以应用于任意分类器,只要该分类器能够处理加权数据即可。AdaBoost算法十分强大,它能够快速处理其他分类器难以处理的数据集。

非均衡分类问题是指在分类器训练时正例数目和反例数目不相等(相差很大)。该问题在正例和反例的代价不同时也存在。本章不仅考察了一种不同分类器的评价方法——ROC曲线,还介绍了正确率和召回率这两种在类别重要性不同时,度量分类器性能的指标。

本章介绍了通过过抽样和欠抽样方法来调节数据集中的正例和反例数目。另外一种可能更好的非均衡问题的处理方法,就是在训练分类器时将错误的代价考虑在内。

END.

举报

相关推荐

0 条评论