SWIFTMonitor¶
SWIFTMonitor
¶
SWIFTMonitor(model: object = None, order: int = 1, n_permutations: int = 1000, alpha: float = 0.05, correction: Union[CorrectionMethod, str] = BH, n_synthetic: int = 10, max_samples: int | None = None, random_state: int = 42)
Bases: BaseEstimator, TransformerMixin
SHAP-Weighted Impact Feature Testing monitor.
Orchestrates the 5-stage SWIFT pipeline:
1. Extract decision points from trained model
2. Build buckets from decision points
3. Compute bucket-level mean SHAP (SHAP normalization σ_j)
4. Compute Wasserstein distance on SHAP-transformed distributions
5. Permutation-based significance testing with MTC
The transformation σ_j is computed ONCE during fit() and applied
identically to all monitoring samples via transform().
| PARAMETER | DESCRIPTION |
|---|---|
model
|
Trained tree-ensemble model (LightGBM
TYPE:
|
order
|
Wasserstein order (1 → W₁, 2 → W₂).
TYPE:
|
n_permutations
|
Number of permutations for p-value estimation in
TYPE:
|
alpha
|
Significance level for multiple testing correction.
TYPE:
|
correction
|
Multiple testing correction method. Accepts enum members or
strings (
TYPE:
|
n_synthetic
|
Number of synthetic observations to create for empty buckets
during
TYPE:
|
max_samples
|
Maximum total pool size (n_ref + n_mon) for the permutation test.
If exceeded, subsample proportionally.
TYPE:
|
random_state
|
Seed for the random number generator, ensuring reproducibility.
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
bucket_sets_ |
Per-feature bucket sets with
TYPE:
|
X_ref_ |
Copy of the reference DataFrame (stored for permutation testing).
TYPE:
|
shap_values_ |
SHAP values computed on the reference data.
TYPE:
|
feature_names_in_ |
Feature names inferred from
TYPE:
|
n_features_in_ |
Number of features seen during
TYPE:
|
Examples:
>>> monitor = SWIFTMonitor(model=lgb_model, n_permutations=200)
>>> monitor.fit(X_ref)
SWIFTMonitor(...)
>>> result = monitor.test(X_mon)
>>> result.drifted_features
('feature_3',)
Source code in src/swift/pipeline.py
fit
¶
fit(X: DataFrame, y: None = None) -> SWIFTMonitor
Fit the SWIFT monitor on reference data.
Executes stages 1–3: extraction → bucketing → SHAP normalization.
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Reference DataFrame. Feature names are inferred from
TYPE:
|
y
|
Not used; present for API compatibility.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
self
|
|
Source code in src/swift/pipeline.py
transform
¶
Apply the SHAP transformation σ_j to every feature.
Each value x_ij is mapped to the mean SHAP of its bucket:
σ_j(x_ij) = mean_shap_j^{bucket(x_ij)}.
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Input data.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
SHAP-transformed DataFrame (same shape and column names). |
Source code in src/swift/pipeline.py
score
¶
Compute per-feature SWIFT scores (stage 4 only, no testing).
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Monitoring DataFrame. When X_compare is
TYPE:
|
X_compare
|
Optional second sample. When provided, SWIFT scores are
computed between X and X_compare instead of between
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict[str, float]
|
Feature name → SWIFT score (Wasserstein distance on SHAP-transformed distributions). |
Source code in src/swift/pipeline.py
test
¶
test(X: DataFrame, X_compare: DataFrame | None = None) -> SWIFTResult
Run the full SWIFT pipeline: score + test + aggregate.
Stages 4–5 + aggregation:
- Compute per-feature SWIFT scores (Wasserstein on SHAP-transformed).
- Permutation test for p-values.
- Multiple testing correction.
- Model-level aggregation.
All hyperparameters (order, n_permutations, alpha,
correction, max_samples) are taken from instance attributes
set in the constructor. Use set_params() to override for
individual calls (e.g. different random_state per experiment
repetition).
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Monitoring DataFrame. When X_compare is
TYPE:
|
X_compare
|
Optional second sample. When provided, the test compares
X against X_compare instead of
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
SWIFTResult
|
Per-feature and model-level results. |
Source code in src/swift/pipeline.py
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | |
plot_buckets
¶
plot_buckets(feature_name: str, X: DataFrame | None = None, X_compare: DataFrame | None = None, labels: tuple[str, str] = ('Reference', 'Comparison'), figsize: tuple[float, float] = (10, 5), title: str | None = None, max_label_buckets: int = 20, x_axis: str = 'bucket') -> tuple
Plot the bucketing profile for a single feature.
Shows mean SHAP per bucket (line + 95 % error band) on the left y-axis and observation density (filled line) on the right y-axis.
| PARAMETER | DESCRIPTION |
|---|---|
feature_name
|
Feature to visualise. Must be in
TYPE:
|
X
|
Sample whose density is shown as the primary line. When
TYPE:
|
X_compare
|
Optional second sample for density comparison. Must contain feature_name as a column. Each sample's density is normalised to 1.0 independently.
TYPE:
|
labels
|
Legend labels
TYPE:
|
figsize
|
Figure size in inches.
TYPE:
|
title
|
Custom title. Defaults to
TYPE:
|
max_label_buckets
|
Use compact index labels (
TYPE:
|
x_axis
|
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
(Figure, Axes)
|
Matplotlib figure and primary (SHAP) axes. |
| RAISES | DESCRIPTION |
|---|---|
NotFittedError
|
If the monitor has not been fitted. |
ValueError
|
If feature_name is not in |
Source code in src/swift/pipeline.py
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | |
plot_swift_scores
¶
plot_swift_scores(result: SWIFTResult, result_compare: SWIFTResult | None = None, labels: tuple[str, str] = ('Result A', 'Result B'), threshold: float | None = None, sort_by: str = 'score', figsize: tuple[float, float] = (12, 5), title: str | None = None) -> tuple
Plot SWIFT scores per feature from a test() result.
Draws one bar per feature, colored red (drifted) or blue (not
drifted), with horizontal reference lines for SWIFT_max,
SWIFT_mean, and an optional user-provided threshold.
In comparison mode (when result_compare is given), draws grouped side-by-side bars with neutral coloring.
| PARAMETER | DESCRIPTION |
|---|---|
result
|
Primary result from
TYPE:
|
result_compare
|
Optional second result for grouped comparison.
TYPE:
|
labels
|
Legend labels
TYPE:
|
threshold
|
Optional detection threshold drawn as a dotted black line.
TYPE:
|
sort_by
|
Feature ordering on the x-axis.
TYPE:
|
figsize
|
Figure size in inches.
TYPE:
|
title
|
Custom title.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
(Figure, Axes)
|
|
| RAISES | DESCRIPTION |
|---|---|
NotFittedError
|
If the monitor has not been fitted. |