📄 owinteractivediscretization.py
字号:
self.plotProbCurve(True)
self.plotBaseCurve(True)
self.plotCutLines()
self.updateLayout()
self.update()
class ListItemWithLabel(QListBoxPixmap):
def __init__(self, icon, name, labelIdx, master):
QListBoxPixmap.__init__(self, icon, name)
self.master = master
self.labelIdx = labelIdx
def paint(self, painter):
btext = str(self.text())
self.setText(btext + self.master.indiLabels[self.labelIdx])
QListBoxPixmap.paint(self, painter)
self.setText(btext)
class OWInteractiveDiscretization(OWWidget):
settingsList=["autoApply", "measure", "showBaseLine", "showLookaheadLine", "showTargetClassProb", "showRug", "snap", "autoSynchronize"]
contextHandlers = {"": DomainContextHandler("", ["targetClass", "discretization", "classDiscretization",
"indiDiscretization", "intervals", "classIntervals", "indiIntervals",
"outputOriginalClass", "indiData", "indiLabels", "resetIndividuals",
"selectedAttr", "customSplits"], False, False, False, False)}
callbackDeposit=[]
def __init__(self, parent=None, signalManager=None, name="Interactive Discretization"):
OWWidget.__init__(self, parent, signalManager, name)
self.showBaseLine=1
self.showLookaheadLine=1
self.showTargetClassProb=1
self.showRug=1
self.snap=1
self.measure=0
self.targetClass=0
self.discretization = self.classDiscretization = self.indiDiscretization = 1
self.intervals = self.classIntervals = self.indiIntervals = 3
self.outputOriginalClass = True
self.indiData = []
self.indiLabels = []
self.resetIndividuals = 0
self.selectedAttr = 0
self.customSplits = ["", "", ""]
self.autoApply = True
self.dataChanged = False
self.autoSynchronize = True
self.pointsChanged = False
self.customLineEdits = []
self.needsDiscrete = []
self.data = self.originalData = None
self.loadSettings()
self.inputs=[("Examples", ExampleTableWithClass, self.cdata)]
self.outputs=[("Examples", ExampleTableWithClass)]
self.measures=[("Information gain", orange.MeasureAttribute_info()),
#("Gain ratio", orange.MeasureAttribute_gainRatio),
("Gini", orange.MeasureAttribute_gini()),
("chi-square", orange.MeasureAttribute_chiSquare()),
("chi-square prob.", orange.MeasureAttribute_chiSquare(computeProbabilities=1)),
("Relevance", orange.MeasureAttribute_relevance()),
("ReliefF", orange.MeasureAttribute_relief())]
self.discretizationMethods=["Leave continuous", "Entropy-MDL discretization", "Equal-frequency discretization", "Equal-width discretization"]
self.classDiscretizationMethods=["Equal-frequency discretization", "Equal-width discretization"]
self.indiDiscretizationMethods=["Default", "Leave continuous", "Entropy-MDL discretization", "Equal-frequency discretization", "Equal-width discretization"]
self.layout = QVBoxLayout(self.mainArea, QVBoxLayout.TopToBottom,0)
self.mainVBox = OWGUI.widgetBox(self.mainArea)
self.mainHBox = OWGUI.widgetBox(self.mainVBox, orientation=0)
vbox = OWGUI.widgetBox(self.mainHBox)
box = OWGUI.radioButtonsInBox(vbox, self, "discretization", self.discretizationMethods, "Default discretization", callback=[self.clearLineEditFocus, self.defaultMethodChanged])
self.needsDiscrete.append(box.buttons[1])
box.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed))
self.interBox = OWGUI.widgetBox(box)
OWGUI.widgetLabel(self.interBox, "Number of intervals")
OWGUI.separator(self.interBox, height=4)
self.intervalSlider=OWGUI.hSlider(OWGUI.indentedBox(self.interBox), self, "intervals", None, 2, 10, callback=[self.clearLineEditFocus, self.defaultMethodChanged])
OWGUI.separator(vbox)
OWGUI.radioButtonsInBox(vbox, self, "resetIndividuals", ["Default discretization", "Custom 1", "Custom 2", "Custom 3", "Individual settings"], "Reset individual attribute settings", callback = self.setAllIndividuals)
OWGUI.separator(vbox)
box = self.classDiscBox = OWGUI.radioButtonsInBox(vbox, self, "classDiscretization", self.classDiscretizationMethods, "Class discretization", callback=[self.clearLineEditFocus, self.classMethodChanged])
cinterBox = OWGUI.widgetBox(box)
OWGUI.widgetLabel(cinterBox, "Number of intervals")
OWGUI.separator(cinterBox, height=4)
self.intervalSlider=OWGUI.hSlider(OWGUI.indentedBox(cinterBox), self, "classIntervals", None, 2, 10, callback=[self.clearLineEditFocus, self.classMethodChanged])
hbox = OWGUI.widgetBox(box, orientation = 0)
OWGUI.appendRadioButton(box, self, "discretization", "Custom" + " ", insertInto = hbox)
self.classCustomLineEdit = OWGUI.LineEditWFocusOut(hbox, self.classCustomChanged, focusInCallback = self.classCustomSelected)
self.connect(self.classCustomLineEdit, SIGNAL("returnPressed ()"), self.classCustomChanged)
box.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed))
OWGUI.separator(box)
self.classIntervalsLabel = OWGUI.widgetLabel(box, "Current splits: ")
OWGUI.separator(box)
OWGUI.checkBox(box, self, "outputOriginalClass", "Output original class")
OWGUI.widgetLabel(box, "(Widget always uses discretized class internally.)")
OWGUI.separator(vbox)
OWGUI.rubber(vbox)
box = OWGUI.widgetBox(vbox, "Commit")
applyButton = OWGUI.button(box, self, "Commit", callback = self.commit)
autoApplyCB = OWGUI.checkBox(box, self, "autoApply", "Commit automatically", callback=[self.clearLineEditFocus])
OWGUI.setStopper(self, applyButton, autoApplyCB, "dataChanged", self.commit)
OWGUI.separator(self.mainHBox, width=25)
self.mainIABox = OWGUI.widgetBox(self.mainHBox, "Individual attribute settings")
self.layout.addWidget(self.mainVBox)
self.mainBox = OWGUI.widgetBox(self.mainIABox, orientation=0)
OWGUI.separator(self.mainIABox)#, height=30)
graphBox = OWGUI.widgetBox(self.mainIABox, "", orientation=0)
self.needsDiscrete.append(graphBox)
graphOptBox = OWGUI.widgetBox(graphBox)
OWGUI.separator(graphBox, width=10)
self.graph = DiscGraph(self, graphBox)
graphOptBox.setSpacing(4)
box = OWGUI.widgetBox(graphOptBox, "Split gain measure", addSpace=True)
self.measureCombo=OWGUI.comboBox(box, self, "measure", orientation=0, items=[e[0] for e in self.measures], callback=[self.clearLineEditFocus, self.graph.computeBaseScore, self.graph.plotBaseCurve])
OWGUI.checkBox(box, self, "showBaseLine", "Show discretization gain", callback=[self.clearLineEditFocus, self.graph.plotBaseCurve])
OWGUI.checkBox(box, self, "showLookaheadLine", "Show lookahead gain", callback=self.clearLineEditFocus)
box = OWGUI.widgetBox(graphOptBox, "Target class", addSpace=True)
self.targetCombo=OWGUI.comboBox(box, self, "targetClass", orientation=0, callback=[self.clearLineEditFocus, self.graph.targetClassChanged])
OWGUI.checkBox(box, self, "showTargetClassProb", "Show target class probability", callback=[self.clearLineEditFocus, self.graph.plotProbCurve])
OWGUI.checkBox(box, self, "showRug", "Show rug", callback=[self.clearLineEditFocus, self.graph.plotRug])
box = OWGUI.widgetBox(graphOptBox, "Editing", addSpace=True)
OWGUI.checkBox(box, self, "snap", "Snap to grid", callback=[self.clearLineEditFocus])
syncCB = OWGUI.checkBox(box, self, "autoSynchronize", "Apply on the fly", callback=self.clearLineEditFocus)
syncButton = OWGUI.button(box, self, "Apply", callback = self.synchronizePressed)
OWGUI.setStopper(self, syncButton, syncCB, "pointsChanged", self.synchronize)
OWGUI.rubber(graphOptBox)
attrListBox = QVBox(self.mainBox)
self.attrList = QListBox(attrListBox)
self.attrList.setFixedWidth(300)
self.defaultMethodChanged()
self.connect(self.attrList, SIGNAL("highlighted ( int )"), self.individualSelected)
OWGUI.separator(self.mainBox, width=10)
box = OWGUI.radioButtonsInBox(QHButtonGroup(self.mainBox), self, "indiDiscretization", [], callback=[self.clearLineEditFocus, self.indiMethodChanged])
hbbox = OWGUI.widgetBox(box)
hbbox.setSpacing(4)
for meth in self.indiDiscretizationMethods:
OWGUI.appendRadioButton(box, self, "discretization", meth, insertInto = hbbox)
self.needsDiscrete.append(box.buttons[2])
self.indiInterBox = OWGUI.widgetBox(hbbox)
OWGUI.widgetLabel(self.indiInterBox, "Number of intervals")
OWGUI.separator(self.indiInterBox, height=4)
self.indiIntervalSlider=OWGUI.hSlider(OWGUI.indentedBox(self.indiInterBox), self, "indiIntervals", None, 2, 10, callback=[self.clearLineEditFocus, self.indiMethodChanged])
OWGUI.rubber(self.indiInterBox)
OWGUI.separator(box)
hbbox = OWGUI.widgetBox(box)
for i in range(3):
hbox = OWGUI.widgetBox(hbbox, orientation = 0)
OWGUI.appendRadioButton(box, self, "discretization", "Custom %i" % (i+1) + " ", insertInto = hbox)
le = OWGUI.LineEditWFocusOut(hbox, lambda w=i: self.customChanged(w), focusInCallback = lambda w=i: self.customSelected(w))
self.connect(le, SIGNAL("returnPressed ()"), lambda w=i: self.customChanged(w))
le.setFixedWidth(110)
self.customLineEdits.append(le)
OWGUI.button(hbox, self, "CC", width=30, callback = lambda w=i: self.copyToCustom(w))
OWGUI.rubber(hbbox)
self.controlArea.setFixedWidth(1)
self.contAttrIcon = self.createAttributeIconDict()[orange.VarTypes.Continuous]
def cdata(self, data=None):
self.closeContext()
self.indiData = []
self.attrList.clear()
for le in self.customLineEdits:
le.clear()
self.indiDiscretization = 0
self.originalData = data
haveClass = bool(data and data.domain.classVar)
continuousClass = haveClass and data.domain.classVar.varType == orange.VarTypes.Continuous
if continuousClass:
self.discretizeClass()
else:
self.data = self.originalData
for c in self.needsDiscrete:
c.setEnabled(haveClass)
if self.data:
domain = self.data.domain
self.continuousIndices = [i for i, attr in enumerate(domain.attributes) if attr.varType == orange.VarTypes.Continuous]
if not self.continuousIndices:
self.data = None
self.classDiscBox.setEnabled(not data or continuousClass)
if self.data:
for i, attr in enumerate(domain.attributes):
if attr.varType == orange.VarTypes.Continuous:
self.attrList.insertItem(ListItemWithLabel(self.contAttrIcon, attr.name, self.attrList.count(), self))
self.indiData.append([0, 4, "", "", ""])
else:
self.indiData.append(None)
self.fillClassCombo()
self.indiLabels = [""] * self.attrList.count()
self.graph.setData(None, data)
self.openContext("", data)
self.computeDiscretizers()
self.attrList.setCurrentItem(self.selectedAttr)
else:
self.targetCombo.clear()
self.graph.setData(None, None)
# Prevent entropy discretization with non-discrete class
if not haveClass:
if self.discretization == 1:
self.discretization = 2
if self.indiDiscretization == 2:
self.indiDiscretization = 0
for indiData in self.indiData:
if indiData and indiData[0] == 2:
indiData[0] = 0
# self.graph.setData(self.data)
self.send("Examples", self.data)
self.makeConsistent()
def fillClassCombo(self):
if not self.data:
return
domain = self.data.domain
self.targetCombo.clear()
for v in domain.classVar.values:
self.targetCombo.insertItem(str(v))
if self.targetClass<len(domain.classVar.values):
self.targetCombo.setCurrentItem(self.targetClass)
else:
self.targetCombo.setCurrentItem(0)
self.targetClass=0
def classChanged(self):
self.fillClassCombo()
self.computeDiscretizers()
def clearLineEditFocus(self):
if self.data:
df = self.indiDiscretization
for le in self.customLineEdits:
if le.hasFocus():
le.clearFocus()
self.indiDiscretization = self.indiData[self.continuousIndices[self.selectedAttr]][0] = df
if self.classCustomLineEdit.hasFocus():
self.classCustomLineEdit.clearFocus()
def individualSelected(self, i):
if not self.data:
return
self.selectedAttr = i
attrIndex = self.continuousIndices[i]
attr = self.data.domain[attrIndex]
indiData = self.indiData[attrIndex]
self.customSplits = indiData[2:]
for le, cs in zip(self.customLineEdits, self.customSplits):
le.setText(" ".join(cs))
self.indiDiscretization, self.indiIntervals = indiData[:2]
if self.data.domain.classVar:
self.graph.setData(attr, self.data)
if hasattr(self, "discretizers"):
self.graph.setSplits(self.discretizers[attrIndex] and self.discretizers[attrIndex].getValueFrom.transformer.points or [])
def computeDiscretizers(self):
self.discretizers = []
if not self.data:
return
self.discretizers = [None] * len(self.data.domain)
for i, idx in enumerate(self.continuousIndices):
self.computeDiscretizer(i, idx)
self.commitIf()
def makeConsistent(self):
self.interBox.setEnabled(self.discretization>=2)
self.indiInterBox.setEnabled(self.indiDiscretization in [3, 4])
def defaultMethodChanged(self):
self.interBox.setEnabled(self.discretization>=2)
if not self.data:
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -