I'm wondering if adding Gaussian Noise to two waveforms tends to decrease their Pearson correlation. Below is a simulation of adding noise to two waveforms (blue = np.sin(x)
and orange = 1 + np.sin(1.1 * x)
). While the means don't change very much, the Pearson correlation is much more affected. It makes sense the noise shouldn't change the mean since the noise itself has mean zero, however, for Pearson correlations, it's not obvious whether it'll tend to move the value up, down, or stay the same
Mathematically I think this translates to this for the mean which does show it'll tend to stay the same
For Pearson correlations, this is what I get
The numerator seems to grow as ε, while the denominator grows as sqrt(ε)
. So for small ε, the Pearson correlation will tend to zero since the denominator is larger. I'm not from a statistics background so any help would be greatly appreciated, thank you!
Code
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from tqdm.notebook import tqdm
from matplotlib import animation
from scipy.stats import pearsonr, spearmanr
sns.set()
def rand(y, noise=0.1):
return y + noise * np.random.normal(size=y.shape)
def init():
for line in lines:
line.set_data([], [])
act_text.set_text('')
corr_text.set_text('')
return tuple(lines) + (act_text, corr_text,)
def animate(i):
global y1, y2
y1 = rand(y1, noise=0.04)
y2 = rand(y2, noise=0.04)
lines[0].set_data(x, y1)
lines[1].set_data(x, y2)
y1s.append(y1.mean())
y2s.append(y2.mean())
pears.append(pearsonr(y1, y2)[0])
act = "blue = %.03f\norange = %.03f" % (y1s[-1], y2s[-1])
corr = "\n%.04f" % pears[-1]
act_text.set_text(act)
corr_text.set_text(corr)
return tuple(lines) + (act_text, corr_text)
end = 20
N = 200
x = np.linspace(0, end, N)
y1 = np.sin(x)
y2 = 1 + np.sin(1.1 * x)
fig = plt.figure(figsize=(14, 8))
ax = plt.axes(xlim=(-1, 21), ylim=(-2, 3.8))
lines = [plt.plot([], [])[0], plt.plot([], [])[0]]
params = {"fontsize": 24, "transform": ax.transAxes, "horizontalalignment": "center", "verticalalignment": "top"}
ax.text(0.15, 0.97, "\u0332".join("Mean"), **params)
ax.text(0.40, 0.97, "\u0332".join("Pearson"), **params)
params["horizontalalignment"] = "left"
act_text = ax.text(0.05, 0.90, "", **params)
corr_text = ax.text(0.35, 0.94, "", **params)
ax.tick_params(axis='both', which='major', labelsize=18)
ax.tick_params(axis='both', which='minor', labelsize=16)
pears, y1s, y2s = [], [], []
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=tqdm(range(100)), interval=20, blit=True)
anim.save("noise_simulation.mp4", fps=30, extra_args=['-vcodec', 'libx264']);