Weka学习五(ROC简介)
今天我們來介紹一下ROC(Receiver operating characteristics)國內復旦張文彤老師在《SPSS統計分析基礎教材》中將其翻譯成“受試者工作特征”,也有按字面意思譯成“接受者操作特征曲線”。到底選擇哪一個大家自便吧。ROC曲線是有TP(True positive rate)、FP(Flase positive rate)構成的,以TP作為Y軸,FP作為X軸。
?
對于一個離散型分類器(discrete classifier),每一個分類器僅僅對測試集生成一組(fp,tp)點。這個結果對應著ROC空間上的一個點,例如上圖中的A、B、C幾個點。那么如何讓它們產生一個曲線就成了大家最關心的問題。
有一種方法通過對每一個樣本集中的樣本依次排序進入隊列,來到一個樣本就計算一次(fp,tp)值,直到樣本集中樣本全部進入為止。這樣我們就得到了一個與樣本數量相同的(fp,tp)數組了。然后我們通過這個二維數組我們就可以在ROC空間上做出一個ROC曲線了。具體的算法大家可以參見《An introduction to ROC anslysis》Tom Fawcett, 2005。這篇論文中對ROC曲面進行了很詳細的講解。
這樣我們就可以得到一個如上圖所示的ROC曲線。我們可以看到上圖中有很多條ROC曲線,但是到底哪一條ROC曲線代表對應的分類器的分類效果?這也是一個值得探討的問題。我們可以看到ROC曲線下面覆蓋了一定的面積,不同的曲線覆蓋的大小不同,于是一個通俗的想法就是比較它們覆蓋面積的不同來判斷分類器的效果。當然這個通俗的想法也是有其緣由的,因為對于在ROC空間中的點來說,分類器的分類效果越好它所對應的TP值就越高,FP越低,那么這個對應的點就越靠近西北方向(及左上角)。那么對于一個分類效果比較好的分類器來說,它的ROC曲面必然靠近西北方向,當然它所覆蓋的面積就會比其它分類效果較差的分類器要大了。學界稱這個面積為Area under the ROC curve(AUC)。
說了這么多,如果需要仔細了解ROC的原理請大家參考上文提到的那篇論文?,F在我將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對象包含了很多分類的結果信息
??? ???? * 例如:FMeasure、Recall、Precision、True 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對象得到包含TP、FP的兩個數組
??? ???? * 這兩個數組用于在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等等。在這里我將這個Instances的arff頭羅列出來供大家參見。
@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曲線圖的。線圖效果圖如下:
?
?
?PS:最近發現我的源代碼下載后無法正常工作,大家可以把"import com.learning.Util;";同時刪除"
Util.writeArray(tpRate, fpRate, "d:/roc.txt");";就OK了。這個函數僅僅是為了打印出tpRate,fpRate兩個指標而已。
PS2:現在我這個實例僅僅是對類別標簽 classIndex=0來做的,也就是說,我做的這個ROC曲面是相對于第一個類別的。對于二類別問題,它們兩個類別做處理的ROC曲面是一樣的,這個沒有什么問題,但是如果是多類問題,要比較某個分類器的在某個類別上的分類效果,大家要將classIndex指定到需要測試的類別標簽上。
總結
以上是生活随笔為你收集整理的Weka学习五(ROC简介)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Weka学习四(属性选择)
- 下一篇: LibSVM学习(一)——初识LibSV