Skip to content

Commit 7e2f561

Browse files
committed
Outliers: Refactor
1 parent aa36a3b commit 7e2f561

File tree

3 files changed

+27
-32
lines changed

3 files changed

+27
-32
lines changed

Orange/classification/tests/test_outlier_detection.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
import unittest
66

77
import numpy as np
8-
from Orange.data import Table, Domain, ContinuousVariable
8+
99
from Orange.classification import EllipticEnvelopeLearner, \
1010
IsolationForestLearner, LocalOutlierFactorLearner, OneClassSVMLearner
11+
from Orange.data import Table, Domain, ContinuousVariable
1112

1213

1314
class _TestDetector(unittest.TestCase):

Orange/widgets/data/owoutliers.py

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from Orange.classification import OneClassSVMLearner, EllipticEnvelopeLearner,\
1111
LocalOutlierFactorLearner, IsolationForestLearner
12-
from Orange.data import Table, DiscreteVariable
12+
from Orange.data import Table
1313
from Orange.widgets import gui
1414
from Orange.widgets.settings import Setting
1515
from Orange.widgets.utils.sql import check_sql_input
@@ -238,44 +238,40 @@ def enable_controls(self):
238238
self.method_combo.model().item(self.Covariance).setEnabled(False)
239239
self.Warning.disabled_cov()
240240

241-
def _get_outliers(self) -> Tuple[Table, Table, Table]:
241+
def commit(self):
242+
inliers, outliers, data = self.detect_outliers()
243+
summary = len(inliers) if inliers else self.info.NoOutput
244+
self.info.set_output_summary(summary)
245+
self.Outputs.inliers.send(inliers)
246+
self.Outputs.outliers.send(outliers)
247+
self.Outputs.data.send(data)
248+
249+
def detect_outliers(self) -> Tuple[Table, Table, Table]:
250+
self.n_inliers = self.n_outliers = None
242251
self.Error.singular_cov.clear()
243252
self.Error.memory_error.clear()
253+
if not self.data:
254+
return None, None, None
244255
try:
245-
pred, outlier_var = self.detect_outliers()
256+
learner_class = self.METHODS[self.outlier_method]
257+
kwargs = self.current_editor.get_parameters()
258+
learner = learner_class(**kwargs)
259+
model = learner(self.data)
260+
pred = model(self.data)
246261
except ValueError:
247262
self.Error.singular_cov()
248263
return None, None, None
249264
except MemoryError:
250265
self.Error.memory_error()
251266
return None, None, None
252267
else:
253-
col = pred[:, outlier_var].metas
268+
col = pred[:, model.outlier_var].metas
254269
inliers_ind = np.where(col == 1)[0]
255270
outliers_ind = np.where(col == 0)[0]
256271
self.n_inliers = len(inliers_ind)
257272
self.n_outliers = len(outliers_ind)
258273
return self.data[inliers_ind], self.data[outliers_ind], pred
259274

260-
def commit(self):
261-
inliers = outliers = data = None
262-
self.n_inliers = self.n_outliers = None
263-
if self.data:
264-
inliers, outliers, data = self._get_outliers()
265-
266-
summary = len(inliers) if inliers else self.info.NoOutput
267-
self.info.set_output_summary(summary)
268-
self.Outputs.inliers.send(inliers)
269-
self.Outputs.outliers.send(outliers)
270-
self.Outputs.data.send(data)
271-
272-
def detect_outliers(self) -> Tuple[Table, DiscreteVariable]:
273-
learner_class = self.METHODS[self.outlier_method]
274-
kwargs = self.current_editor.get_parameters()
275-
learner = learner_class(**kwargs)
276-
model = learner(self.data)
277-
return model(self.data), model.outlier_var
278-
279275
def send_report(self):
280276
if self.n_outliers is None or self.n_inliers is None:
281277
return

Orange/widgets/data/tests/test_owoutliers.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,20 @@ def callback():
6868
self.assertIsNotNone(self.get_output(self.widget.Outputs.outliers))
6969
self.assertIsNotNone(self.get_output(self.widget.Outputs.data))
7070

71-
self.send_signal(self.widget.Inputs.data, self.iris)
71+
self.send_signal(self.widget.Inputs.data, self.heart_disease)
7272
simulate.combobox_run_through_all(self.widget.method_combo,
7373
callback=callback)
7474

75-
def test_memory_error(self):
75+
@patch("Orange.classification.outlier_detection._OutlierModel.predict")
76+
def test_memory_error(self, mocked_predict: Mock):
7677
"""
7778
Handling memory error.
7879
GH-2374
7980
"""
80-
data = Table("iris")[::3]
8181
self.assertFalse(self.widget.Error.memory_error.is_shown())
82-
with unittest.mock.patch(
83-
"Orange.widgets.data.owoutliers.OWOutliers.detect_outliers",
84-
side_effect=MemoryError):
85-
self.send_signal("Data", data)
86-
self.assertTrue(self.widget.Error.memory_error.is_shown())
82+
mocked_predict.side_effect = MemoryError
83+
self.send_signal(self.widget.Inputs.data, self.iris)
84+
self.assertTrue(self.widget.Error.memory_error.is_shown())
8785

8886
def test_nans(self):
8987
"""Widget does not crash with nans"""

0 commit comments

Comments
 (0)