# ground truth fit is worse than cross validated fit on noisy data?

I am having these weird results when playing around with cross validation that I would greatly appreciate to have any comments.

Briefly, I have a lower mean squared error (MSE) when doing regression (least-squares) using cross-valitation (CV), than when using the "ground truth weights" that I used to generate the data.

Note however, that I compute the MSE on noisy data (generated data + noise), so MSE of 0 would not be expected for noise levels above 0.

Weirdly, for high noise conditions, I get lower MSE with cross validated least squares than with the "ground" truth weights used to generate the clean data - to which I then add different levels of noise to the input (X). Instead, if I add guassian noise to the output (y) the "ground truth weights" perform better.

More details below.

## Simulation of data

I am generating beta from a guassian and X from a uniform distribution. I then compute the to-be-regressed y as y = beta * X. python 3 code:

def generate_data(noise_frac):
X = np.random.rand(ntrials,nneurons)
X = np.random.normal(size=(ntrials,nneurons))

beta = np.random.randn(nneurons)
y = X @ beta

# not very important how I generated noise here
noise_x = np.random.multivariate_normal(mean=zeros(nneurons), cov=diag(np.random.rand(nneurons)), size=ntrials)

X_noise = X + noise_x*noise_frac

return X_noise, y, beta



As you can see I also add noise to X.

# Regression

I then project this noised data X_noise for different values of noise onto beta:

y_hat = (X_noise) @ beta


And compute the MSE:

mse = mean((y_hat - y)**2)


As expected, MSE increases with noise (blue line in the figure).

However, I get lower MSE if I use cross validated least-squares! This is now orange line in the figure.

To do CV, I split X_noise in random 100 train and test sets. In broad terms, This is how I do CV in python:

beta_lsq = pinv(X_train) @ y_train
y_hat_lsq = (X_test) @ beta_lsq
mse = mean((y_hat_lsq - y_test)**2)


On the other hand, if I add noise to y, instead of X, then everything makes sense:

Thank you very much in advance!

PS: This is a crosspost from stack overflow

• Can you specify nneurons and ntrials to make this reproducible? – Itamar Mushkin Jul 6 '20 at 11:40
• Sorry, here's the link to a notebook that reproduces this: colab.research.google.com/drive/… – user2183045 Jul 6 '20 at 12:35
• I only asked for those two parameters; anyway, I see they are ntrials = 1000 nneurons = 100 – Itamar Mushkin Jul 6 '20 at 12:58
• the mentioned cross-post: stackoverflow.com/q/62744439/10495893 – Ben Reiniger Jul 7 '20 at 20:14
• I can't actually reproduce your second graph; I still get a noticeably larger mse for the ground truth model compared to the fitted model. – Ben Reiniger Jul 8 '20 at 1:41