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

📄 owpredictions.py

📁 orange源码 数据挖掘技术
💻 PY
字号:
"""
<name>Predictions</name>
<description>Displays predictions of models for a particular data set.</description>
<icon>icons/Predictions.png</icon>
<contact>Blaz Zupan (blaz.zupan(@at@)fri.uni-lj.si)</contact> 
<priority>300</priority>
"""

from qttable import *
from OWWidget import *
import OWGUI

##############################################################################

class colorItem(QTableItem):
    def __init__(self, table, editType, text):
        QTableItem.__init__(self, table, editType, str(text))

    def paint(self, painter, colorgroup, rect, selected):
        g = QColorGroup(colorgroup)
        g.setColor(QColorGroup.Base, Qt.lightGray)
        QTableItem.paint(self, painter, g, rect, selected)

##############################################################################

class OWPredictions(OWWidget):
    settingsList = ["ShowProb", "ShowClass", "ShowTrueClass", "ShowAttributeMethod", "sendDataType", "commitOnChange"]

    def __init__(self, parent=None, signalManager = None):
        OWWidget.__init__(self, parent, signalManager, "Classifications")

        self.callbackDeposit = []
        self.inputs = [("Examples", ExampleTable, self.dataset),("Classifiers", orange.Classifier, self.classifier, Multiple)]
        self.outputs = [("Selected Examples", ExampleTableWithClass)]
        self.classifiers = {}

        # saveble settings
        self.ShowProb = 1; self.ShowClass = 1; self.ShowTrueClass = 0
        self.ShowAttributeMethod = 0
        self.sendDataType = 0; self.commitOnChange = 1
        self.loadSettings()

        self.freezeAttChange = 0 # 1 to block table update followed by changes in attribute list box
        self.data=None
        
        # GUI - Options
        self.options = QVButtonGroup("Options", self.controlArea)
        self.options.setDisabled(1)
        OWGUI.checkBox(self.options, self, 'ShowProb', "Show predicted probabilities", callback=self.updateTableOutcomes)

        self.lbClasses = QListBox(self.options)
        self.lbClasses.setSelectionMode(QListBox.Multi)
        self.connect(self.lbClasses, SIGNAL("selectionChanged()"), self.updateTableOutcomes)
        
        OWGUI.checkBox(self.options, self, 'ShowClass', "Show predicted class", callback=[self.updateTableOutcomes, self.checkenable])
        self.trueClassCheckBox = OWGUI.checkBox(self.options, self, 'ShowTrueClass', "Show true class", callback=self.updateTrueClass, disabled=1)

        OWGUI.separator(self.controlArea)
        self.att = QVButtonGroup("Data Attributes", self.controlArea)
        OWGUI.radioButtonsInBox(self.att, self, 'ShowAttributeMethod', ['Show all', 'Hide all'], callback=self.updateAttributes)
        self.att.setDisabled(1)

        OWGUI.separator(self.controlArea)
        self.outBox = QVButtonGroup("Output", self.controlArea)
        OWGUI.radioButtonsInBox(self.outBox, self, 'sendDataType', ['None', 'Data with class conflict', 'Data with class agreement'], box='Data Selection',
                                tooltips=['No data will be sent to the output channel', 'Send data for which the predicted (and true class, if shown) are different.', 'Send data for which the predicted (and true class, if shown) match.'],
                                callback=self.checksenddata)
        OWGUI.checkBox(self.outBox, self, 'commitOnChange', 'Commit data on any change')
        self.commitBtn = OWGUI.button(self.outBox, self, "Commit", callback=self.senddata)

        self.outBox.setDisabled(1)

        # GUI - Table        
        self.layout = QVBoxLayout(self.mainArea)
        self.table = QTable(self.mainArea)
        self.table.setSelectionMode(QTable.NoSelection)
        self.header = self.table.horizontalHeader()
        self.vheader = self.table.verticalHeader()
        # manage sorting (not correct, does not handle real values)
        self.connect(self.header, SIGNAL("pressed(int)"), self.sort)
        self.sortby = -1

        self.layout.add(self.table)
