Repository navigation
Conversation
The Gaussian-process kernel used by `denoise=True` was `RBF + WhiteKernel + ConstantKernel`, with no amplitude on the RBF term and no `normalize_y`. The smooth component therefore had a fixed prior variance of 1, so for targets far from unit scale the fitted model attributed most of the signal to noise and over-smoothed it. For `y = A sin(2x) + noise` (noise sd = 0.1 A), the RMSE of the "denoised" targets against the true signal was 0.25x the noise level at A = 1, but 7.3x at A = 100 or 1e4, i.e. far worse than not denoising at all. Use `ConstantKernel() * RBF(...) + WhiteKernel(...)` with `normalize_y=True`, and standardize `X` (applying the same transform to `Xresampled`) so the initial length scales suit any input units. The error is now 0.23-0.25x the noise level at every amplitude tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each restart re-runs the marginal-likelihood optimization from random hyperparameters, at O(n^3) per optimizer step, so denoising took minutes for a few hundred rows (about 55-63 s at n=250 and 10 min at n=500 with three features). With standardized inputs and normalized targets, the fits were identical across 0, 2, 10, and 50 restarts on every case tested (RMSE against the true signal of 0.377/0.397 at n=250 for all four, and 0.327/0.330 at n=500 for 2 and 10), so keep a few restarts as a guard against poor local optima and drop the rest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`check_array(Xresampled)` dropped the column names, so when `X` and `Xresampled` were DataFrames with columns in different orders, the denoised targets were evaluated at, and the search was run on, rows whose columns were silently swapped (e.g. a temperature column read as a fraction). Select the columns of `X` from `Xresampled` by name, and raise a clear error when some are missing. Also reject `weights` together with `Xresampled` when denoising: the denoised targets have one row per row of `Xresampled`, so the weights no longer line up, which previously failed with a bare `AssertionError`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Learn the GP signal amplitude with ConstantKernel() * RBF and normalize_y=True, keeping 50 optimizer restarts and unscaled inputs. Match a DataFrame Xresampled to X by column name, and reject weights combined with Xresampled under denoise. Register TestDenoising in runtests() so CI runs it. Co-authored-by: Miles Cranmer <miles.cranmer@gmail.com>
…-scale targets Co-authored-by: Miles Cranmer <miles.cranmer@gmail.com>
|
This is a behavior change, correct? |
|
Yes, for anyone using
With a fixed |
|
Sorry to ask but could you be clear which part is you and which part is suggested by Claude? I am trying to understand the need better. PySR is quite a mature library at this point so any behavior changes need a strong motivation. |
|
Fair question. The PR came from Claude Code: I asked it to review PySR, and it found this by reading
So for speeds, denoising currently makes the data about 5× worse than not denoising at all. One caveat: for targets near unit scale (e.g. 1–7 Likert), it makes no difference with strong effects, and |
Summary
With
denoise=True, the Gaussian process produced denoised targets that were much worse than the raw data wheneverywas not on unit scale. The kernel wasRBF + WhiteKernel + ConstantKernel, with no amplitude on the RBF term and nonormalize_y. The smooth component therefore had a fixed prior variance of 1, and for larger-scale targets the fit attributed most of the signal to noise.For
y = A·sin(2x) + noise, with noise s.d. = 0.1·A and n = 200, here is the RMSE of the denoisedyagainst the true signal, as a multiple of the noise level:yThe PR has three commits:
ConstantKernel() * RBF(...) + WhiteKernel(...)withnormalize_y=True, and standardizeX(applying the same transform toXresampled) so the initial length scales suit any units.XresampledtoXby column name.check_array(Xresampled)dropped the column names, so DataFrames with columns in a different order silently swapped columns. The test uses a temperature column in [300, 400] and a fraction in [0, 1]. The PR also raises a clear error when columns are missing, and whenweightsare combined withXresampledunder denoising: the targets then have one row per row ofXresampled, so the weights no longer line up, which previously failed with a bareAssertionError.Tests
TestDenoising.test_denoise_learns_signal_amplitude: at amplitude 100 the RMSE is 73 on master against a noise level of 10.TestDenoising.test_xresampled_columns_are_matched_by_nameBoth fail on master and pass here.
test_pandas_resample_with_nested_constraintsalso passes.🤖 Generated with Claude Code