Skip to content

Commit 5c52251

Browse files
authored
Merge pull request #4571 from PrimozGodec/test-and-score-doc
Test and Score: Update documentation
2 parents 94c0178 + eecbdd1 commit 5c52251

File tree

12 files changed

+70
-59
lines changed

12 files changed

+70
-59
lines changed
Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def raise_(exc):
114114

115115
class State(enum.Enum):
116116
"""
117-
OWTestLearner's runtime state.
117+
OWTestAndScore's runtime state.
118118
"""
119119
#: No or insufficient input (i.e. no data or no learners)
120120
Waiting = "Waiting"
@@ -126,12 +126,13 @@ class State(enum.Enum):
126126
Cancelled = "Cancelled"
127127

128128

129-
class OWTestLearners(OWWidget):
129+
class OWTestAndScore(OWWidget):
130130
name = "Test and Score"
131131
description = "Cross-validation accuracy estimation."
132132
icon = "icons/TestLearners1.svg"
133133
priority = 100
134134
keywords = ['Cross Validation', 'CV']
135+
replaces = ["Orange.widgets.evaluate.owtestlearners.OWTestLearners"]
135136

136137
class Inputs:
137138
train_data = Input("Data", Table, default=True)
@@ -345,10 +346,10 @@ def _update_controls(self):
345346
self.fold_feature = self.feature_model[0]
346347
enabled = bool(self.feature_model)
347348
self.controls.resampling.buttons[
348-
OWTestLearners.FeatureFold].setEnabled(enabled)
349+
OWTestAndScore.FeatureFold].setEnabled(enabled)
349350
self.features_combo.setEnabled(enabled)
350-
if self.resampling == OWTestLearners.FeatureFold and not enabled:
351-
self.resampling = OWTestLearners.KFold
351+
if self.resampling == OWTestAndScore.FeatureFold and not enabled:
352+
self.resampling = OWTestAndScore.KFold
352353

353354
@Inputs.learner
354355
def set_learner(self, learner, key):
@@ -428,7 +429,7 @@ def set_train_data(self, data):
428429
self._update_class_selection()
429430
self.openContext(data.domain)
430431
if self.fold_feature_selected and bool(self.feature_model):
431-
self.resampling = OWTestLearners.FeatureFold
432+
self.resampling = OWTestAndScore.FeatureFold
432433
self._invalidate()
433434

434435
@Inputs.test_data
@@ -471,7 +472,7 @@ def set_test_data(self, data):
471472
self.Warning.missing_data.clear()
472473

473474
self.test_data = data
474-
if self.resampling == OWTestLearners.TestOnTest:
475+
if self.resampling == OWTestAndScore.TestOnTest:
475476
self._invalidate()
476477

477478
def _which_missing_data(self):
@@ -533,26 +534,26 @@ def handleNewSignals(self):
533534
self.__update()
534535

535536
def kfold_changed(self):
536-
self.resampling = OWTestLearners.KFold
537+
self.resampling = OWTestAndScore.KFold
537538
self._param_changed()
538539

539540
def fold_feature_changed(self):
540-
self.resampling = OWTestLearners.FeatureFold
541+
self.resampling = OWTestAndScore.FeatureFold
541542
self._param_changed()
542543

543544
def shuffle_split_changed(self):
544-
self.resampling = OWTestLearners.ShuffleSplit
545+
self.resampling = OWTestAndScore.ShuffleSplit
545546
self._param_changed()
546547

547548
def _param_changed(self):
548-
self.modcompbox.setEnabled(self.resampling == OWTestLearners.KFold)
549+
self.modcompbox.setEnabled(self.resampling == OWTestAndScore.KFold)
549550
self._update_view_enabled()
550551
self._invalidate()
551552
self.__update()
552553