#        self.table.hide()

    # updates the columns associated with the classifiers
    def updateTableOutcomes(self):
        if self.freezeAttChange: # program-based changes should not alter the table immediately
            return
        if not self.data or not self.classifiers:
            return
        
        attsel = [self.lbClasses.isSelected(i) for i in range(len(self.data.domain.attributes))]
        showatt = attsel.count(1)
        # sindx is the column where these start
        sindx = 1 + len(self.data.domain.attributes) + 1 * (self.data.domain.classVar<>None)
        col = sindx
        if self.ShowClass or self.ShowProb:
            for (cid, c) in enumerate(self.classifiers.values()):
                if self.data.domain.classVar.varType == orange.VarTypes.Continuous:
                    # regression
                    for (i, d) in enumerate(self.data):
                        cl = c(d)
                        self.classifications[i].append(cl)
                        self.table.setText(self.rindx[i], col, str(cl))
                else:
                    # classification
                    for (i, d) in enumerate(self.data):
                        (cl, p) = c(d, orange.GetBoth)
                        self.classifications[i].append(cl)
                        s = ''
                        if self.ShowProb and showatt:
                            s += reduce(lambda x,y: x+' : '+y, map(lambda x: "%5.3f"%x[1], filter(lambda x,s=attsel: s[x[0]], enumerate(p))))
                            if self.ShowClass:
                                s += ' -> '
                        if self.ShowClass:
                            s += str(cl)
                        self.table.setText(self.rindx[i], col, s)
                col += 1
        else:
            for i in range(len(self.data)):
                for c in range(len(self.classifiers)):
                    self.table.setText(self.rindx[i], col+c, '')
            col += len(self.classifiers)
    
        for i in range(sindx, col):
            self.table.adjustColumn(i)
            if self.ShowClass or self.ShowProb:
                self.table.showColumn(i)
            else:
                self.table.hideColumn(i)

    def updateTrueClass(self):
        if self.classifiers:
            col = 1+len(self.data.domain.attributes)
            if self.ShowTrueClass and self.data.domain.classVar:
                self.table.showColumn(col)
                self.table.adjustColumn(col)
            else:
                self.table.hideColumn(col)

    def updateAttributes(self):
        if self.ShowAttributeMethod == 0:
            for i in range(len(self.data.domain.attributes)):
                self.table.showColumn(i+1)
                self.table.adjustColumn(i+1)
        if self.ShowAttributeMethod == 1:
            for i in range(len(self.data.domain.attributes)):
                self.table.hideColumn(i+1)

    # defines the table and paints its contents    
    def setTable(self):
        if self.data==None:
            return

        self.table.setNumCols(0)
        self.table.setNumCols(1 + len(self.data.domain.attributes) + (self.ShowTrueClass) + len(self.classifiers))
        self.table.setNumRows(len(self.data))

        # HEADER: set the header (attribute names)
        self.header.setLabel(0, '#')
        for col in range(len(self.data.domain.attributes)):
            self.header.setLabel(col+1, self.data.domain.attributes[col].name)
        col = len(self.data.domain.attributes)+1
        self.header.setLabel(col, self.data.domain.classVar.name)
        col += 1
        for (i,c) in enumerate(self.classifiers.values()):
            self.header.setLabel(col+i, c.name)

        # ATTRIBUTE VALUES: set the contents of the table (values of attributes), data first
        for i in range(len(self.data)):
            self.table.setText(i, 0, str(i+1))
            for j in range(len(self.data.domain.attributes)):
                self.table.setText(i, j+1, str(self.data[i][j]))
        col = 1+len(self.data.domain.attributes)

        self.classifications = [[]] * len(self.data)
        if self.data.domain.classVar:
            # column for the true class
            for i in range(len(self.data)):
                c = self.data[i].getclass()
                item = colorItem(self.table, QTableItem.WhenCurrent, str(c))
                self.table.setItem(i, col, item)
                self.classifications[i] = [c]
            col += 1
    
        for i in range(col):
            self.table.adjustColumn(i)

        # include classifications
        self.updateTableOutcomes()
        self.updateAttributes()
        self.updateTrueClass()
        self.table.hideColumn(0) # hide column with indices, we will use vertical header to show this info
                
    def sort(self, col):
        "sorts the table by column col"
        self.sortby = - self.sortby
        self.table.sortColumn(col, self.sortby>=0, TRUE)

        # the table may be sorted, figure out data indices
        for i in range(len(self.data)):
            self.rindx[int(str(self.table.item(i,0).text()))-1] = i
        for (i, indx) in enumerate(self.rindx):
            self.vheader.setLabel(i, self.table.item(i,0).text())
        
    ##############################################################################
    # Input signals

    def dataset(self,data):
        self.data = data
        if not data:
            self.table.hide()
            self.send("Selected Examples", None)
        else:
            if self.data.domain.classVar.varType == orange.VarTypes.Continuous:
                # regression
                pass
            else:
                lb = self.lbClasses
                lb.clear()
                for v in self.data.domain.classVar.values:
                    lb.insertItem(str(v))
                self.freezeAttChange = 1
                for i in range(len(self.data.domain.classVar.values)):
                    lb.setSelected(i, 1)
                self.freezeAttChange = 0
                lb.show()
                # classification

            if not self.classifiers:
                self.ShowTrueClass = 1
            
            self.rindx = range(len(self.data))
            self.setTable()
            self.table.show()
            self.checkenable()

    def classifier(self, c, id):
        if not c:
            if self.classifiers.has_key(id):
                del self.classifiers[id]
        else:
            self.classifiers[id] = c
        if self.data:
            self.setTable()
            self.table.show()
        self.checkenable()

    # based on the data and classifiers enables/disables the control boxes
    def checkenable(self):
        # following should be more complicated and depends on what data are we showing
        cond = self.data<>None and (len(self.classifiers)>1 or len(self.classifiers)>0 and self.ShowTrueClass)
        self.outBox.setEnabled(cond)
        if self.commitOnChange:
            if cond:
                self.senddata()
            else:
                self.send("Selected Examples", None)

        self.trueClassCheckBox.setEnabled(self.data<>None and self.data.domain.classVar<>None)
