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

📄 owinteractivediscretization.py

📁 orange源码 数据挖掘技术
💻 PY
📖 第 1 页 / 共 3 页
字号:
"""
<name>Interactive Discretization</name>
<description>Interactive discretization of continuous attributes</description>
<icon>icons/InteractiveDiscretization.png</icon>
<priority>2105</priority>
<contact>Ales Erjavec (ales.erjavec(@at@)fri.uni-lj.si)</contact>
"""

import orange
from OWWidget import *
from OWGraph import *
from qt import *
from qtcanvas import *
import OWGUI, OWGraphTools
import Numeric

def frange(low, up, steps):
    inc=(up-low)/steps
    return [low+i*inc for i in range(steps)]

class DiscGraph(OWGraph):
    def __init__(self, master, *args):
        OWGraph.__init__(self, *args)
        self.master=master

        self.rugKeys = []
        self.cutLineKeys = []
        self.cutMarkerKeys = []
        self.probCurveKey = None
        self.baseCurveKey = None
        self.lookaheadCurveKey = None

        self.customLink = -1

        self.setAxisScale(QwtPlot.yRight, 0.0, 1.0, 0.0)
        self.setYLaxisTitle("Split gain")
        self.setXaxisTitle("Attribute value")
        self.setYRaxisTitle("Class probability")
        self.setShowYRaxisTitle(1)
        self.setShowYLaxisTitle(1)
        self.setShowXaxisTitle(1)
        self.enableYRightAxis(1)

        self.resolution=50
        self.setCursor(Qt.arrowCursor)
        self.canvas().setCursor(Qt.arrowCursor)
        
        self.data = self.attr = self.contingency = None
        self.minVal = self.maxVal = 0
        self.curCutPoints=[]
        
    
    def computeAddedScore(self, spoints):
        candidateSplits = [x for x in frange(self.minVal, self.maxVal, self.resolution) if x not in spoints]
        idisc = orange.IntervalDiscretizer(points = [-99999] + spoints)
        var = idisc.constructVariable(self.data.domain[self.master.continuousIndices[self.master.selectedAttr]])
        measure = self.master.measures[self.master.measure][1]
        score=[]
        chisq = self.master.measure == 2
        for cut in candidateSplits:
            idisc.points = spoints + [cut]
            idisc.points.sort()
            score.append(measure(var, self.data))

        return candidateSplits, score

            
    def computeBaseScore(self):
        if self.data:
            self.baseCurveX, self.baseCurveY = self.computeAddedScore(list(self.curCutPoints))


    def computeLookaheadScore(self, split):
        if self.data:
            self.lookaheadCurveX, self.lookaheadCurveY = self.computeAddedScore(list(self.curCutPoints) + [split])


    def setData(self, attr, data):
        self.clear()
        self.attr, self.data = attr, data
        self.curCutPoints = []

        if not data:
            return

        self.classColors = OWGraphTools.ColorPaletteHSV(len(data.domain.classVar.values))

        if not attr:
            return
        
        self.contingency = orange.ContingencyAttrClass(attr, data)
        self.condProb = orange.ConditionalProbabilityEstimatorConstructor_loess(self.contingency)

        attrValues = self.contingency.keys()        
        self.minVal, self.maxVal = min(attrValues), max(attrValues)
        self.snapDecimals = -int(math.ceil(math.log(self.maxVal-self.minVal, 10)) -2)
        
        self.replotAll()


    def plotRug(self, noUpdate = False):
        for rug in self.rugKeys:
            self.removeCurve(rug)
        self.rugKeys = []

        if self.data and self.master.showRug:
            targetClass = self.master.targetClass

            freqhigh = [(val, freq[targetClass]) for val, freq in self.contingency.items() if freq[targetClass] > 1e-6]
            freqlow = [(val, freq.abs - freq[targetClass]) for val, freq in self.contingency.items()]
            freqlow = [f for f in freqlow if f[1] > 1e-6]
            if not freqhigh or not freqlow:
                return
            freqfac = .1 / max(max([f[1] for f in freqhigh]), max([f[1] for f in freqlow]))

            for val, freq in freqhigh:        
                c = self.addCurve("", Qt.gray, Qt.gray, 1, style = QwtCurve.Lines, symbol = QwtSymbol.None, xData = [val, val], yData = [1.0, 1.0 - max(.02, freqfac * freq)])
                self.setCurveYAxis(c, QwtPlot.yRight)
                self.rugKeys.append(c)

            for val, freq in freqlow:        
                c = self.addCurve("", Qt.gray, Qt.gray, 1, style = QwtCurve.Lines, symbol = QwtSymbol.None, xData = [val, val], yData = [0.04, 0.04 + max(.02, freqfac * freq)])
                self.setCurveYAxis(c, QwtPlot.yRight)
                self.rugKeys.append(c)

        if not noUpdate:
            self.update()            


    def plotBaseCurve(self, noUpdate = False):
        if self.baseCurveKey:
            self.removeCurve(self.baseCurveKey)
            
        if self.data and self.master.showBaseLine:
            self.setAxisOptions(QwtPlot.yLeft, self.master.measure == 3 and QwtAutoScale.Inverted or QwtAutoScale.None)
            self.baseCurveKey = self.addCurve("", Qt.black, Qt.black, 1, style = QwtCurve.Lines, symbol = QwtSymbol.None, xData = self.baseCurveX, yData = self.baseCurveY, lineWidth = 2)
            self.setCurveYAxis(self.baseCurveKey, QwtPlot.yLeft)
        else:
            self.baseCurveKey = None

        if not noUpdate:                
            self.update()

        
    def plotLookaheadCurve(self, noUpdate = False):
        if self.lookaheadCurveKey:
            self.removeCurve(self.lookaheadCurveKey)
            
        if self.data and self.master.showLookaheadLine:
            self.setAxisOptions(QwtPlot.yLeft, self.master.measure == 3 and QwtAutoScale.Inverted or QwtAutoScale.None)
            self.lookaheadCurveKey = self.addCurve("", Qt.black, Qt.black, 1, style = QwtCurve.Lines, symbol = QwtSymbol.None, xData = self.lookaheadCurveX, yData = self.lookaheadCurveY, lineWidth = 1)
            self.setCurveYAxis(self.lookaheadCurveKey, QwtPlot.yLeft)
            self.curve(self.lookaheadCurveKey).setEnabled(1)
        else:
            self.lookaheadCurveKey = None

        if not noUpdate:            
            self.update()


    def plotProbCurve(self, noUpdate = False):
        if self.probCurveKey:
            self.removeCurve(self.probCurveKey)
            
        if self.data and self.master.showTargetClassProb:            
            xData = self.contingency.keys()[1:-1]
            self.probCurveKey = self.addCurve("", Qt.gray, Qt.gray, 1, style = QwtCurve.Lines, symbol = QwtSymbol.None, xData = xData, yData = [self.condProb(x)[self.master.targetClass] for x in xData], lineWidth = 2)
            self.setCurveYAxis(self.probCurveKey, QwtPlot.yRight)
        else:
            self.probCurveKey = None

        if not noUpdate:
            self.update()

        
    def plotCutLines(self):
        attr = self.data.domain[self.master.continuousIndices[self.master.selectedAttr]]
        for c in self.cutLineKeys:
            self.removeCurve(c)
        
        for m in self.cutMarkerKeys:
            self.removeMarker(m)
        
        self.cutLineKeys = []
        self.cutMarkerKeys = []
        for cut in self.curCutPoints:
            c = self.addCurve("", Qt.blue, Qt.blue, 1, style = QwtCurve.Steps, symbol = QwtSymbol.None, xData = [cut, cut], yData = [.9, 0.1])
            self.setCurveYAxis(c, QwtPlot.yRight)
            self.cutLineKeys.append(c)

            m = self.addMarker(str(attr(cut)), cut, .9, Qt.AlignCenter + Qt.AlignTop, bold=1)
            self.setMarkerYAxis(m, QwtPlot.yRight)
            self.cutMarkerKeys.append(m)


    def getCutCurve(self, cut):
        ccc = self.transform(QwtPlot.xBottom, cut)
        for i,c in enumerate(self.curCutPoints):
            cc = self.transform(QwtPlot.xBottom, c)
            if abs(cc-ccc)<3:
                curve = self.curve(self.cutLineKeys[i])
                curve.curveInd = i
                return curve
        return None


    def setSplits(self, splits):
        if self.data:
            self.curCutPoints = splits

            self.computeBaseScore()
            self.plotBaseCurve()
            self.plotCutLines()
            self.customLink = -1
            

    def addCutPoint(self, cut):
        self.curCutPoints.append(cut)
        c = self.addCurve("", Qt.blue, Qt.blue, 1, style = QwtCurve.Steps, symbol = QwtSymbol.None, xData = [cut, cut], yData = [1.0, 0.015])
        self.setCurveYAxis(c, QwtPlot.yRight)
        self.cutLineKeys.append(c)
        curve = self.curve(c)
        curve.curveInd = len(self.cutLineKeys) - 1        
        return curve

    
    def onMousePressed(self, e):
        if not self.data:
            return
        
        self.mouseCurrentlyPressed = 1
        
        cut = self.invTransform(QwtPlot.xBottom, e.x())
        curve = self.getCutCurve(cut)
        if not curve and self.master.snap:
            curve = self.getCutCurve(round(cut, self.snapDecimals))
            
        if curve:
            if e.button() == Qt.RightButton:
                self.curCutPoints.pop(curve.curveInd)
                self.plotCutLines()
            else:
                cut = self.curCutPoints.pop(curve.curveInd)
                self.plotCutLines()
                self.selectedCutPoint=self.addCutPoint(cut)
        else:
            self.selectedCutPoint=self.addCutPoint(cut)
            self.plotCutLines()
            self.update()

        self.computeBaseScore()
        self.plotBaseCurve()
        self.master.synchronizeIf()


    def onMouseMoved(self, e):
        if not self.data:
            return
        
        if self.mouseCurrentlyPressed:
            if self.selectedCutPoint:
                pos = self.invTransform(QwtPlot.xBottom, e.x())
                if self.master.snap:
                    pos = round(pos, self.snapDecimals)

                if self.curCutPoints[self.selectedCutPoint.curveInd]==pos:
                    return
                if pos > self.maxVal or pos < self.minVal:
                    self.curCutPoints.pop(self.selectedCutPoint.curveInd)
                    self.computeBaseScore()
                    self.plotCutLines()
                    self.mouseCurrentlyPressed = 0
                    return
                
                self.curCutPoints[self.selectedCutPoint.curveInd] = pos
                self.selectedCutPoint.setData([pos, pos], [.9, 0.1])

                self.computeLookaheadScore(pos)
                self.plotLookaheadCurve()
                self.update()

                self.master.synchronizeIf()
                
                
        elif self.getCutCurve(self.invTransform(QwtPlot.xBottom, e.x())):
            self.canvas().setCursor(Qt.sizeHorCursor)
        else:
            self.canvas().setCursor(Qt.arrowCursor)

                                  
    def onMouseReleased(self, e):
        if not self.data:
            return
        
        self.mouseCurrentlyPressed = 0
        self.selectedCutPoint = None
        self.computeBaseScore()
        self.plotBaseCurve()
        self.plotCutLines()
        self.master.synchronizeIf()
        if self.lookaheadCurveKey:
            self.curve(self.lookaheadCurveKey).setEnabled(0)
        self.update()


    def targetClassChanged(self):
        self.plotRug()
        self.plotProbCurve()


    def replotAll(self):
        self.clear()
        if not self.contingency:
            return

        self.computeBaseScore()

        self.plotRug(True)

⌨️ 快捷键说明

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