553554
def _update_view_enabled(self):
554555
self.comparison_table.setEnabled(
555-
self.resampling == OWTestLearners.KFold
556+
self.resampling == OWTestAndScore.KFold
556557
and len(self.learners) > 1
557558
and self.data is not None)
558559
self.score_table.view.setEnabled(
@@ -661,7 +662,7 @@ def update_comparison_table(self):
661662
return
662663
names = [learner_name(slot.learner) for slot in slots]
663664
self._set_comparison_headers(names)
664-
if self.resampling == OWTestLearners.KFold:
665+
if self.resampling == OWTestAndScore.KFold:
665666
scores = self._scores_by_folds(slots)
666667
self._fill_table(names, scores)
667668

@@ -790,7 +791,7 @@ def _on_target_class_changed(self):
790791
def _invalidate(self, which=None):
791792
self.cancel()
792793
self.fold_feature_selected = \
793-
self.resampling == OWTestLearners.FeatureFold
794+
self.resampling == OWTestAndScore.FeatureFold
794795
# Invalidate learner results for `which` input keys
795796
# (if None then all learner results are invalidated)
796797
if which is None:
@@ -912,14 +913,14 @@ def __update(self):
912913
self.__state = State.Waiting
913914
self.commit()
914915
return
915-
if self.resampling == OWTestLearners.KFold and \
916+
if self.resampling == OWTestAndScore.KFold and \
916917
len(self.data) < self.NFolds[self.n_folds]:
917918
self.Error.too_many_folds()
918919
self.__state = State.Waiting
919920
self.commit()
920921
return
921922

922-
elif self.resampling == OWTestLearners.TestOnTest:
923+
elif self.resampling == OWTestAndScore.TestOnTest:
923924
if self.test_data is None:
924925
if not self.Error.test_data_empty.is_shown():
925926
self.Warning.test_data_missing()
@@ -947,30 +948,30 @@ def __update(self):
947948
# learners bellow)
948949
learners_c = [copy.deepcopy(learner) for learner in learners]
949950

950-
if self.resampling == OWTestLearners.TestOnTest:
951+
if self.resampling == OWTestAndScore.TestOnTest:
951952
test_f = partial(
952953
Orange.evaluation.TestOnTestData(
953954
store_data=True, store_models=True),
954955
self.data, self.test_data, learners_c, self.preprocessor
955956
)
956957
else:
957-
if self.resampling == OWTestLearners.KFold:
958+
if self.resampling == OWTestAndScore.KFold:
958959
sampler = Orange.evaluation.CrossValidation(
959960
k=self.NFolds[self.n_folds],
960961
random_state=rstate)
961-
elif self.resampling == OWTestLearners.FeatureFold:
962+
elif self.resampling == OWTestAndScore.FeatureFold:
962963
sampler = Orange.evaluation.CrossValidationFeature(
963964
feature=self.fold_feature)
964-
elif self.resampling == OWTestLearners.LeaveOneOut:
965+
elif self.resampling == OWTestAndScore.LeaveOneOut:
965966
sampler = Orange.evaluation.LeaveOneOut()
966-
elif self.resampling == OWTestLearners.ShuffleSplit:
967+
elif self.resampling == OWTestAndScore.ShuffleSplit:
967968
sampler = Orange.evaluation.ShuffleSplit(
968969
n_resamples=self.NRepeats[self.n_repeats],
969970
train_size=self.SampleSizes[self.sample_size] / 100,
970971
test_size=None,
971972
stratified=self.shuffle_stratified,
972973
random_state=rstate)
973-
elif self.resampling == OWTestLearners.TestOnTrain:
974+
elif self.resampling == OWTestAndScore.TestOnTrain:
974975
sampler = Orange.evaluation.TestOnTrainingData(
975976
store_models=True)
976977
else:
@@ -1184,7 +1185,7 @@ def results_one_vs_rest(results, pos_index):
11841185
Orange.regression.KNNRegressionLearner(),
11851186
Orange.regression.RidgeRegressionLearner()]
11861187

