diff --git a/Orange/classification/elliptic_envelope.py b/Orange/classification/elliptic_envelope.py index f596a84c830..7b694f4d1e3 100644 --- a/Orange/classification/elliptic_envelope.py +++ b/Orange/classification/elliptic_envelope.py @@ -2,6 +2,7 @@ from Orange.base import SklLearner, SklModel from Orange.data import Table +from Orange.preprocess import Continuize, RemoveNaNColumns, SklImpute __all__ = ["EllipticEnvelopeLearner"] @@ -27,6 +28,7 @@ def mahalanobis(self, observations): class EllipticEnvelopeLearner(SklLearner): __wraps__ = skl_covariance.EllipticEnvelope __returns__ = EllipticEnvelopeClassifier + preprocessors = [Continuize(), RemoveNaNColumns(), SklImpute()] def __init__(self, store_precision=True, assume_centered=False, support_fraction=None, contamination=0.1, diff --git a/Orange/widgets/data/owoutliers.py b/Orange/widgets/data/owoutliers.py index f295f1b483d..8c77277ecfd 100644 --- a/Orange/widgets/data/owoutliers.py +++ b/Orange/widgets/data/owoutliers.py @@ -43,7 +43,6 @@ class Outputs: class Error(widget.OWWidget.Error): singular_cov = Msg("Singular covariance matrix.") - multiclass_error = Msg("Multiple class data is not supported") memory_error = Msg("Not enough memory") def __init__(self): @@ -149,6 +148,7 @@ def _get_outliers(self): except ValueError: self.Error.singular_cov() self.in_out_info_label.setText(self.in_out_info_default) + return None, None except MemoryError: self.Error.memory_error() return None, None @@ -170,10 +170,7 @@ def commit(self): inliers = outliers = None self.n_inliers = self.n_outliers = None if self.data is not None and len(self.data) > 0: - if self.data.Y.ndim > 1 and self.data.Y.shape[1] > 1: - self.Error.multiclass_error() - else: - inliers, outliers = self._get_outliers() + inliers, outliers = self._get_outliers() self.Outputs.inliers.send(inliers) self.Outputs.outliers.send(outliers) @@ -188,8 +185,9 @@ def detect_outliers(self): support_fraction=self.support_fraction if self.empirical_covariance else None, contamination=self.cont / 100.) - model = learner(self.data) - y_pred = model(self.data) + data = self.data.transform(Domain(self.data.domain.attributes)) + model = learner(data) + y_pred = model(data) self.add_metas(model) return np.array(y_pred) diff --git a/Orange/widgets/data/tests/test_owoutliers.py b/Orange/widgets/data/tests/test_owoutliers.py index 9365da3d5ab..0dedb3862b5 100644 --- a/Orange/widgets/data/tests/test_owoutliers.py +++ b/Orange/widgets/data/tests/test_owoutliers.py @@ -5,7 +5,7 @@ import numpy as np -from Orange.data import Table, Domain, ContinuousVariable, DiscreteVariable +from Orange.data import Table from Orange.widgets.data.owoutliers import OWOutliers from Orange.widgets.tests.base import WidgetTest @@ -25,20 +25,6 @@ def test_data(self): self.assertEqual(self.widget.data, None) self.assertIsNone(self.get_output("Data")) - def test_multiclass(self): - """Check widget for multiclass dataset""" - attrs = [ContinuousVariable("c1"), ContinuousVariable("c2")] - class_vars = [DiscreteVariable("cls", ["a", "b", "c"]), - DiscreteVariable("cls", ["aa", "bb", "cc"])] - domain = Domain(attrs, class_vars) - X = np.arange(12).reshape(6, 2) - Y = np.array([[0, 1], [2, 1], [0, 2], [1, 1], [1, 2], [2, 0]]) - data = Table(domain, X, Y) - self.send_signal(self.widget.Inputs.data, data) - self.assertTrue(self.widget.Error.multiclass_error.is_shown()) - self.send_signal(self.widget.Inputs.data, None) - self.assertFalse(self.widget.Error.multiclass_error.is_shown()) - def test_memory_error(self): """ Handling memory error. @@ -51,3 +37,11 @@ def test_memory_error(self): side_effect=MemoryError): self.send_signal("Data", data) self.assertTrue(self.widget.Error.memory_error.is_shown()) + + def test_nans(self): + """Widget does not crash with nans""" + a = np.arange(20, dtype=float).reshape(4, 5) + a[0, 0] = np.nan + data = Table(a) + self.send_signal(self.widget.Inputs.data, data) + self.assertIsNot(self.get_output(self.widget.Outputs.inliers), None)