Conversation
1. Tukey threshold percentile scale (0.25, 0.75) -> (25, 75)
numpy.percentile expects values in [0, 100], not [0, 1]. The old
calls were essentially returning the minimum of di_train for both
hinges, so IQR collapsed to ~0 and the Tukey cutoff was always
the 75th-percentile-ish value of di_train -- then the next line
(cutpoint = numpy.maximum(cutpoint, di_train.max())) clamped it
up to the max anyway, hiding the bug.
2. Float-threshold percentile scale: numpy.percentile(di_train, t)
where t in (0, 1). Same scale issue. Documentation says the
user passes a quantile in (0, 1); convert to percentile via
threshold * 100.
3. CV-split unpack order: sklearn CrossValidator.split() yields
(train_idx, test_idx). The previous loop unpacked them as
(test_ix, train_ix), so:
- d_mins[test_ix] = ... was actually d_mins[train_ix_real],
overwritten (k-1) times per index (one per fold the point
appeared in as training data) instead of filled exactly
once for each held-out point.
- hold_to_seen_d was train->test distance, not the intended
holdout->in-fold distance. Symmetric in Euclidean so the
distance values weren't wrong per se, but the rows fed to
d_mins[test_ix] = ...min(axis=1) corresponded to the wrong
points.
Restores the documented semantics: each held-out point's
minimum distance to its training fold, recorded once per point.
nanophyto
self-requested a review
May 28, 2026 08:55
nanophyto
approved these changes
May 28, 2026
nanophyto
left a comment
Owner
There was a problem hiding this comment.
Good catch thanks for fixing it.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
sorry! Reworking through this code an i caught two bugs in using numpy.percentile (caused by the difference between it and pandas) and one train/test confusion that didn’t affect validity
Tukey threshold percentile scale (0.25, 0.75) -> (25, 75) numpy.percentile expects values in [0, 100], not [0, 1]. The old calls were essentially returning the minimum of di_train for both hinges, so IQR collapsed to ~0 and the Tukey cutoff was always the 75th-percentile-ish value of di_train -- then the next line (cutpoint = numpy.maximum(cutpoint, di_train.max())) clamped it up to the max anyway, hiding the bug.
Float-threshold percentile scale: numpy.percentile(di_train, t) where t in (0, 1). Same scale issue. Documentation says the user passes a quantile in (0, 1); convert to percentile via threshold * 100.
CV-split unpack order: sklearn CrossValidator.split() yields (train_idx, test_idx). The previous loop unpacked them as (test_ix, train_ix), so:
it’s important to note this is symmetric in Euclidean so the distance values weren't wrong per se, but the rows fed to d_mins[test_ix] = ...min(axis=1) corresponded to the wrong points. Restores the documented semantics: each held-out point's minimum distance to its training fold, recorded once per point.
Further we weren’t using the tukey cutoff, but it’s useful to correct just in case.