注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

anqiang专栏

不要问细节是怎么搞的,源码说明一切

 
 
 

日志

 
 

Weka学习五(ROC简介)  

2009-04-06 15:29:03|  分类: Weka 学习系列 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

今天我们来介绍一下ROCReceiver operating characteristics)国内复旦张文彤老师在《SPSS统计分析基础教材》中将其翻译成“受试者工作特征”,也有按字面意思译成“接受者操作特征曲线”。到底选择哪一个大家自便吧。ROC曲线是有TP(True positive rate)FP(Flase positive rate)构成的,以TP作为Y轴,FP作为X轴。

Weka学习五(ROC简介) - 笨笨 - 笨笨的博客

 

对于一个离散型分类器(discrete classifier),每一个分类器仅仅对测试集生成一组(fp,tp)点。这个结果对应着ROC空间上的一个点,例如上图中的ABC几个点。那么如何让它们产生一个曲线就成了大家最关心的问题。

有一种方法通过对每一个样本集中的样本依次排序进入队列,来到一个样本就计算一次(fp,tp)值,直到样本集中样本全部进入为止。这样我们就得到了一个与样本数量相同的(fp,tp)数组了。然后我们通过这个二维数组我们就可以在ROC空间上做出一个ROC曲线了。具体的算法大家可以参见《An introduction to ROC anslysisTom Fawcett, 2005。这篇论文中对ROC曲面进行了很详细的讲解。

Weka学习五(ROC简介) - 笨笨 - 笨笨的博客

这样我们就可以得到一个如上图所示的ROC曲线。我们可以看到上图中有很多条ROC曲线,但是到底哪一条ROC曲线代表对应的分类器的分类效果?这也是一个值得探讨的问题。我们可以看到ROC曲线下面覆盖了一定的面积,不同的曲线覆盖的大小不同,于是一个通俗的想法就是比较它们覆盖面积的不同来判断分类器的效果。当然这个通俗的想法也是有其缘由的,因为对于在ROC空间中的点来说,分类器的分类效果越好它所对应的TP值就越高,FP越低,那么这个对应的点就越靠近西北方向(及左上角)。那么对于一个分类效果比较好的分类器来说,它的ROC曲面必然靠近西北方向,当然它所覆盖的面积就会比其它分类效果较差的分类器要大了。学界称这个面积为Area under the ROC curveAUC)。

说了这么多,如果需要仔细了解ROC的原理请大家参考上文提到的那篇论文。现在我将weka中得到ROC曲面的方法,以及通过SPSS绘制一个ROC曲面的方法以源码的形式介绍给大家:

package com.csdn;

 

import java.awt.BorderLayout;

import java.io.BufferedReader;

import java.io.FileReader;

import java.util.Random;

 

import weka.classifiers.Classifier;

import weka.classifiers.Evaluation;

import weka.classifiers.bayes.NaiveBayes;

import weka.classifiers.evaluation.ThresholdCurve;

import weka.core.Instances;

import weka.core.Utils;

import weka.gui.visualize.PlotData2D;

import weka.gui.visualize.ThresholdVisualizePanel;

 

import com.learning.Util;

 

/*

 * Date: 2009.4.6

 * by: Wang Yi

 * Email: wangyi19840906@yahoo.com.cn

 * QQ: 270135367

 *

 */

public class SimpleROC {

 

    /**

     * @param args

     */

