source: orange/orange/OrangeWidgets/Unsupervised/OWExampleDistance.py @ 9058:7d7eaa6f04a6

Revision 9058:7d7eaa6f04a6, 5.1 KB checked in by ales_erjavec <ales.erjavec@…>, 3 years ago (diff)

Added 'Normalize data' check box.

Line 
1"""
2<name>Example Distance</name>
3<description>Computes a distance matrix from a set of data examples.</description>
4<icon>icons/ExampleDistance.png</icon>
5<contact>Blaz Zupan (blaz.zupan(@at@)fri.uni-lj.si)</contact>
6<priority>1300</priority>
7"""
8import orange, math
9import OWGUI
10from OWWidget import *
11import random
12import orngClustering
13import orngMisc
14
15##############################################################################
16# main class
17
18class OWExampleDistance(OWWidget):
19    settingsList = ["Metrics", "Normalize"]
20    contextHandlers = {"": DomainContextHandler("", ["Label"])}
21
22    def __init__(self, parent=None, signalManager = None):
23        OWWidget.__init__(self, parent, signalManager, 'ExampleDistance', wantMainArea = 0, resizingEnabled = 0)
24
25        self.inputs = [("Examples", ExampleTable, self.dataset)]
26        self.outputs = [("Distance Matrix", orange.SymMatrix)]
27
28        self.Metrics = 0
29        self.Normalize = True
30        self.Label = ""
31        self.loadSettings()
32        self.data = None
33        self.matrix = None
34
35        self.metrics = [
36            ("Euclidean", orange.ExamplesDistanceConstructor_Euclidean),
37            ("Pearson Correlation", orngClustering.ExamplesDistanceConstructor_PearsonR),
38            ("Spearman Rank Correlation", orngClustering.ExamplesDistanceConstructor_SpearmanR),
39            ("Manhattan", orange.ExamplesDistanceConstructor_Manhattan),
40            ("Hamming", orange.ExamplesDistanceConstructor_Hamming),
41            ("Relief", orange.ExamplesDistanceConstructor_Relief),
42            ]
43
44        cb = OWGUI.comboBox(self.controlArea, self, "Metrics", box="Distance Metrics",
45            items=[x[0] for x in self.metrics],
46            tooltip="Choose metrics to measure pairwise distance between examples.",
47            callback=self.distMetricChanged, valueType=str)
48        cb.setMinimumWidth(170)
49       
50        OWGUI.separator(self.controlArea)
51       
52        box = OWGUI.widgetBox(self.controlArea, "Normalization", 
53                              addSpace=True)
54        self.normalizeCB = OWGUI.checkBox(box, self, "Normalize", "Normalize data", 
55                                          callback=self.computeMatrix)
56       
57        self.normalizeCB.setEnabled(self.Metrics in [0, 3])
58       
59        self.labelCombo = OWGUI.comboBox(self.controlArea, self, "Label", box="Example Label",
60            items=[],
61            tooltip="Attribute used for example labels",
62            callback=self.setLabel, sendSelectedValue = 1)
63
64        self.labelCombo.setDisabled(1)
65       
66        OWGUI.rubber(self.controlArea)
67
68    def sendReport(self):
69        self.reportSettings("Settings",
70                            [("Metrics", self.metrics[self.Metrics][0]),
71                             ("Label", self.Label)])
72        self.reportData(self.data)
73
74    def distMetricChanged(self):
75        self.normalizeCB.setEnabled(self.Metrics in [0, 3])
76        self.computeMatrix()
77
78    def computeMatrix(self):
79        if not self.data:
80            return
81        data = self.data
82        constructor = self.metrics[self.Metrics][1]()
83        constructor.normalize = self.Normalize
84        dist = constructor(data)
85        self.error(0)
86        try:
87            self.matrix = orange.SymMatrix(len(data))
88        except orange.KernelException, ex:
89            self.error(0, "Could not create distance matrix! %s" % str(ex))
90            self.matrix = None
91            self.send("Distance Matrix", None)
92            return
93        self.matrix.setattr('items', data)
94        pb = OWGUI.ProgressBar(self, 100)
95        milestones  = orngMisc.progressBarMilestones(len(data)*(len(data)-1)/2, 100)
96        count = 0
97        for i in range(len(data)):
98            for j in range(i+1):
99                self.matrix[i, j] = dist(data[i], data[j])
100                if count in milestones:
101                    pb.advance()
102                count += 1
103        pb.finish()
104        self.send("Distance Matrix", self.matrix)
105
106    def setLabel(self):
107        for d in self.data:
108            d.name = str(d[str(self.Label)])
109        self.send("Distance Matrix", self.matrix)
110
111    def setLabelComboItems(self):
112        d = self.data
113        self.labelCombo.clear()
114        self.labelCombo.setDisabled(0)
115        labels = [m.name for m in d.domain.getmetas().values()] + \
116                 [a.name for a in d.domain.variables]
117        self.labelCombo.addItems(labels)
118        # here we would need to use the domain dependent setting of the label id
119        self.labelCombo.setCurrentIndex(0); self.Label = labels[0]
120        self.setLabel()
121
122    def dataset(self, data):
123        if data and len(data.domain.attributes):
124            self.data = data
125            self.setLabelComboItems()
126            self.computeMatrix()
127        else:
128            self.send("Distance Matrix", None)
129
130##################################################################################################
131# test script
132
133if __name__=="__main__":
134    import os
135    data = orange.ExampleTable(r'../../doc/datasets/glass')
136    data = orange.ExampleTable('glass')
137    a = QApplication(sys.argv)
138    ow = OWExampleDistance()
139    ow.show()
140    ow.dataset(data)
141    a.exec_()
142    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.