Skip to content

Commit 137f2d8

Browse files
committed
TestAndScore: Fix data errors
1 parent d019c6c commit 137f2d8

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

Orange/widgets/evaluate/owtestandscore.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from Orange.evaluation import Results
3333
from Orange.preprocess.preprocess import Preprocess
3434
import Orange.regression
35+
from Orange.statistics.util import unique
3536
from Orange.widgets import gui, settings, widget
3637
from Orange.widgets.evaluate.utils import \
3738
usable_scorers, ScoreTable, learner_name, scorer_caller
@@ -189,17 +190,14 @@ class Outputs:
189190
class Error(OWWidget.Error):
190191
train_data_empty = Msg("Train dataset is empty.")
191192
test_data_empty = Msg("Test dataset is empty.")
192-
class_required = Msg("Train data input requires a target variable.")
193-
too_many_classes = Msg("Too many target variables.")
194193
class_required_test = Msg("Test data input requires a target variable.")
195194
too_many_folds = Msg("Number of folds exceeds the data size")
196195
class_inconsistent = Msg("Test and train datasets "
197196
"have different target variables.")
198197
memory_error = Msg("Not enough memory.")
199-
no_class_values = Msg("Target variable has no values.")
200-
only_one_class_var_value = Msg("Target variable has only one value.")
201198
test_data_incompatible = Msg(
202199
"Test data may be incompatible with train data.")
200+
data_error = Msg("{}")
203201

204202
class Warning(OWWidget.Warning):
205203
missing_data = \
@@ -383,25 +381,29 @@ def set_train_data(self, data):
383381
self.cancel()
384382
self.Information.data_sampled.clear()
385383
self.Error.train_data_empty.clear()
386-
self.Error.class_required.clear()
387-
self.Error.too_many_classes.clear()
388-
self.Error.no_class_values.clear()
389-
self.Error.only_one_class_var_value.clear()
384+
self.Error.data_error.clear()
385+
390386
if data is not None and not data:
391387
self.Error.train_data_empty()
392388
data = None
393389
if data:
394-
conds = [not data.domain.class_vars,
395-
len(data.domain.class_vars) > 1,
396-
np.isnan(data.Y).all(),
397-
data.domain.has_discrete_class and len(data.domain.class_var.values) == 1]
398-
errors = [self.Error.class_required,
399-
self.Error.too_many_classes,
400-
self.Error.no_class_values,
401-
self.Error.only_one_class_var_value]
402-
for cond, error in zip(conds, errors):
390+
data_errors = [
391+
(
392+
"Train data input requires a target variable.",
393+
not data.domain.class_vars
394+
),
395+
("Too many target variables.", len(data.domain.class_vars) > 1),
396+
("Target variable has no values.", np.isnan(data.Y).all()),
397+
(
398+
"Target variable has only one value.",
399+
data.domain.has_discrete_class and len(unique(data.Y)) < 2
400+
),
401+
("Data has no features to learn from.", data.X.shape[1] == 0),
402+
]
403+
404+
for error_msg, cond in data_errors:
403405
if cond:
404-
error()
406+
self.Error.data_error(error_msg)
405407
data = None
406408
break
407409

Orange/widgets/evaluate/tests/test_owtestandscore.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ def test_one_class_value(self):
166166
"yyyy"))
167167
)
168168
self.widget.n_folds = 0
169-
self.assertFalse(self.widget.Error.only_one_class_var_value.is_shown())
169+
self.assertFalse(self.widget.Error.data_error.is_shown())
170170
self.send_signal("Data", table)
171171
self.send_signal("Learner", MajorityLearner(), 0, wait=1000)
172-
self.assertTrue(self.widget.Error.only_one_class_var_value.is_shown())
172+
self.assertTrue(self.widget.Error.data_error.is_shown())
173173

174174
def test_nan_class(self):
175175
"""
@@ -178,12 +178,14 @@ def test_nan_class(self):
178178
"""
179179
def assertErrorShown(data, is_shown):
180180
self.send_signal("Data", data)
181-
self.assertEqual(is_shown, self.widget.Error.no_class_values.is_shown())
181+
self.assertEqual(is_shown, self.widget.Error.data_error.is_shown())
182182

183183
data = Table("iris")[::30]
184184
data.Y[:] = np.nan
185185

186-
for data, is_shown in zip([None, data, Table("iris")[:30]], [False, True, False]):
186+
for data, is_shown in zip(
187+
[None, data, Table("iris")[:30]], [False, True, True]
188+
):
187189
assertErrorShown(data, is_shown)
188190

189191
def test_addon_scorers(self):
@@ -319,15 +321,19 @@ def _test_scores(self, train_data, test_data, learner, sampling, n_folds):
319321
self.send_signal(self.widget.Inputs.learner, learner, 0, wait=5000)
320322
return self._retrieve_scores()
321323

322-
def test_scores_constant_all_same(self):
324+
def test_scores_constant(self):
323325
table = Table.from_list(
324326
self.scores_domain,
325-
list(zip(*self.scores_table_values + [list("yyyy")]))
327+
list(zip(*self.scores_table_values + [list("yyyn")]))
326328
)
327329

328-
self.assertTupleEqual(self._test_scores(
329-
table, table, ConstantLearner(), OWTestAndScore.TestOnTest, None),
330-
(None, 1, 1, 1, 1))
330+
self.assertTupleEqual(
331+
self._test_scores(
332+
table, table[:3], ConstantLearner(),
333+
OWTestAndScore.TestOnTest, None
334+
),
335+
(None, 1, 1, 1, 1)
336+
)
331337

332338
def test_scores_log_reg_overfitted(self):
333339
table = Table.from_list(

0 commit comments

Comments
 (0)