    public static void main(String[] args) throws Exception {

       // TODO Auto-generated method stub

       /*

        * 1.读入数据集

        */

        Instances data = new Instances(

                              new BufferedReader(

                                new FileReader("C:\Program Files\Weka-3-6\data\segment-challenge.arff")));

        data.setClassIndex(data.numAttributes() - 1);

 

        /*

         * 2.训练分类器并用十字交叉验证法来获得Evaluation对象

         * 注意这里的方法与我们在上几节中使用的验证法是不同。

         */

        Classifier cl = new NaiveBayes();

        Evaluation eval = new Evaluation(data);

        eval.crossValidateModel(cl, data, 10, new Random(1));

 

        /*

         * 3.生成用于得到ROC曲面和AUC值的Instances对象

         * 顺带打印了一些其它信息,用于在SPSS中生成ROC曲面

         * 如果我们查看weka源码就会知道这个Instances对象包含了很多分类的结果信息

         * 例如:FMeasureRecallPrecisionTrue Positive Rate

         * False Positive Rate等等。我们可以用这些信息绘制各种曲面。

         */

        ThresholdCurve tc = new ThresholdCurve();

       

        //classIndex is the index of the class to consider as "positive"

        int classIndex = 0;

        Instances result = tc.getCurve(eval.predictions(), classIndex);

        System.out.println("The area under the ROC curve: " + eval.areaUnderROC(classIndex));

       

        /*

         * 在这里我们通过结果信息Instances对象得到包含TPFP的两个数组

         * 这两个数组用于在SPSS中通过线图绘制ROC曲面

         */

        int tpIndex = result.attribute(ThresholdCurve.TP_RATE_NAME).index();

        int fpIndex = result.attribute(ThresholdCurve.FP_RATE_NAME).index();

        double [] tpRate = result.attributeToDoubleArray(tpIndex);

        double [] fpRate = result.attributeToDoubleArray(fpIndex);

       

        Util.writeArray(tpRate, fpRate, "d:\roc.txt");

       

        /*

         * 4.使用结果信息instances对象来显示ROC曲面

         */

        ThresholdVisualizePanel vmc = new ThresholdVisualizePanel();

       

        //这个获得AUC的方式与上面的不同,其实得到的都是一个共同的结果

        vmc.setROCString("(Area under ROC = " +

            Utils.doubleToString(tc.getROCArea(result), 4) + ")");

        vmc.setName(result.relationName());

        PlotData2D tempd = new PlotData2D(result);

        tempd.setPlotName(result.relationName());

        tempd.addInstanceNumberAttribute();

        vmc.addPlot(tempd);

 

        // 显示曲面

        String plotName = vmc.getName();

        final javax.swing.JFrame jf =

          new javax.swing.JFrame("Weka Classifier Visualize: "+plotName);

        jf.setSize(500,400);

        jf.getContentPane().setLayout(new BorderLayout());

        jf.getContentPane().add(vmc, BorderLayout.CENTER);

        jf.addWindowListener(new java.awt.event.WindowAdapter() {

          public void windowClosing(java.awt.event.WindowEvent e) {

          jf.dispose();

          }

        });

        jf.setVisible(true);

    }

 

}

在代码的第三部分,有一个result 结果信息对象被建立,这个对象里面有很多分类器分类后产生的结果,如代码中解释的那样,它们包括,TP Rate, FP Rate, Recall, FMeasure等等。在这里我将这个Instancesarff头罗列出来供大家参见。

@relation ThresholdCurve

 

@attribute 'True Positives' numeric

@attribute 'False Negatives' numeric

@attribute 'False Positives' numeric

@attribute 'True Negatives' numeric

@attribute 'False Positive Rate' numeric

@attribute 'True Positive Rate' numeric

@attribute Precision numeric

@attribute Recall numeric

@attribute Fallout numeric

@attribute FMeasure numeric

@attribute Threshold numeric

 

由于在weka中得到的ROC曲线图不够清晰而且无法导出,因此我通过SPSS绘制了ROC曲线。我们是通过result这个对象得到TP Rate FP Rate数组,然后借助SPSS的线图功能得到ROC曲线图的。线图效果图如下:

 

 

Weka学习五(ROC简介) - 笨笨 - 笨笨的博客

 PS:最近发现我的源代码下载后无法正常工作,大家可以把"import com.learning.Util;";同时删除"

Util.writeArray(tpRate, fpRate, "d:\roc.txt");";就OK了。这个函数仅仅是为了打印出tpRate,fpRate两个指标而已。

PS2:现在我这个实例仅仅是对类别标签 classIndex=0来做的,也就是说,我做的这个ROC曲面是相对于第一个类别的。对于二类别问题,它们两个类别做处理的ROC曲面是一样的,这个没有什么问题,但是如果是多类问题,要比较某个分类器的在某个类别上的分类效果,大家要将classIndex指定到需要测试的类别标签上。

  评论这张
 
阅读(5633)| 评论(6)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017