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

📄 owhierarchicalclustering.py

📁 orange源码 数据挖掘技术
💻 PY
📖 第 1 页 / 共 3 页
字号:
"""
<name>Hierarchical Clustering</name>
<description>Hierarchical clustering based on distance matrix, and a dendrogram viewer.</description>
<icon>HierarchicalClustering.png</icon>
<contact>Ales Erjavec (ales.erjavec324(@at@)email.si)</contact> 
<prority>1550</priority>
"""

from OWWidget import *
from qtcanvas import *
from sets import Set
import qt
import OWGUI
import OWGraphTools
import math
import os

try:
    from OWDataFiles import DataFiles
except:
    class DataFiles:
        pass


class OWHierarchicalClustering(OWWidget):
    settingsList=["Linkage", "OverwriteMatrix", "Annotation", "Brightness", "PrintDepthCheck",
                "PrintDepth", "HDSize", "VDSize", "FitToWindow","AutoResize",
                "TextSize", "LineSpacing", "ZeroOffset", "SelectionMode", "DisableHighlights",
                "DisableBubble", "ClassifySelected", "CommitOnChange", "ClassifyName"]
    def __init__(self, parent=None, signalManager=None):
        #OWWidget.__init__(self, parent, 'Hierarchical Clustering')
        OWWidget.__init__(self, parent, signalManager, 'Hierarchical Clustering')
        self.parent=parent
        self.callbackDeposit=[]
        self.inputs=[("Distance matrix", orange.SymMatrix, self.dataset)]
        self.outputs=[("Selected Examples", ExampleTable), ("Structured Data Files", DataFiles)]
        self.linkage=[("Single ", orange.HierarchicalClustering.Single),
                        ("Average", orange.HierarchicalClustering.Average),
                        ("Complete", orange.HierarchicalClustering.Complete)]
        self.Linkage=0
        self.OverwriteMatrix=0
        self.Annotation=0
        self.Brightness=5
        self.PrintDepthCheck=0
        self.PrintDepth=100
        self.HDSize=500         #initial horizontal and vertical dendogram size
        self.VDSize=800
        self.FitToWindow=0
        self.AutoResize=0
        self.TextSize=8
        self.LineSpacing=4
        self.SelectionMode=0
        self.ZeroOffset=1
        self.DisableHighlights=0
        self.DisableBubble=0
        self.ClassifySelected=0
        self.CommitOnChange=0
        self.ClassifyName="HC_class"
        self.loadSettings()
        self.AutoResize=False
        self.inputMatrix=None
        self.matrixSource="Unknown"
        self.rootCluster=None
        self.selectedExamples=None
        self.ctrlPressed=FALSE

        self.linkageMethods=[a[0] for a in self.linkage]

        #################################
        ##GUI
        #################################

        #Tabs
        self.tabs=QTabWidget(self.controlArea,"tabWidget")
        self.settingsTab=QVGroupBox(self,"Settings")
        self.selectionTab=QVGroupBox(self,"Selection")
        self.tabs.insertTab(self.settingsTab, "Settings")
        self.tabs.insertTab(self.selectionTab, "Selection")

        #HC Settings
        OWGUI.comboBox(self.settingsTab, self, "Linkage", box="Linkage",
                items=self.linkageMethods, tooltip="Choose linkage method",
                callback=self.constructTree)
        #Label
        self.labelCombo=OWGUI.comboBox(self.settingsTab, self, "Annotation",
                box="Annotation", items=["None"],tooltip="Choose label attribute",
                callback=self.updateLabel)

        #Dendogram graphics settings
        dendogramBox=QVGroupBox(self.settingsTab, "Dendogram")
        dendogramBox.setTitle("Dendogram setings")
        #OWGUI.spin(dendogramBox, self, "Brightness", label="Brigthtness",min=1,max=9,step=1)
        OWGUI.checkWithSpin(dendogramBox, self, "Print depth", 1, 100, "PrintDepthCheck",
                "PrintDepth")
        #OWGUI.spin(dendogramBox, self, "VDSize", label="Vertical size", min=100,
        #        max=10000, step=10)
        self.hSizeBox=OWGUI.spin(dendogramBox, self, "HDSize", label="Horizontal size", min=200,
                max=10000, step=10)
        OWGUI.checkBox(dendogramBox, self, "FitToWindow","Fit hor. size to window",
                callback=lambda:self.hSizeBox.setDisabled(self.FitToWindow))
        self.hSizeBox.setDisabled(self.FitToWindow)
        #OWGUI.checkBox(dendogramBox, self, "FitToWindow", "Fit horizontal size")
        #OWGUI.checkBox(dendogramBox, self, "AutoResize", "Auto resize")
        OWGUI.spin(dendogramBox, self, "TextSize", label="Text font size",
                        min=5, max=15, step=1)
        OWGUI.spin(dendogramBox,self, "LineSpacing", label="Line spacing",
                        min=2,max=8,step=1)
        OWGUI.button(dendogramBox, self, "&Apply",self.applySettings)

        #Selection options
        OWGUI.checkBox(self.selectionTab, self, "SelectionMode", "Cutoff line", 
              callback=self.updateCutOffLine)
        self.classificationBox=QVGroupBox(self.selectionTab)
        #self.classificationBox.setTitle("Classification")
        OWGUI.checkBox(self.classificationBox, self, "ClassifySelected","Classify selected examples")
        OWGUI.lineEdit(self.classificationBox, self, "ClassifyName", "Class name")
        #selectionBox=QVGroupBox(self.selectionTab)
        commitBox=QVGroupBox(self.selectionTab)
        commitBox.setTitle("Commit settings")
        OWGUI.checkBox(commitBox, self, "CommitOnChange", "Commit on change")
        OWGUI.button(commitBox, self, "&Commit", self.commitData)
        OWGUI.checkBox(self.selectionTab, self, "DisableHighlights", "Disable highlights")
        OWGUI.checkBox(self.selectionTab, self, "DisableBubble", "Disable bubble info")
        OWGUI.button(self.controlArea, self, "&Save graph", self.saveGraph)

        self.mainAreaLayout=QVBoxLayout(self.mainArea, QVBoxLayout.TopToBottom,0)
        scale=QCanvas(self)
        self.headerView=ScaleCanvas(self, scale, self.mainArea)
        self.footerView=ScaleCanvas(self, scale, self.mainArea)
        self.dendogram=Dendogram(self)
        self.dendogramView=DendogramView(self.dendogram, self.mainArea)
    
        self.mainAreaLayout.addWidget(self.headerView)
        self.mainAreaLayout.addWidget(self.dendogramView)
        self.mainAreaLayout.addWidget(self.footerView)

        self.dendogram.header=self.headerView
        self.dendogram.footer=self.footerView

        self.connect(self.dendogramView.horizontalScrollBar(),SIGNAL("valueChanged(int)"),
                self.footerView.horizontalScrollBar().setValue)
        self.connect(self.dendogramView.horizontalScrollBar(),SIGNAL("valueChanged(int)"),
                self.headerView.horizontalScrollBar().setValue)
        self.dendogram.resize(self.HDSize,self.VDSize)
        self.dendogram.update()


    def dataset(self, data):
        self.matrix=data
        if not self.matrix:
            self.rootCluster=None
            self.selectedExamples=None
            self.dendogram.clear()
            self.footerView.clear()
            self.labelCombo.clear()
            self.send("Selected Examples", None)
            self.classificationBox.setDisabled(True)
            return

        self.matrixSource="Unknown"
        items=getattr(self.matrix, "items")
        if type(items)==orange.ExampleTable: #Example Table from Example Distance

            self.labels=["None","Default"]+ \
                         [a.name for a in items.domain.attributes]
            if items.domain.classVar:
                self.labels.append(items.domain.classVar.name)
                    
            self.labelInd=range(len(self.labels)-2)
            self.labels.extend([m.name for m in items.domain.getmetas().values()])
            self.labelInd.extend(items.domain.getmetas().keys())
            #print self.labelInd
            #print self.labels
            self.numMeta=len(items.domain.getmetas())
            self.metaLabels=items.domain.getmetas().values()
            self.matrixSource="Example Distance"
        elif  type(items)==list:   #Structured data files from Data Distance
            self.labels=["None", "Default", "Name", "Strain"]
            self.Annotation=0
            self.matrixSource="Data Distance"
        else:   #From Attribute Distance
            self.labels=["None","Attribute Name"]
            self.Annotation=0
            self.matrixSource="Attribute Distance"
        self.labelCombo.clear()
        for a in self.labels:
            self.labelCombo.insertItem(a)
        if self.labelCombo.count()<self.Annotation-1:
                self.Annotation=0
        self.labelCombo.setCurrentItem(self.Annotation)
        if self.matrixSource=="Example Distance":
            self.classificationBox.setDisabled(False)
        else:
            self.classificationBox.setDisabled(True)

        self.constructTree()

    def updateLabel(self):
        items=self.matrix.items
        if self.Annotation==0:
            self.rootCluster.mapping.setattr("objects",
                [" " for i in range(len(items))])

        elif self.Annotation==1:
            if self.matrixSource=="Example Distance" or self.matrixSource=="Data Distance":
                self.rootCluster.mapping.setattr("objects", range(len(items)))
            elif self.matrixSource=="Attribute Distance":
                self.rootCluster.mapping.setattr("objects", [a.name for a in items])
        elif self.matrixSource=="Example Distance":
            try:
                print self.labelInd[self.Annotation-2]
                self.rootCluster.mapping.setattr("objects",
                                [str(e[self.labelInd[self.Annotation-2]]) for e in items])
            except IndexError:
                self.Annotation=0
                self.rootCluster.mapping.setattr("objects", [str(e[0]) for e in items])
        elif self.matrixSource=="Data Distance":
            if self.Annotation==2:
                self.rootCluster.mapping.setattr("objects", [getattr(a, "name", "") for a in items])
            else:
                self.rootCluster.mapping.setattr("objects", [getattr(a, "strain", "") for a in items])
        #print self.rootCluster.mapping
        self.dendogram.updateLabel()

    def constructTree(self):
        if self.matrix:
            self.progressBarInit()
            self.rootCluster=orange.HierarchicalClustering(self.matrix,
                linkage=self.linkage[self.Linkage][1],
                overwriteMatrix=self.OverwriteMatrix,
                progressCallback=self.progressBarSet)
            self.progressBarFinished()
            self.dendogram.displayTree(self.rootCluster)
            self.updateLabel()

    def applySettings(self):
        self.dendogram.resize(self.HDSize, self.VDSize)
        self.dendogram.displayTree(self.rootCluster)

    def progressBarSet(self, value, a):
        OWWidget.progressBarSet(self, value*100)

    def keyPressEvent(self, key):
        if key.key()==Qt.Key_Control:
            self.ctrlPressed=TRUE
        else:
            key.ignore()

    def keyReleaseEvent(self, key):
        if key.key()==Qt.Key_Control:
            self.ctrlPressed=FALSE
        else:
            key.ignore()

    def updateCutOffLine(self):
        if self.SelectionMode:
            self.dendogram.cutOffLine.show()
            self.footerView.canvas().marker.show()
    	else:
            self.dendogram.cutOffLine.hide()
            self.footerView.canvas().marker.hide()
        self.dendogram.update()
        self.footerView.canvas().update()

    def updateSelection(self, selection):
        if self.matrixSource=="Attribute Distance":
            return
        self.selectionList=selection
        if self.CommitOnChange and self.dendogram.cutOffLineDragged==False:
            self.commitData()

    def commitData(self):
        self.selection=[]
        selection=self.selectionList
        maps=[self.rootCluster.mapping[c.first:c.last] for c in [e.rootCluster for e in selection]]
        self.selection=[self.matrix.items[k] for k in [j for i in range(len(maps)) for j in maps[i]]]

        if not self.selection:
            self.send("Selected Examples",None)
            self.send("Structured Data Files", None)
            return
        if self.matrixSource=="Example Distance":
            if self.ClassifySelected:
                classVar=orange.EnumVariable(self.ClassifyName ,
                            values=[str(i) for i in range(len(maps))])
                domain=orange.Domain(self.matrix.items.domain.attributes,classVar)
                if self.matrix.items.domain.classVar:
                    domain.addmetas(self.matrix.items.domain.getmetas())
                    id=orange.newmetaid()
                    domain.addmeta(id, self.matrix.items.domain.classVar)

⌨️ 快捷键说明

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