⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 owroc.py

📁 orange源码 数据挖掘技术
💻 PY
📖 第 1 页 / 共 3 页
字号:
"""
<name>ROC Analysis</name>
<description>Displays Receiver Operating Characteristics curve based on evaluation of classifiers.</description>
<contact>Tomaz Curk</contact>
<icon>ROCAnalysis.png</icon>
<priority>1010</priority>
"""

from OWTools import *
from OWWidget import *
from OWGraph import *

import OWGUI

import orngStat, orngTest
import statc, math

def TCconvexHull(curves):
    ## merge curves into one
    mergedCurve = []
    for c in curves:
        mergedCurve.extend(c)
    mergedCurve.sort() ## increasing by fp, tp

    if len(mergedCurve) == 0: return []

    hull = []
    (prevX, maxY, fscore) = (mergedCurve[0] + (0.0,))[:3]
    prevPfscore = [fscore]
    px = prevX
    for p in mergedCurve[1:]:
        (px, py, fscore) = (p + (0.0,))[:3]
        if (px == prevX):
            if py > maxY:
                prevPfscore = [fscore]
                maxY = py
            elif py == maxY:
                prevPfscore.append(fscore)
        elif (px > prevX):
            hull = orngStat.ROCaddPoint((prevX, maxY, prevPfscore), hull, keepConcavities=0)
            prevX = px
            maxY = py
            prevPfscore = [fscore]
    hull = orngStat.ROCaddPoint((prevX, maxY, prevPfscore), hull, keepConcavities=0)

    return hull