##        self.options.setEnabled(len(self.classifiers)>0)
        self.att.setEnabled(self.data<>None)            
        self.options.setEnabled(self.data<>None)            
        

    ##############################################################################
    # Ouput signals

    def checksenddata(self):
        if self.commitOnChange and self.outBox.isEnabled():
            self.senddata()

    # assumes that the data and display conditions
    # (enough classes are displayed) have been checked
    
    def senddata(self):
        def cmpclasses(clist):
            ref = clist[0]
            for c in clist[1:]:
                if c<>ref: return 0
            return 1

        if not self.sendDataType or not self.data or not self.classifiers:
            self.send("Selected Examples", None)
            return

        # list of columns to check
        selclass = [[],[0]][self.ShowTrueClass>0]
        for (i, classifier) in enumerate(self.classifiers):
            selclass.append(i+1)
        
##        s = [reduce(lambda x,y: [x, None][x==None or x<>y],  map(lambda x: cls[x], selclass)) <> None for cls in self.classifications]
        s = [cmpclasses(map(lambda x: cls[x], selclass)) for cls in self.classifications]
        if self.sendDataType == 1:
            s = [not x for x in s]
        data_selection = self.data.select(s)
        self.send("Selected Examples", data_selection)

##############################################################################
# Test the widget, run from DOS prompt

if __name__=="__main__":
    a = QApplication(sys.argv)
    ow = OWPredictions()
    a.setMainWidget(ow)
    ow.show()

    if 0: # data set only
        data = orange.ExampleTable('sailing')
        ow.dataset(data)
    elif 0: 
        data = orange.ExampleTable('outcome')
        test = orange.ExampleTable('cheat', uses=data.domain)
        data = orange.ExampleTable('iris')

        bayes = orange.BayesLearner(data, name="NBC")

        import orngTree
        tree = orngTree.TreeLearner(data, name="Tree")
        ow.classifier(bayes, 1)
        ow.classifier(tree, 2)
        ow.dataset(test)
    elif 1: # two classifiers
        data = orange.ExampleTable('sailing.txt')
        bayes = orange.BayesLearner(data)
        bayes.name = "NBC"
        ow.classifier(bayes, 1)
        maj = orange.MajorityLearner(data)
        maj.name = "Majority"
        import orngTree
        tree = orngTree.TreeLearner(data, name="Tree")
        knn = orange.kNNLearner(data, k = 10)
        knn.name = "knn"
        ow.classifier(maj, 2)
        ow.classifier(knn, 3)
        ow.dataset(data)
    else: # regression
        data = orange.ExampleTable('auto-mpg')
        knn = orange.kNNLearner(data, name="knn")
        knn.name = "knn"
        maj = orange.MajorityLearner(data)
        maj.name = "Majority"
        ow.classifier(knn, 1)
        ow.classifier(maj, 2)
        ow.dataset(data)
        
    a.exec_loop()
    ow.saveSettings()

⌨️ 快捷键说明

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