source: orange/Orange/OrangeWidgets/Unsupervised/OWSOM.py @ 11318:2645d3af788a

Revision 11318:2645d3af788a, 6.5 KB checked in by Ales Erjavec <ales.erjavec@…>, 14 months ago (diff)

Ported SOM to new Orange library structure (orange2to25).

Line 
1"""
2<name>SOM</name>
3<description>Self organizing maps learner.</description>
4<icon>icons/SOM.svg</icon>
5<contact>Ales Erjavec (ales.erjevec(@at@)fri.uni.lj.si)</contact>
6<priority>5010</priority>
7"""
8
9import Orange
10from Orange.projection import som
11
12from OWWidget import *
13import OWGUI
14
15
16class OWSOM(OWWidget):
17    settingsList = ["xdim", "ydim", "neighborhood", "topology", "alphaType",
18                    "iterations1", "iterations2", "radius1", "radius2",
19                    "alpha1", "alpha2", "initialization", "eps"]
20
21    def __init__(self, parent=None, signalManager=None, name="SOM"):
22        OWWidget.__init__(self, parent, signalManager, name,
23                          wantMainArea=False)
24
25        self.inputs = [("Data", Orange.data.Table, self.setData)]
26        self.outputs = [("Classifier", Orange.core.Classifier),
27                        ("Learner", Orange.core.Learner),
28                        ("SOM", som.SOMMap)]
29
30        self.LearnerName = "SOM Map"
31        self.xdim = 5
32        self.ydim = 10
33        self.initialization = som.InitializeLinear
34        self.neighborhood = 0
35        self.topology = 0
36        self.alphaType = 0
37        self.iterations1 = 100
38        self.iterations2 = 10000
39        self.radius1 = 3
40        self.radius2 = 1
41        self.eps = 1e-5
42        self.alpha1 = 0.05
43        self.alpha2 = 0.01
44        self.loadSettings()
45
46        self.TopolMap = [som.HexagonalTopology,
47                         som.RectangularTopology]
48
49        self.NeighMap = [som.NeighbourhoodGaussian,
50                         som.NeighbourhoodBubble]
51
52        self.learnerName = OWGUI.lineEdit(
53            self.controlArea, self, "LearnerName",
54            box="Learner/Classifier Name",
55            tooltip=("Name to be used by other widgets to identify your "
56                     "Learner/Classifier")
57        )
58
59        box = OWGUI.radioButtonsInBox(
60            self.controlArea, self, "topology",
61            ["Hexagonal topology", "Rectangular topology"],
62            box="Topology"
63        )
64
65        OWGUI.spin(box, self, "xdim", 4, 1000,
66                   orientation="horizontal",
67                   label="Columns")
68
69        OWGUI.spin(box, self, "ydim", 4, 1000,
70                   orientation="horizontal",
71                   label="Rows")
72
73        OWGUI.radioButtonsInBox(self.controlArea, self, "initialization",
74                                ["Linear", "Random"],
75                                box="Map Initialization")
76
77        OWGUI.radioButtonsInBox(self.controlArea, self, "neighborhood",
78                                ["Gaussian neighborhood",
79                                 "Bubble neighborhood"],
80                                box="Neighborhood")
81
82        b = OWGUI.widgetBox(self.controlArea, "Radius")
83
84        OWGUI.spin(b, self, "radius1", 2, 50,
85                   orientation="horizontal", label="Initial radius")
86
87        OWGUI.spin(b, self, "radius2", 1, 50,
88                   orientation="horizontal", label="Final radius")
89
90        b = OWGUI.widgetBox(self.controlArea, "Stopping Conditions")
91        OWGUI.spin(b, self, "iterations1", 10, 10000, label="Iterations")
92
93        OWGUI.button(self.controlArea, self, "&Apply",
94                     callback=self.ApplySettings,
95                     default=True)
96
97        OWGUI.rubber(self.controlArea)
98
99        self.data = None
100        self.classifier = None
101        self.learner = None
102
103        self.resize(100, 100)
104
105    def dataWithDefinedValues(self, data):
106        self.warning(1235)
107        self.warning(1236)
108        exclude = []
109        for attr in data.domain.variables:
110            if not any(not ex[attr].isSpecial() for ex in data):
111                exclude.append(attr)
112
113        if exclude:
114            self.warning(1235,
115                         "Excluding attributes with all unknown "
116                         "values: %s." % \
117                         ", ".join(attr.name for attr in exclude))
118
119            exclude_class = data.domain.class_var in exclude
120            if exclude_class:
121                self.warning(1236,
122                             "Excluding class attribute: %s" % \
123                             data.domain.class_var.name)
124
125            domain = Orange.data.Domain(
126                [attr for attr in data.domain.variables
127                 if attr not in exclude],
128                data.domain.class_var if not exclude_class else False
129            )
130
131            domain.addmetas(data.domain.getmetas())
132            data = Orange.data.Table(domain, data)
133
134        return data
135
136    def setData(self, data=None):
137        self.data = data
138        if data:
139            self.data = self.dataWithDefinedValues(data)
140            self.ApplySettings()
141        else:
142            self.send("Classifier", None)
143            self.send("SOM", None)
144            self.send("Learner", None)
145
146    def ApplySettings(self):
147        topology = self.TopolMap[self.topology]
148        neigh = self.NeighMap[self.neighborhood]
149
150        self.learner = som.SOMLearner(
151            name=self.LearnerName,
152            map_shape=(self.xdim, self.ydim),
153            topology=topology,
154            neighbourhood=neigh,
155            epochs=self.iterations1,
156            eps=self.eps,
157            initialize=self.initialization,
158            radius_ini=self.radius1,
159            radius_fin=self.radius2
160        )
161
162        self.send("Learner", self.learner)
163
164        if self.data:
165            self.progressBarInit()
166            self.classifier = self.learner(
167                self.data, progressCallback=self.progressBarSet
168            )
169
170            self.progressBarFinished()
171            self.classifier.name = self.LearnerName
172            self.classifier.setattr("data", self.data)
173            if self.data.domain.class_var:
174                self.send("Classifier", self.classifier)
175            self.send("SOM", self.classifier)
176
177    def sendReport(self):
178        self.reportSettings(
179            "Topology",
180            [("Shape", ["hexagonal", "rectangular"][self.topology]),
181             ("Size", "%i columns, %i rows" % (self.xdim, self.ydim))]
182        )
183
184        self.reportSettings(
185            "Optimization",
186            [("Initialization", ["linear", "random"][self.initialization]),
187             ("Neighborhood", ["Gaussian", "bubble"][self.neighborhood]),
188             ("Radius", "initial: %i, final: %i" % \
189              (self.radius1, self.radius2)),
190             ("Number of iterations", self.iterations1)
191            ])
192
193
194if __name__ == "__main__":
195    app = QApplication(sys.argv)
196    w = OWSOM()
197    w.show()
198    data = Orange.data.Table("iris")
199
200    w.setData(data)
201    app.exec_()
Note: See TracBrowser for help on using the repository browser.