class singleClassROCgraph(OWGraph):
    def __init__(self, parent = None, name = None, title = ""):
        OWGraph.__init__(self, parent, name)

        self.setYRlabels(None)
        self.enableGridXB(0)
        self.enableGridYL(0)
        self.setAxisMaxMajor(QwtPlot.xBottom, 10)
        self.setAxisMaxMinor(QwtPlot.xBottom, 5)
        self.setAxisMaxMajor(QwtPlot.yLeft, 10)
        self.setAxisMaxMinor(QwtPlot.yLeft, 5)
        self.setAxisScale(QwtPlot.xBottom, -0.0, 1.0, 0)
        self.setAxisScale(QwtPlot.yLeft, -0.0, 1.0, 0)
        self.setShowXaxisTitle(1)
        self.setXaxisTitle("FP Rate (1-Specificity)")
        self.setShowYLaxisTitle(1)
        self.setYLaxisTitle("TP Rate (Sensitivity)")
        self.setShowMainTitle(1)
        self.setMainTitle(title)
        self.targetClass = 0
        self.averagingMethod = None
        self.splitByIterations = None
        self.VTAsamples = 10 ## vertical threshold averaging, number of samples
        self.FPcost = 500.0
        self.FNcost = 500.0
        self.pvalue = 400.0 ##0.400

        self.performanceLineSymbol = QwtSymbol(QwtSymbol.Ellipse, QBrush(Qt.color0), QPen(self.black), QSize(7,7))
        self.defaultLineSymbol = QwtSymbol(QwtSymbol.Ellipse, QBrush(Qt.black), QPen(self.black), QSize(8,8))
        self.convexHullPen = QPen(Qt.yellow, 3)

        self.removeMarkers()
        self.performanceMarkerKeys = []

        self.removeCurves()

    def computeCurve(self, res, classIndex=-1, keepConcavities=1):
        return orngStat.TCcomputeROC(res, classIndex, keepConcavities)

    def setNumberOfClassifiersIterationsAndClassifierColors(self, classifierNames, iterationsNum, classifierColor):
        classifiersNum = len(classifierNames)
        self.removeCurves()
        self.classifierColor = classifierColor
        self.classifierNames = classifierNames

        for cNum in range(classifiersNum):
            self.classifierIterationCKeys.append([])
            self.classifierIterationConvexCKeys.append([])
            self.classifierIterationROCdata.append([])
            for iNum in range(iterationsNum):
                ckey = self.insertCurve('')
                self.setCurvePen(ckey, QPen(self.classifierColor[cNum], 3))
                self.classifierIterationCKeys[cNum].append(ckey)
                ckey = self.insertCurve('')
                self.setCurvePen(ckey, QPen(self.classifierColor[cNum], 1))
                self.classifierIterationConvexCKeys[cNum].append(ckey)
                self.classifierIterationROCdata[cNum].append(None)

            self.showClassifiers.append(0)
            self.showIterations.append(0)

            ## 'merge' average curve keys
            ckey = self.insertCurve('')
            self.setCurvePen(ckey, QPen(self.classifierColor[cNum], 2))
            self.mergedCKeys.append(ckey)

            ckey = self.insertCurve('')
            self.setCurveSymbol(ckey, self.defaultLineSymbol)
            self.setCurvePen(ckey, QPen(Qt.black, 5))
            self.mergedCThresholdKeys.append(ckey)
            self.mergedCThresholdMarkers.append([])

            ckey = self.insertCurve('')
            self.setCurvePen(ckey, QPen(self.classifierColor[cNum], 1))
            self.mergedConvexCKeys.append(ckey)

            newSymbol = QwtSymbol(QwtSymbol.None, QBrush(Qt.color0), QPen(self.classifierColor[cNum], 2), QSize(0,0))
            ## 'vertical' average curve keys
            curve = errorBarQwtPlotCurve(self, '', connectPoints = 1, tickXw = 1.0/self.VTAsamples/5.0)
            ckey = self.insertCurve(curve)
            self.setCurveSymbol(ckey, newSymbol)
            self.setCurveStyle(ckey, QwtCurve.UserCurve)
            self.verticalCKeys.append(ckey)

            ## 'threshold' average curve keys
            curve = errorBarQwtPlotCurve(self, '', connectPoints = 1, tickXw = 1.0/self.VTAsamples/5.0, tickYw = 1.0/self.VTAsamples/5.0, showVerticalErrorBar = 1, showHorizontalErrorBar = 1)
            ckey = self.insertCurve(curve)
            self.setCurveSymbol(ckey, newSymbol)
            self.setCurveStyle(ckey, QwtCurve.UserCurve)
            self.thresholdCKeys.append(ckey)

        ## iso-performance line on top of all curves
        self.performanceLineCKey = self.insertCurve('')
        self.setCurvePen(self.performanceLineCKey, QPen(Qt.black, 2))
        self.setCurveSymbol(self.performanceLineCKey, self.performanceLineSymbol)

    def removeCurves(self):
        OWGraph.removeCurves(self)
        self.classifierColor = []
        self.classifierNames = []
        self.classifierIterationROCdata = []
        self.showClassifiers = []
        self.showIterations = []
        self.showConvexCurves = 0
        self.showConvexHull = 0
        self.showPerformanceLine = 0
        self.showDefaultThresholdPoint = 0
        self.showDiagonal = 0

        ## 'merge' average curve keys
        self.mergedCKeys = []
        self.mergedCThresholdKeys = []
        self.mergedCThresholdMarkers = []
        self.mergedConvexCKeys = []
        ## 'vertical' average curve keys
        self.verticalCKeys = []
        ## 'threshold' average curve keys
        self.thresholdCKeys = []
        ## 'None' average curve keys
        self.classifierIterationCKeys = []
        self.classifierIterationConvexCKeys = []

        ## convex hull calculation
        self.mergedConvexHullData = []
        self.verticalConvexHullData = []
        self.thresholdConvexHullData = []
        self.classifierConvexHullData = []
        self.hullCurveDataForPerfLine = [] ## for performance analysis

        ## diagonal curve
        self.diagonalCKey = self.insertCurve('')
        self.setCurvePen(self.diagonalCKey, QPen(Qt.black, 1))
        self.setCurveData(self.diagonalCKey, [0.0, 1.0], [0.0, 1.0])
        
        ## convex hull curve keys
        self.mergedConvexHullCKey = self.insertCurve('')
        self.setCurvePen(self.mergedConvexHullCKey, self.convexHullPen)
        self.verticalConvexHullCKey = self.insertCurve('')
        self.setCurvePen(self.verticalConvexHullCKey, self.convexHullPen)
        self.thresholdConvexHullCKey = self.insertCurve('')
        self.setCurvePen(self.thresholdConvexHullCKey, self.convexHullPen)
        self.classifierConvexHullCKey = self.insertCurve('')
        self.setCurvePen(self.classifierConvexHullCKey, self.convexHullPen)

        ## iso-performance line
        self.performanceLineCKey = -1

    def setIterationCurves(self, iteration, curves):
        classifier = 0
        for c in curves:
            x = [px for (px, py, pf) in c]
            y = [py for (px, py, pf) in c]
            ckey = self.classifierIterationCKeys[classifier][iteration]
            self.setCurveData(ckey, x, y)
            self.classifierIterationROCdata[classifier][iteration] = c
            classifier += 1

    def setIterationConvexCurves(self, iteration, curves):
        classifier = 0
        for c in curves:
            x = [px for (px, py, pf) in c]
            y = [py for (px, py, pf) in c]
            ckey = self.classifierIterationConvexCKeys[classifier][iteration]
            self.setCurveData(ckey, x, y)
            classifier += 1

    def setTestSetData(self, splitByIterations, targetClass):
        self.splitByIterations = splitByIterations
        ## generate the "base" unmodified ROC curves
        self.targetClass = targetClass
        iteration = 0
        for isplit in splitByIterations:
            # unmodified ROC curve
            curves = self.computeCurve(isplit, self.targetClass, 1)
            self.setIterationCurves(iteration, curves)

            # convex ROC curve
            curves = self.computeCurve(isplit, self.targetClass, 0)
            self.setIterationConvexCurves(iteration, curves)
            iteration += 1

    def updateCurveDisplay(self):
        self.curve(self.diagonalCKey).setEnabled(self.showDiagonal)

        showSomething = 0
        for cNum in range(len(self.showClassifiers)):
            showCNum = (self.showClassifiers[cNum] <> 0)

            ## 'merge' averaging
            b = (self.averagingMethod == 'merge') and showCNum
            showSomething = showSomething or b
            curve =  self.curve(self.mergedCKeys[cNum])
            if curve <> None: curve.setEnabled(b)

            b2 = b and self.showDefaultThresholdPoint
            curve =  self.curve(self.mergedCThresholdKeys[cNum])
            if curve <> None: curve.setEnabled(b2)
            for mkey in self.mergedCThresholdMarkers[cNum]:
            	marker = self.marker(mkey)
            	if marker <> None: marker.setEnabled(b2)

            b = b and self.showConvexCurves
            curve =  self.curve(self.mergedConvexCKeys[cNum])
            if curve <> None: curve.setEnabled(b)


            ## 'vertical' averaging
            b = (self.averagingMethod == 'vertical') and showCNum
            showSomething = showSomething or b
            curve =  self.curve(self.verticalCKeys[cNum])
            if curve <> None: curve.setEnabled(b)

            ## 'threshold' averaging
            b = (self.averagingMethod == 'threshold') and showCNum
            showSomething = showSomething or b
            curve =  self.curve(self.thresholdCKeys[cNum])
            if curve <> None: curve.setEnabled(b)

            ## 'None' averaging
            for iNum in range(len(self.showIterations)):
                b = (self.averagingMethod == None) and showCNum and (self.showIterations[iNum] <> 0)
                showSomething = showSomething or b
                self.curve(self.classifierIterationCKeys[cNum][iNum]).setEnabled(b)
                b = b and self.showConvexCurves
                self.curve(self.classifierIterationConvexCKeys[cNum][iNum]).setEnabled(b)

        chb = (showSomething) and (self.averagingMethod == None) and self.showConvexHull
        curve =  self.curve(self.classifierConvexHullCKey)
        if curve <> None: curve.setEnabled(chb)

        chb = (showSomething) and (self.averagingMethod == 'merge') and self.showConvexHull
        curve =  self.curve(self.mergedConvexHullCKey)
        if curve <> None: curve.setEnabled(chb)

        chb = (showSomething) and (self.averagingMethod == 'vertical') and self.showConvexHull
        curve =  self.curve(self.verticalConvexHullCKey)
        if curve <> None: curve.setEnabled(chb)

        chb = (showSomething) and (self.averagingMethod == 'threshold') and self.showConvexHull
        curve =  self.curve(self.thresholdConvexHullCKey)
        if curve <> None: curve.setEnabled(chb)

        ## performance line
        b = (self.averagingMethod == 'merge') and self.showPerformanceLine
        for mkey in self.performanceMarkerKeys:
            self.marker(mkey).setEnabled(b)
        curve = self.curve(self.performanceLineCKey)
        if curve <> None: curve.setEnabled(b)

        self.updateLayout()
        self.update()

    def setShowConvexCurves(self, b):
        self.showConvexCurves = b
        self.updateCurveDisplay()

    def setShowConvexHull(self, b):
        self.showConvexHull = b
        self.updateCurveDisplay()

    def setShowPerformanceLine(self, b):
        self.showPerformanceLine = b
        self.updateCurveDisplay()
        
    def setShowDefaultThresholdPoint(self, b):
    	self.showDefaultThresholdPoint = b
    	self.updateCurveDisplay()

    def setShowClassifiers(self, list):
        self.showClassifiers = list
        self.calcConvexHulls()
        self.calcUpdatePerformanceLine() ## new data for performance line
        self.updateCurveDisplay()

    def setShowIterations(self, list):
        self.showIterations = list
        self.calcAverageCurves()
        self.calcConvexHulls()
        self.calcUpdatePerformanceLine() ## new data for performance line
        self.updateCurveDisplay()

    ## calculate the average curve for the selected test sets (with all the averaging methods)
    def calcAverageCurves(self):
        ##
        ## self.averagingMethod == 'merge':
        mergedIterations = orngTest.ExperimentResults(1, self.splitByIterations[0].classifierNames, self.splitByIterations[0].classValues, self.splitByIterations[0].weights, classifiers=self.splitByIterations[0].classifiers, loaded=self.splitByIterations[0].loaded)
        i = 0
        for isplit in self.splitByIterations:
            if self.showIterations[i]:
                for te in isplit.results:
                    mergedIterations.results.append( te )
            i += 1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -