Skip to content

Fix StandardScaler discarding the mean on a constant feature - #363

Merged
josevalim merged 2 commits into
elixir-nx:mainfrom
RicardoSantos-99:fix-standard-scaler-constant-feature
Aug 26, 2026
Merged

Fix StandardScaler discarding the mean on a constant feature#363
josevalim merged 2 commits into
elixir-nx:mainfrom
RicardoSantos-99:fix-standard-scaler-constant-feature

Conversation

@RicardoSantos-99

Copy link
Copy Markdown
Contributor

StandardScaler zeroed out the mean for any zero-variance feature instead of keeping it, so a constant feature came out uncentered instead of 0.0. Worse on new data: transforming an unseen value through a constant training column just passes it through raw instead of centering it, which is silent data leakage into a pipeline that assumes standardized input.

sklearn only clamps the scale to 1 for a constant feature, it never touches the mean. Removed the line that zeroed it, the existing division-by-1 guard was already enough.

With a zero-variance feature, fit forced the stored mean to 0.0 instead
of the real mean, so transform silently returned the raw (uncentered)
values for that feature instead of 0.0. sklearn keeps the true mean and
only forces scale_ to 1.0, so the constant feature transforms to 0.0
like every other case. scale/3 already divides by 1.0 when std is 0,
so removing the forced-zero mean is enough to match.
Verified against sklearn.preprocessing.StandardScaler directly: it
only clamps scale_ to 1 for a zero-variance feature, mean_ is always
the real column mean. The strongest case is transform on data the
scaler was not fit on - a constant training feature must still center
new values by the fitted mean, not pass them through raw. Confirmed
these tests fail against the code they replace and pass here.
@josevalim
josevalim merged commit 2b8c9fa into elixir-nx:main Aug 26, 2026
2 checks passed
@josevalim

Copy link
Copy Markdown
Contributor

💚 💙 💜 💛 ❤️

@RicardoSantos-99
RicardoSantos-99 deleted the fix-standard-scaler-constant-feature branch August 26, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants