imbalanced-data — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited imbalanced-data (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
When positives are rare, naive training and naive metrics both mislead. A model that always predicts "negative" can score 99% accuracy and catch zero fraud. Handle imbalance at three levels: metric, algorithm, and threshold — and resample inside cross-validation, never before.
Drop accuracy and ROC-AUC-as-sole-metric. Prefer:
| Technique | How | When |
|---|---|---|
| Class weights | class_weight="balanced" / scale_pos_weight | First choice — no data duplication |
| Undersample majority | RandomUnderSampler | Lots of data, majority redundant |
| Oversample minority | SMOTE / ADASYN | Limited minority samples |
| Combine | SMOTE + Tomek/ENN | Noisy boundaries |
Class weights are the cheapest, leak-free first move:
# sklearn
LogisticRegression(class_weight="balanced")
# XGBoost / LightGBM
scale_pos_weight = n_negative / n_positiveResampling before CV leaks synthetic neighbors across the split and inflates scores. Use imblearn's pipeline so SMOTE fits on training folds only:
from imblearn.pipeline import Pipeline as ImbPipeline
from imblearn.over_sampling import SMOTE
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.model_selection import cross_val_score, StratifiedKFold
pipe = ImbPipeline([
("smote", SMOTE(random_state=42)), # applied to train fold only
("clf", HistGradientBoostingClassifier(random_state=42)),
])
cv = StratifiedKFold(5, shuffle=True, random_state=42)
print(cross_val_score(pipe, X, y, cv=cv, scoring="average_precision").mean())Default 0.5 is almost always wrong for imbalanced problems. Pick the threshold from the validation PR curve to hit your precision/recall target:
from sklearn.metrics import precision_recall_curve
import numpy as np
prec, rec, thr = precision_recall_curve(y_val, val_scores)
# smallest threshold achieving >= 0.90 precision
ok = np.where(prec[:-1] >= 0.90)[0]
chosen = thr[ok[0]] if len(ok) else 0.5A model trained with leak-free resampling/weights, scored with PR-AUC and a tuned threshold via model-evaluation, ready for model-serving.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.