source: orange/orange/OrangeWidgets/Classify/OWKNN.py @ 9546:2b6cc6f397fe

Revision 9546:2b6cc6f397fe, 5.4 KB checked in by ales_erjavec <ales.erjavec@…>, 2 years ago (diff)

Renamed widget channel names in line with the new naming rules/convention.
Added backwards compatibility in orngDoc loadDocument to enable loading of schemas saved before the change.

Line 
1"""
2<name>k Nearest Neighbours</name>
3<description>K-nearest neighbours learner/classifier.</description>
4<icon>icons/kNearestNeighbours.png</icon>
5<contact>Janez Demsar (janez.demsar(@at@)fri.uni-lj.si)</contact>
6<priority>25</priority>
7"""
8from OWWidget import *
9import OWGUI
10from exceptions import Exception
11from orngWrap import PreprocessedLearner
12
13class OWKNN(OWWidget):
14    settingsList = ["name", "k", "metrics", "ranks", "normalize", "ignoreUnknowns"]
15
16    def __init__(self, parent=None, signalManager = None, name='kNN'):
17        OWWidget.__init__(self, parent, signalManager, name, wantMainArea = 0, resizingEnabled = 0)
18
19        self.callbackDeposit = []
20
21        self.inputs = [("Data", ExampleTable, self.setData), ("Preprocess", PreprocessedLearner, self.setPreprocessor)]
22        self.outputs = [("Learner", orange.Learner),("kNN Classifier", orange.kNNClassifier)]
23
24        self.metricsList = [("Euclidean", orange.ExamplesDistanceConstructor_Euclidean),
25                       ("Hamming", orange.ExamplesDistanceConstructor_Hamming),
26                       ("Manhattan", orange.ExamplesDistanceConstructor_Manhattan),
27                       ("Maximal", orange.ExamplesDistanceConstructor_Maximal),
28#                       ("Dynamic time warp", orange.ExamplesDistanceConstructor_DTW)
29                            ]
30
31        # Settings
32        self.name = 'kNN'
33        self.k = 5;  self.metrics = 0; self.ranks = 0
34        self.ignoreUnknowns = 0
35        self.normalize = self.oldNormalize = 1
36        self.loadSettings()
37
38        self.data = None                    # input data set
39        self.preprocessor = None            # no preprocessing as default
40        self.setLearner()                   # this just sets the learner, no data
41                                            # has come to the input yet
42
43        OWGUI.lineEdit(self.controlArea, self, 'name', box='Learner/Classifier Name', \
44                 tooltip='Name to be used by other widgets to identify your learner/classifier.')
45
46        OWGUI.separator(self.controlArea)
47
48        wbN = OWGUI.widgetBox(self.controlArea, "Neighbours")
49        OWGUI.spin(wbN, self, "k", 1, 100, 1, None, "Number of neighbours   ", orientation="horizontal")
50        OWGUI.checkBox(wbN, self, "ranks", "Weighting by ranks, not distances")
51
52        OWGUI.separator(self.controlArea)
53
54        wbM = OWGUI.widgetBox(self.controlArea, "Metrics")
55        OWGUI.comboBox(wbM, self, "metrics", items = [x[0] for x in self.metricsList], valueType = int, callback = self.metricsChanged)
56        self.cbNormalize = OWGUI.checkBox(wbM, self, "normalize", "Normalize continuous attributes")
57        OWGUI.checkBox(wbM, self, "ignoreUnknowns", "Ignore unknown values")
58        self.metricsChanged()
59
60        OWGUI.separator(self.controlArea)
61
62        OWGUI.button(self.controlArea, self, "&Apply", callback=self.setLearner, disabled=0, default=True)
63       
64        OWGUI.rubber(self.controlArea)
65
66        self.resize(100,250)
67
68    def sendReport(self):
69        self.reportSettings("Learning parameters",
70                            [("Metrics", self.metricsList[self.metrics][0]),
71                             not self.metrics and ("Continuous attributes", ["Raw", "Normalized"][self.normalize]),
72                             ("Unknown values ignored", OWGUI.YesNo[self.ignoreUnknowns]),
73                             ("Number of neighbours", self.k),
74                             ("Weighting", ["By distances", "By ranked distances"][self.ranks])])
75        self.reportData(self.data)
76       
77    def metricsChanged(self):
78        if not self.metrics and not self.cbNormalize.isEnabled():
79            self.normalize = self.oldNormalize
80            self.cbNormalize.setEnabled(True)
81        elif self.metrics and self.cbNormalize.isEnabled():
82            self.oldNormalize = self.normalize
83            self.normalize = False
84            self.cbNormalize.setEnabled(False)
85           
86    def setData(self,data):
87        self.data = self.isDataWithClass(data, orange.VarTypes.Discrete, checkMissing=True) and data or None
88        self.setLearner()
89
90    def setPreprocessor(self, pp):
91        self.preprocessor = pp
92        self.setLearner()
93
94    def setLearner(self):
95        distconst = self.metricsList[self.metrics][1]()
96        distconst.ignoreUnknowns = self.ignoreUnknowns
97        distconst.normalize = self.normalize
98        self.learner = orange.kNNLearner(k = self.k, rankWeight = self.ranks, distanceConstructor = distconst)
99        if self.preprocessor:
100            self.learner = self.preprocessor.wrapLearner(self.learner)
101        self.learner.name = self.name
102
103        self.send("Learner", self.learner)
104
105        self.learn()
106
107
108    def learn(self):
109        self.classifier = None
110        if self.data and self.learner:
111            try:
112                self.classifier = self.learner(self.data)
113                self.classifier.name = self.name
114            except Exception, (errValue):
115                self.classifier = None
116                self.error(str(errValue))
117        self.send("kNN Classifier", self.classifier)
118
119##############################################################################
120# Test the widget, run from DOS prompt
121# > python OWDataTable.py)
122# Make sure that a sample data set (adult_sample.tab) is in the directory
123
124if __name__=="__main__":
125    a=QApplication(sys.argv)
126    ow=OWKNN()
127
128##    dataset = orange.ExampleTable('adult_sample')
129##    ow.setData(dataset)
130
131    ow.show()
132    a.exec_()
133    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.