1187-
WidgetPreview(OWTestLearners).run(
1188+
WidgetPreview(OWTestAndScore).run(
11881189
set_train_data=preview_data,
11891190
set_test_data=preview_data,
11901191
set_learner=[(learner, i) for i, learner in enumerate(prev_learners)]

Orange/widgets/evaluate/tests/test_owtestlearners.py renamed to Orange/widgets/evaluate/tests/test_owtestandscore.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
from Orange.base import Learner
1919
from Orange.modelling import ConstantLearner
2020
from Orange.regression import MeanLearner
21-
from Orange.widgets.evaluate.owtestlearners import (
22-
OWTestLearners, results_one_vs_rest)
21+
from Orange.widgets.evaluate.owtestandscore import (
22+
OWTestAndScore, results_one_vs_rest)
2323
from Orange.widgets.evaluate.utils import BUILTIN_SCORERS_ORDER
2424
from Orange.widgets.settings import (
2525
ClassValuesContextHandler, PerfectDomainContextHandler)
@@ -33,10 +33,10 @@ def fit(self, *_, **_2): # pylint: disable=arguments-differ
3333
return 1 / 0
3434

3535

36-
class TestOWTestLearners(WidgetTest):
36+
class TestOWTestAndScore(WidgetTest):
3737
def setUp(self):
3838
super().setUp()
39-
self.widget = self.create_widget(OWTestLearners) # type: OWTestLearners
39+
self.widget = self.create_widget(OWTestAndScore) # type: OWTestAndScore
4040

4141
self.scores_domain = Domain(
4242
[ContinuousVariable("a"), ContinuousVariable("b")],
@@ -82,7 +82,7 @@ def test_more_learners(self):
8282
def test_testOnTest(self):
8383
data = Table("iris")
8484
self.send_signal(self.widget.Inputs.train_data, data)
85-
self.widget.resampling = OWTestLearners.TestOnTest
85+
self.widget.resampling = OWTestAndScore.TestOnTest
8686
self.send_signal(self.widget.Inputs.test_data, data)
8787

8888
def test_testOnTest_incompatible_domain(self):
@@ -91,7 +91,7 @@ def test_testOnTest_incompatible_domain(self):
9191
self.send_signal(self.widget.Inputs.learner, LogisticRegressionLearner(), 0)
9292
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
9393
self.assertFalse(self.widget.Error.test_data_incompatible.is_shown())
94-
self.widget.resampling = OWTestLearners.TestOnTest
94+
self.widget.resampling = OWTestAndScore.TestOnTest
9595
# test data with the same class (otherwise the widget shows a different error)
9696
# and a non-nan X
9797
iris_test = iris.transform(Domain([ContinuousVariable("x")],
@@ -106,7 +106,7 @@ def test_CrossValidationByFeature(self):
106106
attrs = data.domain.attributes
107107
domain = Domain(attrs[:-1], attrs[-1], data.domain.class_vars)
108108
data_with_disc_metas = Table.from_table(domain, data)
109-
rb = self.widget.controls.resampling.buttons[OWTestLearners.FeatureFold]
109+
rb = self.widget.controls.resampling.buttons[OWTestAndScore.FeatureFold]
110110

111111
self.send_signal(self.widget.Inputs.learner, ConstantLearner(), 0)
112112
self.send_signal(self.widget.Inputs.train_data, data)
@@ -117,15 +117,15 @@ def test_CrossValidationByFeature(self):
117117
self.send_signal(self.widget.Inputs.train_data, data_with_disc_metas)
118118
self.assertTrue(rb.isEnabled())
119119
rb.click()
120-
self.assertEqual(self.widget.resampling, OWTestLearners.FeatureFold)
120+
self.assertEqual(self.widget.resampling, OWTestAndScore.FeatureFold)
121121
self.assertTrue(self.widget.features_combo.isEnabled())
122122
self.assertEqual(self.widget.features_combo.currentText(), "iris")
123123
self.assertEqual(len(self.widget.features_combo.model()), 1)
124124
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
125125

126126
self.send_signal(self.widget.Inputs.train_data, None)
127127
self.assertFalse(rb.isEnabled())
128-
self.assertEqual(self.widget.resampling, OWTestLearners.KFold)
128+
self.assertEqual(self.widget.resampling, OWTestAndScore.KFold)
129129
self.assertFalse(self.widget.features_combo.isEnabled())
130130

131131
def test_migrate_removes_invalid_contexts(self):
@@ -226,7 +226,7 @@ class NewRegressionScore(RegressionScore):
226226

227227
def test_target_changing(self):
228228
data = Table("iris")
229-
w = self.widget #: OWTestLearners
229+
w = self.widget #: OWTestAndScore
230230
model = w.score_table.model
231231

232232
w.n_folds = 2
@@ -305,7 +305,7 @@ def _retrieve_scores(self):
305305
return auc, ca, f1, precision, recall
306306

307307
def _test_scores(self, train_data, test_data, learner, sampling, n_folds):
308-
w = self.widget #: OWTestLearners
308+
w = self.widget #: OWTestAndScore
309309
w.controls.resampling.buttons[sampling].click()
310310
if n_folds is not None:
311311
w.n_folds = n_folds
@@ -323,7 +323,7 @@ def test_scores_constant_all_same(self):
323323
)
324324

325325
self.assertTupleEqual(self._test_scores(
326-
table, table, ConstantLearner(), OWTestLearners.TestOnTest, None),
326+
table, table, ConstantLearner(), OWTestAndScore.TestOnTest, None),
327327
(None, 1, 1, 1, 1))
328328

329329
def test_scores_log_reg_overfitted(self):
@@ -334,7 +334,7 @@ def test_scores_log_reg_overfitted(self):
334334

335335
self.assertTupleEqual(self._test_scores(
336336
table, table, LogisticRegressionLearner(),
337-
OWTestLearners.TestOnTest, None),
337+
OWTestAndScore.TestOnTest, None),
338338
(1, 1, 1, 1, 1))
339339

340340
def test_scores_log_reg_bad(self):
@@ -349,7 +349,7 @@ def test_scores_log_reg_bad(self):
349349

350350
self.assertTupleEqual(self._test_scores(
351351
table_train, table_test, LogisticRegressionLearner(),
352-
OWTestLearners.TestOnTest, None),
352+
OWTestAndScore.TestOnTest, None),
353353
(0, 0, 0, 0, 0))
354354

355355
def test_scores_log_reg_bad2(self):
@@ -361,7 +361,7 @@ def test_scores_log_reg_bad2(self):
361361
list(zip(*(self.scores_table_values + [list("yynn")]))))
362362
self.assertTupleEqual(self._test_scores(
363363
table_train, table_test, LogisticRegressionLearner(),
364-
OWTestLearners.TestOnTest, None),
364+
OWTestAndScore.TestOnTest, None),
365365
(0, 0, 0, 0, 0))
366366

