1212#
1313# License: BSD 3 clause
1414
15+ import warnings
1516import numpy as np
1617import scipy as sp
1718from . import MinCovDet
1819from ..base import ClassifierMixin
20+ from ..utils .validation import check_is_fitted
1921
2022
2123class OutlierDetectionMixin (object ):
@@ -36,7 +38,6 @@ class OutlierDetectionMixin(object):
3638 """
3739 def __init__ (self , contamination = 0.1 ):
3840 self .contamination = contamination
39- self .threshold = None
4041
4142 def decision_function (self , X , raw_values = False ):
4243 """Compute the decision function of the given observations.
@@ -62,14 +63,14 @@ def decision_function(self, X, raw_values=False):
6263 such as the One-Class SVM.
6364
6465 """
66+ check_is_fitted (self , 'threshold_' )
6567 mahal_dist = self .mahalanobis (X )
6668 if raw_values :
6769 decision = mahal_dist
6870 else :
69- if self .threshold is None :
70- raise Exception ("Please fit data before predicting" )
71+ check_is_fitted (self , 'threshold_' )
7172 transformed_mahal_dist = mahal_dist ** 0.33
72- decision = self .threshold ** 0.33 - transformed_mahal_dist
73+ decision = self .threshold_ ** 0.33 - transformed_mahal_dist
7374
7475 return decision
7576
@@ -90,17 +91,23 @@ def predict(self, X):
9091 The values of the less outlying point's decision function.
9192
9293 """
93- if self .threshold is None :
94- raise Exception ("Please fit data before predicting" )
94+ check_is_fitted (self , 'threshold_' )
9595 is_inlier = - np .ones (X .shape [0 ], dtype = int )
9696 if self .contamination is not None :
9797 values = self .decision_function (X , raw_values = True )
98- is_inlier [values <= self .threshold ] = 1
98+ is_inlier [values <= self .threshold_ ] = 1
9999 else :
100100 raise NotImplementedError ("You must provide a contamination rate." )
101101
102102 return is_inlier
103103
104+ @property
105+ def threshold (self ):
106+ warnings .warn (("The threshold attribute is renamed to threshold_ from "
107+ "0.16 onwards and will be removed in 0.18" ),
108+ DeprecationWarning , stacklevel = 1 )
109+ return getattr (self , 'threshold_' , None )
110+
104111
105112class EllipticEnvelope (ClassifierMixin , OutlierDetectionMixin , MinCovDet ):
106113 """An object for detecting outliers in a Gaussian distributed dataset.
@@ -175,10 +182,7 @@ def __init__(self, store_precision=True, assume_centered=False,
175182 OutlierDetectionMixin .__init__ (self , contamination = contamination )
176183
177184 def fit (self , X , y = None ):
178- """
179- """
180185 MinCovDet .fit (self , X )
181- self .threshold = sp .stats .scoreatpercentile (
186+ self .threshold_ = sp .stats .scoreatpercentile (
182187 self .dist_ , 100. * (1. - self .contamination ))
183-
184188 return self
0 commit comments