@@ -216,18 +216,17 @@ def __init__(
216
216
):
217
217
if algorithm not in {"SAMME" , "SAMME.R" }:
218
218
raise ValueError ("algorithm must be 'SAMME' or 'SAMME.R'" )
219
-
219
+
220
220
super ().__init__ (
221
- estimator = SEFR (),
222
- n_estimators = n_estimators ,
223
- learning_rate = learning_rate
221
+ estimator = SEFR (), n_estimators = n_estimators , learning_rate = learning_rate
224
222
)
225
223
self .algorithm = algorithm
226
224
self .scaler = scaler
227
225
self .class_weight = class_weight
228
226
self .loss_function = loss_function
229
227
230
228
if SKLEARN_V1_6_OR_LATER :
229
+
231
230
def __sklearn_tags__ (self ):
232
231
tags = super ().__sklearn_tags__ ()
233
232
tags .input_tags .sparse = False
@@ -236,7 +235,6 @@ def __sklearn_tags__(self):
236
235
tags .classifier_tags .poor_score = True
237
236
return tags
238
237
239
-
240
238
def _more_tags (self ) -> dict [str , bool ]:
241
239
return {
242
240
"binary_only" : True ,
@@ -306,7 +304,6 @@ def fit(self, X, y, sample_weight=None) -> Self:
306
304
sample_weight = sample_weight * expanded_class_weight
307
305
else :
308
306
sample_weight = expanded_class_weight
309
-
310
307
311
308
with warnings .catch_warnings ():
312
309
if SKLEARN_V1_6_OR_LATER :
@@ -316,7 +313,7 @@ def fit(self, X, y, sample_weight=None) -> Self:
316
313
message = ".*parameter 'algorithm' is deprecated.*" ,
317
314
)
318
315
return super ().fit (X_transformed , y , sample_weight )
319
-
316
+
320
317
def _samme_proba (self , estimator , n_classes , X ):
321
318
"""Calculate algorithm 4, step 2, equation c) of Zhu et al [1].
322
319
@@ -345,7 +342,9 @@ def _boost(self, iboost, X, y, sample_weight, random_state):
345
342
y_pred = estimator .predict (X )
346
343
347
344
incorrect = y_pred != y
348
- estimator_error = np .mean (np .average (incorrect , weights = sample_weight , axis = 0 ))
345
+ estimator_error = np .mean (
346
+ np .average (incorrect , weights = sample_weight , axis = 0 )
347
+ )
349
348
350
349
if estimator_error <= 0 :
351
350
return sample_weight , 1.0 , 0.0
@@ -355,20 +354,23 @@ def _boost(self, iboost, X, y, sample_weight, random_state):
355
354
return None , None , None
356
355
357
356
# Compute SEFR-specific weight update
358
- estimator_weight = self .learning_rate * np .log ((1 - estimator_error ) / estimator_error )
357
+ estimator_weight = self .learning_rate * np .log (
358
+ (1 - estimator_error ) / estimator_error
359
+ )
359
360
360
361
if iboost < self .n_estimators - 1 :
361
362
sample_weight = np .exp (
362
- np .log (sample_weight ) + estimator_weight * incorrect * (sample_weight > 0 )
363
+ np .log (sample_weight )
364
+ + estimator_weight * incorrect * (sample_weight > 0 )
363
365
)
364
366
365
367
return sample_weight , estimator_weight , estimator_error
366
-
368
+
367
369
else : # standard SAMME
368
370
y_pred = estimator .predict (X )
369
371
incorrect = y_pred != y
370
372
estimator_error = np .mean (np .average (incorrect , weights = sample_weight ))
371
-
373
+
372
374
if estimator_error <= 0 :
373
375
return sample_weight , 1.0 , 0.0
374
376
if estimator_error >= 0.5 :
@@ -378,17 +380,18 @@ def _boost(self, iboost, X, y, sample_weight, random_state):
378
380
"BaseClassifier in AdaBoostClassifier ensemble is worse than random, ensemble cannot be fit."
379
381
)
380
382
return None , None , None
381
-
382
- estimator_weight = (self .learning_rate *
383
- np .log ((1. - estimator_error ) / max (estimator_error , 1e-10 )))
384
-
383
+
384
+ estimator_weight = self .learning_rate * np .log (
385
+ (1.0 - estimator_error ) / max (estimator_error , 1e-10 )
386
+ )
387
+
385
388
sample_weight *= np .exp (estimator_weight * incorrect )
386
389
387
390
# Normalize sample weights
388
391
sample_weight /= np .sum (sample_weight )
389
392
390
393
return sample_weight , estimator_weight , estimator_error
391
-
394
+
392
395
def decision_function (self , X ):
393
396
check_is_fitted (self )
394
397
X_transformed = self .scaler_ .transform (X )
@@ -399,7 +402,8 @@ def decision_function(self, X):
399
402
n_classes = len (classes )
400
403
401
404
pred = sum (
402
- self ._samme_proba (estimator , n_classes , X_transformed ) for estimator in self .estimators_
405
+ self ._samme_proba (estimator , n_classes , X_transformed )
406
+ for estimator in self .estimators_
403
407
)
404
408
pred /= self .estimator_weights_ .sum ()
405
409
if n_classes == 2 :
@@ -410,7 +414,7 @@ def decision_function(self, X):
410
414
else :
411
415
# Standard SAMME algorithm from AdaBoostClassifier (discrete)
412
416
return super ().decision_function (X_transformed )
413
-
417
+
414
418
def predict (self , X ):
415
419
"""Predict classes for X.
416
420
@@ -434,4 +438,3 @@ def predict(self, X):
434
438
return self .classes_ .take (pred > 0 , axis = 0 )
435
439
436
440
return self .classes_ .take (np .argmax (pred , axis = 1 ), axis = 0 )
437
-
0 commit comments