367367
def test_scores_log_reg_advanced(self):
@@ -377,7 +377,7 @@ def test_scores_log_reg_advanced(self):
377377
np.testing.assert_almost_equal(
378378
self._test_scores(table_train, table_test,
379379
LogisticRegressionLearner(),
380-
OWTestLearners.TestOnTest, None),
380+
OWTestAndScore.TestOnTest, None),
381381
(2 / 3, 0.8, 0.8, 13 / 15, 0.8))
382382

383383
def test_scores_cross_validation(self):
@@ -388,7 +388,7 @@ def test_scores_cross_validation(self):
388388
all(x >= y for x, y in zip(
389389
self._test_scores(
390390
Table("iris")[::15], None, LogisticRegressionLearner(),
391-
OWTestLearners.KFold, 0),
391+
OWTestAndScore.KFold, 0),
392392
(0.8, 0.5, 0.5, 0.5, 0.5))))
393393

394394
def test_no_pregressbar_warning(self):
@@ -426,23 +426,23 @@ def test_comparison_requires_cv(self):
426426
self._set_three_majorities()
427427
baycomp.two_on_single.reset_mock()
428428

429-
rbs[OWTestLearners.KFold].click()
429+
rbs[OWTestAndScore.KFold].click()
430430
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
431431
self.assertIsNotNone(w.comparison_table.cellWidget(0, 1))
432432
self.assertTrue(w.modcompbox.isEnabled())
433433
self.assertTrue(w.comparison_table.isEnabled())
434434
baycomp.two_on_single.assert_called()
435435
baycomp.two_on_single.reset_mock()
436436

