source: orange/Orange/OrangeWidgets/Evaluate/OWTestLearners.py @ 11562:ec47c1ae6cc6

Revision 11562:ec47c1ae6cc6, 28.2 KB checked in by Ales Erjavec <ales.erjavec@…>, 11 months ago (diff)

Improved exception checking for learner pre-test.

Line 
1"""
2<name>Test Learners</name>
3<description>Estimates the predictive performance of learners on a data set.</description>
4<icon>icons/TestLearners1.svg</icon>
5<contact>Blaz Zupan (blaz.zupan(@at@)fri.uni-lj.si)</contact>
6<priority>200</priority>
7"""
8#
9# OWTestLearners.py
10#
11from OWWidget import *
12import orngTest, orngStat, OWGUI
13import time
14import warnings
15from orngWrap import PreprocessedLearner
16
17import Orange
18
19##############################################################################
20
21class Learner:
22    def __init__(self, learner, id):
23        self.learner = learner
24        self.name = learner.name
25        self.id = id
26        self.scores = []
27        self.results = None
28        self.time = time.time() # used to order the learners in the table
29
30class Score:
31    def __init__(self, name, label, f, show=True, cmBased=False):
32        self.name = name
33        self.label = label
34        self.f = f
35        self.show = show
36        self.cmBased = cmBased
37       
38def dispatch(score_desc, res, cm):
39    """ Dispatch the call to orngStat method.
40    """
41    return eval("orngStat." + score_desc.f)
42
43
44class OWTestLearners(OWWidget):
45    settingsList = ["nFolds", "pLearning", "pRepeat", "precision",
46                    "selectedCScores", "selectedRScores", "applyOnAnyChange",
47                    "resampling"]
48    contextHandlers = {"": DomainContextHandler("", ["targetClass"])}
49    callbackDeposit = []
50
51    # Classification
52    cStatistics = [Score(*s) for s in [\
53        ('Classification accuracy', 'CA', 'CA(res)', True),
54        ('Sensitivity', 'Sens', 'sens(cm)', True, True),
55        ('Specificity', 'Spec', 'spec(cm)', True, True),
56        ('Area under ROC curve', 'AUC', 'AUC(res)', True),
57        ('Information score', 'IS', 'IS(res)', False),
58        ('F-measure', 'F1', 'F1(cm)', False, True),
59        ('Precision', 'Prec', 'precision(cm)', False, True),
60        ('Recall', 'Recall', 'recall(cm)', False, True),
61        ('Brier score', 'Brier', 'BrierScore(res)', True),
62        ('Matthews correlation coefficient', 'MCC', 'MCC(cm)', False, True)]]
63
64    # Regression
65    rStatistics = [Score(*s) for s in [\
66        ("Mean squared error", "MSE", "MSE(res)", False),
67        ("Root mean squared error", "RMSE", "RMSE(res)"),
68        ("Mean absolute error", "MAE", "MAE(res)", False),
69        ("Relative squared error", "RSE", "RSE(res)", False),
70        ("Root relative squared error", "RRSE", "RRSE(res)"),
71        ("Relative absolute error", "RAE", "RAE(res)", False),
72        ("R-squared", "R2", "R2(res)")]]
73   
74    # Multi-Label
75    mStatistics = [Score(*s) for s in [\
76        ('Hamming Loss', 'HammingLoss', 'mlc_hamming_loss(res)', False),
77        ('Accuracy', 'Accuracy', 'mlc_accuracy(res)', False),
78        ('Precision', 'Precision', 'mlc_precision(res)', False),
79        ('Recall', 'Recall', 'mlc_recall(res)', False),                               
80        ]]
81   
82    resamplingMethods = ["Cross-validation", "Leave-one-out", "Random sampling",
83                         "Test on train data", "Test on test data"]
84
85    def __init__(self,parent=None, signalManager = None):
86        OWWidget.__init__(self, parent, signalManager, "Test Learners")
87
88        self.inputs = [("Data", ExampleTable, self.setData, Default),
89                       ("Separate Test Data", ExampleTable, self.setTestData),
90                       ("Learner", orange.Learner, self.setLearner, Multiple + Default),
91                       ("Preprocess", PreprocessedLearner, self.setPreprocessor)]
92
93        self.outputs = [("Evaluation Results", orngTest.ExperimentResults)]
94
95        # Settings
96        self.resampling = 0             # cross-validation
97        self.nFolds = 5                 # cross validation folds
98        self.pLearning = 70   # size of learning set when sampling [%]
99        self.pRepeat = 10
100        self.precision = 4
101        self.applyOnAnyChange = True
102        self.selectedCScores = [i for (i,s) in enumerate(self.cStatistics) if s.show]
103        self.selectedRScores = [i for (i,s) in enumerate(self.rStatistics) if s.show]
104        self.selectedMScores = [i for (i,s) in enumerate(self.mStatistics) if s.show]
105        self.targetClass = 0
106        self.loadSettings()
107
108        self.stat = self.cStatistics
109
110        self.data = None                # input data set
111        self.testdata = None            # separate test data set
112        self.learners = {}              # set of learners (input)
113        self.results = None             # from orngTest
114        self.preprocessor = None
115
116        self.controlArea.layout().setSpacing(8)
117        # GUI
118        self.sBtns = OWGUI.radioButtonsInBox(self.controlArea, self, "resampling", 
119                                             box="Sampling",
120                                             btnLabels=self.resamplingMethods[:1],
121                                             callback=self.newsampling)
122        indent = OWGUI.checkButtonOffsetHint(self.sBtns.buttons[-1])
123       
124        ibox = OWGUI.widgetBox(OWGUI.indentedBox(self.sBtns, sep=indent))
125        OWGUI.spin(ibox, self, 'nFolds', 2, 100, step=1,
126                   label='Number of folds:',
127                   callback=lambda p=0: self.conditionalRecompute(p),
128                   keyboardTracking=False)
129       
130        OWGUI.separator(self.sBtns, height = 3)
131       
132        OWGUI.appendRadioButton(self.sBtns, self, "resampling", self.resamplingMethods[1])      # leave one out
133        OWGUI.separator(self.sBtns, height = 3)
134        OWGUI.appendRadioButton(self.sBtns, self, "resampling", self.resamplingMethods[2])      # random sampling
135                       
136        ibox = OWGUI.widgetBox(OWGUI.indentedBox(self.sBtns, sep=indent))
137        OWGUI.spin(ibox, self, 'pRepeat', 1, 100, step=1,
138                   label='Repeat train/test:',
139                   callback=lambda p=2: self.conditionalRecompute(p),
140                   keyboardTracking=False)
141       
142        OWGUI.widgetLabel(ibox, "Relative training set size:")
143       
144        OWGUI.hSlider(ibox, self, 'pLearning', minValue=10, maxValue=100,
145                      step=1, ticks=10, labelFormat="   %d%%",
146                      callback=lambda p=2: self.conditionalRecompute(p))
147       
148        OWGUI.separator(self.sBtns, height = 3)
149        OWGUI.appendRadioButton(self.sBtns, self, "resampling", self.resamplingMethods[3])  # test on train
150        OWGUI.separator(self.sBtns, height = 3)
151        OWGUI.appendRadioButton(self.sBtns, self, "resampling", self.resamplingMethods[4])  # test on test
152
153        self.trainDataBtn = self.sBtns.buttons[-2]
154        self.testDataBtn = self.sBtns.buttons[-1]
155        self.testDataBtn.setDisabled(True)
156       
157        OWGUI.separator(self.sBtns)
158        OWGUI.checkBox(self.sBtns, self, 'applyOnAnyChange',
159                       label="Apply on any change", callback=self.applyChange)
160        self.applyBtn = OWGUI.button(self.sBtns, self, "&Apply",
161                                     callback=lambda f=True: self.recompute(f))
162        self.applyBtn.setDisabled(True)
163
164        if self.resampling == 4:
165            self.resampling = 3
166
167        # statistics
168        self.statLayout = QStackedLayout()
169        self.cbox = OWGUI.widgetBox(self.controlArea, addToLayout=False)
170        self.cStatLabels = [s.name for s in self.cStatistics]
171        self.cstatLB = OWGUI.listBox(self.cbox, self, 'selectedCScores',
172                                     'cStatLabels', box = "Performance scores",
173                                     selectionMode = QListWidget.MultiSelection,
174                                     callback=self.newscoreselection)
175       
176        self.cbox.layout().addSpacing(8)
177        self.targetCombo = OWGUI.comboBox(self.cbox, self, "targetClass", orientation=0,
178                                        callback=[self.changedTarget],
179                                        box="Target class")
180
181        self.rStatLabels = [s.name for s in self.rStatistics]
182        self.rbox = OWGUI.widgetBox(self.controlArea, "Performance scores", addToLayout=False)
183        self.rstatLB = OWGUI.listBox(self.rbox, self, 'selectedRScores', 'rStatLabels',
184                                     selectionMode = QListWidget.MultiSelection,
185                                     callback=self.newscoreselection)
186
187        self.mStatLabels = [s.name for s in self.mStatistics]
188        self.mbox = OWGUI.widgetBox(self.controlArea, "Performance scores", addToLayout=False)
189        self.mstatLB = OWGUI.listBox(self.mbox, self, 'selectedMScores', 'mStatLabels',
190                                     selectionMode = QListWidget.MultiSelection,
191                                     callback=self.newscoreselection)
192       
193        self.statLayout.addWidget(self.cbox)
194        self.statLayout.addWidget(self.rbox)
195        self.statLayout.addWidget(self.mbox)
196        self.controlArea.layout().addLayout(self.statLayout)
197       
198        self.statLayout.setCurrentWidget(self.cbox)
199
200        # score table
201        # table with results
202        self.g = OWGUI.widgetBox(self.mainArea, 'Evaluation Results')
203        self.tab = OWGUI.table(self.g, selectionMode = QTableWidget.NoSelection)
204
205        self.resize(680,470)
206
207    # scoring and painting of score table
208    def isclassification(self):
209        if not self.data or not self.data.domain.classVar:
210            return True
211        return self.data.domain.classVar.varType == orange.VarTypes.Discrete
212
213    def ismultilabel(self, data = 42):
214        if data==42:
215            data = self.data
216        if not data:
217            return False
218        return Orange.multilabel.is_multilabel(data)
219
220    def get_usestat(self):
221        return ([self.selectedRScores, self.selectedCScores, self.selectedMScores]
222                [2 if self.ismultilabel() else self.isclassification()])
223
224    def paintscores(self):
225        """paints the table with evaluation scores"""
226
227        self.tab.setColumnCount(len(self.stat)+1)
228        self.tab.setHorizontalHeaderLabels(["Method"] + [s.label for s in self.stat])
229       
230        prec="%%.%df" % self.precision
231
232        learners = [(l.time, l) for l in self.learners.values()]
233        learners.sort()
234        learners = [lt[1] for lt in learners]
235
236        self.tab.setRowCount(len(self.learners))
237        for (i, l) in enumerate(learners):
238            OWGUI.tableItem(self.tab, i,0, l.name)
239           
240        for (i, l) in enumerate(learners):
241            if l.scores:
242                for j in range(len(self.stat)):
243                    if l.scores[j] is not None:
244                        OWGUI.tableItem(self.tab, i, j+1, prec % l.scores[j])
245                    else:
246                        OWGUI.tableItem(self.tab, i, j+1, "N/A")
247            else:
248                for j in range(len(self.stat)):
249                    OWGUI.tableItem(self.tab, i, j+1, "")
250       
251        # adjust the width of the score table cloumns
252        self.tab.resizeColumnsToContents()
253        self.tab.resizeRowsToContents()
254        usestat = self.get_usestat()
255        for i in range(len(self.stat)):
256            if i not in usestat:
257                self.tab.hideColumn(i + 1)
258            else:
259                self.tab.showColumn(i + 1)
260
261    def sendReport(self):
262        method = [("Method", self.resamplingMethods[self.resampling])]
263
264        exset = []
265
266        if self.resampling == 0:
267            exset = [("Folds", self.nFolds)]
268        elif self.resampling == 2:
269            exset = [("Repetitions", self.pRepeat),
270                     ("Proportion of training instances", "%i%%" \
271                      % self.pLearning)]
272        else:
273            exset = []
274
275        if self.data and \
276                isinstance(self.data.domain.classVar, orange.EnumVariable):
277            target = [("Target class",
278                       self.data.domain.classVar.values[self.targetClass])]
279        else:
280            target = []
281
282        if not self.ismultilabel():
283            self.reportSettings("Validation method", method + exset + target)
284        else:
285            self.reportSettings("Validation method", method + exset)
286
287        self.reportData(self.data)
288
289        if self.data:
290            self.reportSection("Results")
291            learners = [(l.time, l) for l in self.learners.values()]
292            learners.sort()
293            learners = [lt[1] for lt in learners]
294            usestat = self.get_usestat()
295            # table header
296            res = "<table><tr><th></th>" + \
297                  "".join("<th><b>%s</b></th>" % s.label \
298                          for i, s in enumerate(self.stat) \
299                          if i in usestat) + \
300                  "</tr>"
301
302            for i, learner in enumerate(learners):
303                res += "<tr><th><b>%s</b></th>" % learner.name
304                if learner.scores:
305                    for j in usestat:
306                        score = learner.scores[j]
307                        score = "%.4f" % score if score is not None else ""
308                        res += "<td>" + score + "</td>"
309                res += "</tr>"
310            res += "</table>"
311            self.reportRaw(res)
312
313    def score(self, ids):
314        """compute scores for the list of learners"""
315        if (not self.data):
316            for id in ids:
317                self.learners[id].results = None
318                self.learners[id].scores = []
319            return
320        # test which learners can accept the given data set
321        # e.g., regressions can't deal with classification data
322        learners = []
323        used_ids = []
324        n = len(self.data.domain.attributes)*2
325        indices = orange.MakeRandomIndices2(p0=min(n, len(self.data)), stratified=orange.MakeRandomIndices2.StratifiedIfPossible)
326        new = self.data.selectref(indices(self.data), 0)
327
328        multilabel = self.ismultilabel()
329       
330        self.warning(0)
331        learner_exceptions = []
332        for l in [self.learners[id] for id in ids]:
333            learner = l.learner
334            if self.preprocessor:
335                learner = self.preprocessor.wrapLearner(learner)
336            try:
337                predictor = learner(new)
338            except Exception, ex:
339                learner_exceptions.append((l, ex))
340                l.scores = []
341                l.results = None
342            else:
343                if (multilabel and isinstance(learner, Orange.multilabel.MultiLabelLearner)) or predictor(new[0]).varType == new.domain.classVar.varType:
344                    learners.append(learner)
345                    used_ids.append(l.id)
346                else:
347                    l.scores = []
348                    l.results = None
349
350        if learner_exceptions:
351            text = "\n".join("Learner %s ends with exception: %s" % (l.name, str(ex)) \
352                             for l, ex in learner_exceptions)
353            self.warning(0, text)
354           
355        if not learners:
356            return
357
358        # computation of results (res, and cm if classification)
359        pb = None
360        if self.resampling==0:
361            pb = OWGUI.ProgressBar(self, iterations=self.nFolds)
362            res = orngTest.crossValidation(learners, self.data, folds=self.nFolds,
363                                           strat=orange.MakeRandomIndices.StratifiedIfPossible,
364                                           callback=pb.advance, storeExamples = True)
365            pb.finish()
366        elif self.resampling==1:
367            pb = OWGUI.ProgressBar(self, iterations=len(self.data))
368            res = orngTest.leaveOneOut(learners, self.data,
369                                       callback=pb.advance, storeExamples = True)
370            pb.finish()
371        elif self.resampling==2:
372            pb = OWGUI.ProgressBar(self, iterations=self.pRepeat)
373            res = orngTest.proportionTest(learners, self.data, self.pLearning/100.,
374                                          times=self.pRepeat, callback=pb.advance, storeExamples = True)
375            pb.finish()
376        elif self.resampling==3:
377            pb = OWGUI.ProgressBar(self, iterations=len(learners))
378            res = orngTest.learnAndTestOnLearnData(learners, self.data, storeExamples = True, callback=pb.advance)
379            pb.finish()
380           
381        elif self.resampling==4:
382            if not self.testdata:
383                for l in self.learners.values():
384                    l.scores = []
385                return
386            pb = OWGUI.ProgressBar(self, iterations=len(learners))
387            res = orngTest.learnAndTestOnTestData(learners, self.data, self.testdata, storeExamples = True, callback=pb.advance)
388            pb.finish()
389           
390        if not self.ismultilabel() and self.isclassification():
391            cm = orngStat.computeConfusionMatrices(res, classIndex = self.targetClass)
392        else:
393            cm = None
394
395        if self.preprocessor: # Unwrap learners
396            learners = [l.wrappedLearner for l in learners]
397           
398        res.learners = learners
399       
400        for l in [self.learners[id] for id in ids]:
401            if l.learner in learners:
402                l.results = res
403            else:
404                l.results = None
405
406        self.error(range(len(self.stat)))
407        scores = []
408       
409        for i, s in enumerate(self.stat):
410            if s.cmBased:
411                try:
412                    scores.append(dispatch(s, res, cm))
413                except Exception, ex:
414                    self.error(i, "An error occurred while evaluating orngStat." + s.f + "on %s due to %s" % \
415                               (" ".join([l.name for l in learners]), ex.message))
416                    scores.append([None] * len(self.learners))
417            else:
418                scores_one = []
419                for res_one in orngStat.split_by_classifiers(res):
420                    try:
421                        scores_one.extend(dispatch(s, res_one, cm))
422                    except Exception, ex:
423                        self.error(i, "An error occurred while evaluating orngStat." + s.f + "on %s due to %s" % \
424                                   (res.classifierNames[0], ex.message))
425                        scores_one.append(None)
426                scores.append(scores_one)
427
428        for i, (id, l) in enumerate(zip(used_ids, learners)):
429            self.learners[id].scores = [s[i] if s else None for s in scores]
430           
431        self.sendResults()
432
433    def recomputeCM(self):
434        if not self.results:
435            return
436        cm = orngStat.computeConfusionMatrices(self.results, classIndex = self.targetClass)
437        scores = [(indx, eval("orngStat." + s.f))
438                  for (indx, s) in enumerate(self.stat) if s.cmBased]
439        for (indx, score) in scores:
440            for (i, l) in enumerate([l for l in self.learners.values() if l.scores]):
441                learner_indx = self.results.learners.index(l.learner)
442                l.scores[indx] = score[learner_indx]
443
444        self.paintscores()
445       
446    def clearScores(self, ids=None):
447        """
448        Clear/invalidate evaluation results/scores for learners for an
449        `ids` sequence (keys into self.learners). If `ids` is None then
450        invalidate data for all learners.
451
452        """
453        if ids is None:
454            ids = self.learners.keys()
455
456        for id in ids:
457            self.learners[id].scores = []
458            self.learners[id].results = None
459
460    # handle input signals
461    def setData(self, data):
462        """
463        Set the input train data set.
464        """
465        self.closeContext()
466
467        self.clearScores()
468
469        multilabel = self.ismultilabel(data)
470        if not multilabel:
471            if self.isDataWithClass(data, checkMissing=True):
472                self.data = orange.Filter_hasClassValue(data)
473            else:
474                self.data = None
475        else:
476            self.data = data
477
478        self.fillClassCombo()
479
480        if self.data is not None:
481            # Ensure the correct statistics selection is visible.
482            if self.ismultilabel():
483                statwidget = self.mbox
484                stat = self.mStatistics
485            elif self.isclassification():
486                statwidget = self.cbox
487                stat = self.cStatistics
488            else:
489                statwidget = self.rbox
490                stat = self.rStatistics
491
492            self.statLayout.setCurrentWidget(statwidget)
493
494            self.stat = stat
495
496    def setTestData(self, data):
497        """
498        Set the 'Separate Test Data' input.
499        """
500        if data is None:
501            self.testdata = None
502        else:
503            self.testdata = orange.Filter_hasClassValue(data)
504        self.testDataBtn.setEnabled(self.testdata is not None)
505        if self.testdata is not None:
506            if self.resampling == 4:
507                self.clearScores()
508
509        elif self.resampling == 4 and self.data:
510            # test data removed, switch to testing on train data
511            self.resampling = 3
512            self.clearScores()
513
514    def fillClassCombo(self):
515        """upon arrival of new data appropriately set the target class combo"""
516        self.targetCombo.clear()
517        if not self.data or not self.data.domain.classVar or not self.isclassification():
518            return
519
520        domain = self.data.domain
521        self.targetCombo.addItems([str(v) for v in domain.classVar.values])
522       
523        if self.targetClass<len(domain.classVar.values):
524            self.targetCombo.setCurrentIndex(self.targetClass)
525        else:
526            self.targetCombo.setCurrentIndex(0)
527            self.targetClass=0
528
529    def setLearner(self, learner, id=None):
530        """
531        Set the input learner with `id`.
532        """
533        if learner is not None:
534            # a new or updated learner
535            if id in self.learners:
536                time = self.learners[id].time
537                self.learners[id] = Learner(learner, id)
538                self.learners[id].time = time
539                self.learners[id] = self.learners[id]
540                self.clearScores([id])
541            else:
542                self.learners[id] = Learner(learner, id)
543        else:
544            # remove a learner and corresponding results
545            if id in self.learners:
546                res = self.learners[id].results
547                if res and res.numberOfLearners > 1:
548                    # Remove the learner from the shared results instance
549                    old_learner = self.learners[id].learner
550                    indx = res.learners.index(old_learner)
551                    res.remove(indx)
552                    del res.learners[indx]
553                del self.learners[id]
554
555    def setPreprocessor(self, pp):
556        self.preprocessor = pp
557        self.clearScores()
558
559    def handleNewSignals(self):
560        """
561        Update the evaluations/scores after new inputs were received.
562        """
563        def needsupdate(learner_id):
564            return not (self.learners[learner_id].scores or
565                        self.learners[learner_id].results)
566
567        if self.applyOnAnyChange:
568            self.score(filter(needsupdate, self.learners))
569            self.applyBtn.setEnabled(False)
570        else:
571            self.applyBtn.setEnabled(True)
572
573        self.paintscores()
574
575        if self.data is not None:
576            self.openContext("", self.data)
577        else:
578            self.send("Evaluation Results", None)
579
580    # handle output signals
581
582    def sendResults(self):
583        """commit evaluation results"""
584        # for each learner, we first find a list where a result is stored
585        # and remember the corresponding index
586
587        valid = [(l.results, l.results.learners.index(l.learner))
588                 for l in self.learners.values() if l.scores and l.results]
589           
590        if not (self.data and len(valid)):
591            self.send("Evaluation Results", None)
592            return
593
594        # find the result set for a largest number of learners
595        # and remove this set from the list of result sets
596        rlist = dict([(l.results,1) for l in self.learners.values() if l.scores and l.results]).keys()
597        rlen = [r.numberOfLearners for r in rlist]
598        results = rlist.pop(rlen.index(max(rlen)))
599       
600        for (i, l) in enumerate(results.learners):
601            if not l in [l.learner for l in self.learners.values()]:
602                results.remove(i)
603                del results.learners[i]
604
605        for r in rlist:
606            for (i, l) in enumerate(r.learners):
607                learner_id = [l1.id for l1 in self.learners.values() if l1.learner is l][0]
608                if (r, i) in valid:
609                    results.add(r, i)
610                    results.learners.append(r.learners[i])
611                    self.learners[learner_id].results = results
612        self.send("Evaluation Results", results)
613        self.results = results
614
615    # signal processing
616
617    def newsampling(self):
618        """handle change of evaluation method"""
619        if not self.applyOnAnyChange:
620            self.applyBtn.setDisabled(self.applyOnAnyChange)
621        else:
622            self.clearScores()
623            if self.learners:
624                self.recompute()
625
626    def newscoreselection(self):
627        """handle change in set of scores to be displayed"""
628        usestat = self.get_usestat()
629        for i in range(len(self.stat)):
630            if i in usestat:
631                self.tab.showColumn(i+1)
632                self.tab.resizeColumnToContents(i+1)
633            else:
634                self.tab.hideColumn(i+1)
635
636    def recompute(self, forced=False):
637        """recompute the scores for all learners,
638           if not forced, will do nothing but enable the Apply button"""
639        if self.applyOnAnyChange or forced:
640            self.score([l.id for l in self.learners.values()])
641            self.paintscores()
642            self.applyBtn.setDisabled(True)
643        else:
644            self.applyBtn.setEnabled(True)
645
646    def conditionalRecompute(self, option):
647        """calls recompute only if specific sampling option enabled"""
648        if self.resampling == option:
649            self.recompute(False)
650
651    def applyChange(self):
652        """
653        A change of 'Apply on any change' check box.
654        """
655        def needsupdate(learner_id):
656            return not (self.learners[learner_id].scores or
657                        self.learners[learner_id].results)
658
659        if self.applyOnAnyChange:
660            self.applyBtn.setDisabled(True)
661            pending = filter(needsupdate, self.learners)
662            if pending:
663                self.score(pending)
664                self.paintscores()
665
666    def changedTarget(self):
667        self.recomputeCM()
668
669##############################################################################
670# Test the widget, run from DOS prompt
671
672if __name__=="__main__":
673    a=QApplication(sys.argv)
674    ow=OWTestLearners()
675    ow.show()
676    a.exec_()
677
678    data1 = orange.ExampleTable(r'../../doc/datasets/voting')
679    data2 = orange.ExampleTable(r'../../golf')
680    datar = orange.ExampleTable(r'../../auto-mpg')
681    data3 = orange.ExampleTable(r'../../sailing-big')
682    data4 = orange.ExampleTable(r'../../sailing-test')
683    data5 = orange.ExampleTable('emotions')
684
685    l1 = orange.MajorityLearner(); l1.name = '1 - Majority'
686
687    l2 = orange.BayesLearner()
688    l2.estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10)
689    l2.conditionalEstimatorConstructor = \
690        orange.ConditionalProbabilityEstimatorConstructor_ByRows(
691        estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10))
692    l2.name = '2 - NBC (m=10)'
693
694    l3 = orange.BayesLearner(); l3.name = '3 - NBC (default)'
695
696    l4 = orange.MajorityLearner(); l4.name = "4 - Majority"
697
698    import orngRegression as r
699    r5 = r.LinearRegressionLearner(name="0 - lin reg")
700
701    l5 = Orange.multilabel.BinaryRelevanceLearner()
702
703    testcase = 4
704
705    if testcase == 0: # 1(UPD), 3, 4
706        ow.setData(data2)
707        ow.setLearner(r5, 5)
708        ow.setLearner(l1, 1)
709        ow.setLearner(l2, 2)
710        ow.setLearner(l3, 3)
711        l1.name = l1.name + " UPD"
712        ow.setLearner(l1, 1)
713        ow.setLearner(None, 2)
714        ow.setLearner(l4, 4)
715#        ow.setData(data1)
716#        ow.setData(datar)
717#        ow.setData(data1)
718    if testcase == 1: # data, but all learners removed
719        ow.setLearner(l1, 1)
720        ow.setLearner(l2, 2)
721        ow.setLearner(l1, 1)
722        ow.setLearner(None, 2)
723        ow.setData(data2)
724        ow.setLearner(None, 1)
725    if testcase == 2: # sends data, then learner, then removes the learner
726        ow.setData(data2)
727        ow.setLearner(l1, 1)
728        ow.setLearner(None, 1)
729    if testcase == 3: # regression first
730        ow.setData(datar)
731        ow.setLearner(r5, 5)
732    if testcase == 4: # separate train and test data
733        ow.setData(data3)
734        ow.setTestData(data4)
735        ow.setLearner(l2, 5)
736        ow.setTestData(None)
737    if testcase == 5: # MLC
738        ow.setData(data5)
739        ow.setLearner(l5, 6)
740
741    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.