Heuristic:DistrictDataLabs Yellowbrick Scikit Learn API Compatibility
| Knowledge Sources | |
|---|---|
| Domains | Compatibility, Machine_Learning |
| Last Updated | 2026-02-08 05:00 GMT |
Overview
Use try/except ImportError blocks with issue-referenced comments to handle scikit-learn API renames and module reorganizations across versions.
Description
Scikit-learn periodically renames functions, moves modules, or deprecates APIs across minor versions. Yellowbrick maintains backward compatibility by wrapping these imports in try/except blocks that first attempt the new API name and fall back to the old one. Each compatibility shim is annotated with a GitHub issue number (e.g., `# See #1137`) that documents the specific sklearn version change, creating a traceable audit trail.
Usage
Apply this heuristic whenever Yellowbrick imports a scikit-learn internal or semi-private API. The pattern ensures that users on older scikit-learn versions (which Yellowbrick supports back to >= 1.0.0) do not encounter import errors, while users on newer versions get the correct API automatically.
The Insight (Rule of Thumb)
- Action: Wrap sklearn imports that have been renamed or moved in try/except ImportError blocks. Always try the new API first, fall back to the old API in the except clause.
- Value: Annotate each block with a comment referencing the GitHub issue number and the sklearn version that introduced the change.
- Trade-off: Adds 3-4 lines of boilerplate per import, but prevents runtime crashes across the entire supported sklearn version range. The alternative (pinning to a single sklearn version) would severely limit user adoption.
Reasoning
Yellowbrick supports scikit-learn >= 1.0.0, spanning multiple sklearn release cycles that include API refactoring. The sklearn project follows a deprecation cycle where functions are renamed (e.g., `calinski_harabaz_score` to `calinski_harabasz_score` to fix a typo) or moved between submodules (e.g., `sklearn.utils.safe_indexing` to `sklearn.utils._safe_indexing` when the function was made private). By importing the new name first, Yellowbrick ensures users on current sklearn get optimal behavior, while the fallback import keeps older installations working.
The issue number annotations serve double duty: they explain why the compatibility code exists (preventing future developers from removing it as "dead code"), and they link to the full discussion of the sklearn change for context.
Code Evidence
Sklearn metric rename (calinski_harabasz) from `yellowbrick/cluster/elbow.py:36-39`:
try:
from sklearn.metrics import calinski_harabasz_score as chs
except ImportError:
from sklearn.metrics import calinski_harabaz_score as chs
Sklearn safe_indexing relocation (issue #1137) from `yellowbrick/classifier/threshold.py:33-37`:
try:
# See #1137: this allows compatibility for scikit-learn >= 0.24
from sklearn.utils import safe_indexing as _safe_indexing
except ImportError:
from sklearn.utils import _safe_indexing
Sklearn _check_targets module move (issue #1124) from `yellowbrick/classifier/class_prediction_error.py:29-33`:
try:
# See #1124: this allows compatibility for scikit-learn >= 0.20
from sklearn.metrics._classification import _check_targets
except ImportError:
from sklearn.metrics.classification import _check_targets