437-
rbs[OWTestLearners.LeaveOneOut].click()
437+
rbs[OWTestAndScore.LeaveOneOut].click()
438438
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
439439
self.assertIsNone(w.comparison_table.cellWidget(0, 1))
440440
self.assertFalse(w.modcompbox.isEnabled())
441441
self.assertFalse(w.comparison_table.isEnabled())
442442
baycomp.two_on_single.assert_not_called()
443443
baycomp.two_on_single.reset_mock()
444444

445-
rbs[OWTestLearners.KFold].click()
445+
rbs[OWTestAndScore.KFold].click()
446446
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
447447
self.assertIsNotNone(w.comparison_table.cellWidget(0, 1))
448448
self.assertTrue(w.modcompbox.isEnabled())
@@ -457,7 +457,7 @@ def test_comparison_requires_multiple_models(self):
457457

458458
self._set_three_majorities()
459459

460-
rbs[OWTestLearners.KFold].click()
460+
rbs[OWTestAndScore.KFold].click()
461461
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
462462
self.assertTrue(w.comparison_table.isEnabled())
463463

@@ -469,7 +469,7 @@ def test_comparison_requires_multiple_models(self):
469469
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
470470
self.assertFalse(w.comparison_table.isEnabled())
471471

472-
rbs[OWTestLearners.LeaveOneOut].click()
472+
rbs[OWTestAndScore.LeaveOneOut].click()
473473
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
474474
self.assertFalse(w.comparison_table.isEnabled())
475475

@@ -479,7 +479,7 @@ def test_comparison_requires_multiple_models(self):
479479
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
480480
self.assertFalse(w.comparison_table.isEnabled())
481481

482-
rbs[OWTestLearners.KFold].click()
482+
rbs[OWTestAndScore.KFold].click()
483483
self.get_output(self.widget.Outputs.evaluations_results, wait=5000)
484484
self.assertTrue(w.comparison_table.isEnabled())
485485

@@ -549,7 +549,7 @@ def test_comparison_binary_score(self):
549549
self.assertFalse("average" in kwargs)
550550

551551
simulate.combobox_activate_item(w.controls.class_selection,
552-
OWTestLearners.TARGET_AVERAGE)
552+
OWTestAndScore.TARGET_AVERAGE)
553553
_, kwargs = f1mock.call_args
554554
self.assertEqual(kwargs["average"], "weighted")
555555
self.assertFalse("target" in kwargs)

Orange/widgets/report/tests/test_report.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from Orange.widgets.evaluate.owcalibrationplot import OWCalibrationPlot
1818
from Orange.widgets.evaluate.owliftcurve import OWLiftCurve
1919
from Orange.widgets.evaluate.owrocanalysis import OWROCAnalysis
20-
from Orange.widgets.evaluate.owtestlearners import OWTestLearners
20+
from Orange.widgets.evaluate.owtestandscore import OWTestAndScore
2121
from Orange.widgets.unsupervised.owcorrespondence import OWCorrespondenceAnalysis
2222
from Orange.widgets.unsupervised.owdistancemap import OWDistanceMap
2323
from Orange.widgets.unsupervised.owdistances import OWDistances
@@ -66,7 +66,7 @@ class TestReportWidgets(WidgetTest):
6666
OWMDS, OWPCA]
6767
dist_widgets = [OWDistanceMap, OWHierarchicalClustering]
6868
visu_widgets = VISUALIZATION_WIDGETS
69-
spec_widgets = [OWTestLearners, OWTreeGraph]
69+
spec_widgets = [OWTestAndScore, OWTreeGraph]
7070

7171
def _create_report(self, widgets, rep, data):
7272
for widget in widgets:
@@ -108,7 +108,7 @@ def test_report_widgets_evaluate(self):
108108
k=3)
109109
results.learner_names = ["LR l2"]
110110

111-
w = self.create_widget(OWTestLearners)
111+
w = self.create_widget(OWTestAndScore)
112112
set_learner = getattr(w, w.Inputs.learner.handler)
113113
set_train = getattr(w, w.Inputs.train_data.handler)
114114
set_test = getattr(w, w.Inputs.test_data.handler)
44.9 KB
Loading
111 KB
Loading
36.1 KB
Loading
45.4 KB
Loading
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)