1515from sklearn .utils import _safe_indexing
1616
1717from ..base import BaseOverSampler
18- from ...exceptions import raise_isinstance_error
1918from ...utils import check_neighbors_object
2019from ...utils import Substitution
2120from ...utils ._docstring import _n_jobs_docstring
@@ -48,18 +47,32 @@ class BorderlineSMOTE(BaseSMOTE):
4847 {random_state}
4948
5049 k_neighbors : int or object, default=5
51- If ``int``, number of nearest neighbours to used to construct synthetic
52- samples. If object, an estimator that inherits from
53- :class:`~sklearn.neighbors.base.KNeighborsMixin` that will be used to
54- find the k_neighbors.
50+ The nearest neighbors used to define the neighborhood of samples to use
51+ to generate the synthetic samples. You can pass:
52+
53+ - an `int` corresponding to the number of neighbors to use. A
54+ `~sklearn.neighbors.NearestNeighbors` instance will be fitted in this
55+ case.
56+ - an instance of a compatible nearest neighbors algorithm that should
57+ implement both methods `kneighbors` and `kneighbors_graph`. For
58+ instance, it could correspond to a
59+ :class:`~sklearn.neighbors.NearestNeighbors` but could be extended to
60+ any compatible class.
5561
5662 {n_jobs}
5763
5864 m_neighbors : int or object, default=10
59- If int, number of nearest neighbours to use to determine if a minority
60- sample is in danger. If object, an estimator that inherits
61- from :class:`~sklearn.neighbors.base.KNeighborsMixin` that will be used
62- to find the m_neighbors.
65+ The nearest neighbors used to determine if a minority sample is in
66+ "danger". You can pass:
67+
68+ - an `int` corresponding to the number of neighbors to use. A
69+ `~sklearn.neighbors.NearestNeighbors` instance will be fitted in this
70+ case.
71+ - an instance of a compatible nearest neighbors algorithm that should
72+ implement both methods `kneighbors` and `kneighbors_graph`. For
73+ instance, it could correspond to a
74+ :class:`~sklearn.neighbors.NearestNeighbors` but could be extended to
75+ any compatible class.
6376
6477 kind : {{"borderline-1", "borderline-2"}}, default='borderline-1'
6578 The type of SMOTE algorithm to use one of the following options:
@@ -155,7 +168,6 @@ def _validate_estimator(self):
155168 self .nn_m_ = check_neighbors_object (
156169 "m_neighbors" , self .m_neighbors , additional_neighbor = 1
157170 )
158- self .nn_m_ .set_params (** {"n_jobs" : self .n_jobs })
159171 if self .kind not in ("borderline-1" , "borderline-2" ):
160172 raise ValueError (
161173 f'The possible "kind" of algorithm are '
@@ -263,21 +275,37 @@ class SVMSMOTE(BaseSMOTE):
263275 {random_state}
264276
265277 k_neighbors : int or object, default=5
266- If ``int``, number of nearest neighbours to used to construct synthetic
267- samples. If object, an estimator that inherits from
268- :class:`~sklearn.neighbors.base.KNeighborsMixin` that will be used to
269- find the k_neighbors.
278+ The nearest neighbors used to define the neighborhood of samples to use
279+ to generate the synthetic samples. You can pass:
280+
281+ - an `int` corresponding to the number of neighbors to use. A
282+ `~sklearn.neighbors.NearestNeighbors` instance will be fitted in this
283+ case.
284+ - an instance of a compatible nearest neighbors algorithm that should
285+ implement both methods `kneighbors` and `kneighbors_graph`. For
286+ instance, it could correspond to a
287+ :class:`~sklearn.neighbors.NearestNeighbors` but could be extended to
288+ any compatible class.
270289
271290 {n_jobs}
272291
273292 m_neighbors : int or object, default=10
274- If int, number of nearest neighbours to use to determine if a minority
275- sample is in danger. If object, an estimator that inherits from
276- :class:`~sklearn.neighbors.base.KNeighborsMixin` that will be used to
277- find the m_neighbors.
293+ The nearest neighbors used to determine if a minority sample is in
294+ "danger". You can pass:
295+
296+ - an `int` corresponding to the number of neighbors to use. A
297+ `~sklearn.neighbors.NearestNeighbors` instance will be fitted in this
298+ case.
299+ - an instance of a compatible nearest neighbors algorithm that should
300+ implement both methods `kneighbors` and `kneighbors_graph`. For
301+ instance, it could correspond to a
302+ :class:`~sklearn.neighbors.NearestNeighbors` but could be extended to
303+ any compatible class.
278304
279305 svm_estimator : estimator object, default=SVC()
280306 A parametrized :class:`~sklearn.svm.SVC` classifier can be passed.
307+ A scikit-learn compatible estimator can be passed but it is required
308+ to expose a `support_` fitted attribute.
281309
282310 out_step : float, default=0.5
283311 Step size when extrapolating.
@@ -381,14 +409,11 @@ def _validate_estimator(self):
381409 self .nn_m_ = check_neighbors_object (
382410 "m_neighbors" , self .m_neighbors , additional_neighbor = 1
383411 )
384- self .nn_m_ .set_params (** {"n_jobs" : self .n_jobs })
385412
386413 if self .svm_estimator is None :
387414 self .svm_estimator_ = SVC (gamma = "scale" , random_state = self .random_state )
388- elif isinstance (self .svm_estimator , SVC ):
389- self .svm_estimator_ = clone (self .svm_estimator )
390415 else :
391- raise_isinstance_error ( "svm_estimator" , [ SVC ], self .svm_estimator )
416+ self . svm_estimator_ = clone ( self .svm_estimator )
392417
393418 def _fit_resample (self , X , y ):
394419 self ._validate_estimator ()
@@ -403,6 +428,12 @@ def _fit_resample(self, X, y):
403428 X_class = _safe_indexing (X , target_class_indices )
404429
405430 self .svm_estimator_ .fit (X , y )
431+ if not hasattr (self .svm_estimator_ , "support_" ):
432+ raise RuntimeError (
433+ "`svm_estimator` is required to exposed a `support_` fitted "
434+ "attribute. Such estimator belongs to the familly of Support "
435+ "Vector Machine."
436+ )
406437 support_index = self .svm_estimator_ .support_ [
407438 y [self .svm_estimator_ .support_ ] == class_sample
408439 ]
0 commit comments