Tineler
Tineler

Reputation: 253

Power spectral density of real accelerometer data shows outlier at 0 Hz

I've gathered accelerometer data with a frequency of approx 50 Hz (every 0.02 sec., as exactly as Android allows it...)

Here is the plot of the magnitudes of a 10 second window of the data, on which I want to estimate power spectral density:

Magnitudes of accelerometer data

After applying scipy.signal.periodogram like this

fs = 50
f, Pxx_den = signal.periodogram(x, fs)
plt.semilogy(f, Pxx_den)
plt.show()

I get the following plot, showing an outliner at 0 Hz: enter image description here

Is this outliner expected? I would like to feed a Machine Learning algorithm with the 3 highest PSDs but having the outliner at 0 makes me think, that something went wrong. Or is this not the case? Applying FFT also leads to a high amplitude at 0 Hz.

Upvotes: 1

Views: 1344

Answers (1)

bnaecker
bnaecker

Reputation: 6430

This is due to the detrending that signal.periodigram does by default.

Detrending is removing a constant or linear term (usually) from the data, defaulting to a constant-detrend. This is effectively subtracting the mean in each section of data over which the PSD is estimated. Subtracting the mean is equivalent to removing the DC or zero-frequency component from the spectrum.

I generated fake data, just Gaussian noise, with a y-offset of 5, similar to that of your data. You can see from the plot below that detrending removes the zero-frequency component, while setting detrend=False keeps it. Keep in mind, however, that detrending may actually be useful. You may or may not care about that, depending on what type of analysis you're interested in.

from scipy import signal
import numpy as np
import matplotlib.pyplot as plt

x = np.random.randn(1000,) * 2.0 + 5.0 # White noise data, with y-offset
fs = 50.0
f, detrended_psd = signal.periodogram(x, fs)
_, psd = signal.periodogram(x, fs, detrend=False)
fig, ax = plt.subplots()
ax.semilogy(f, detrended_psd, linewidth=3.0, label='Detrended')
ax.semilogy(f, psd, linewidth=1.0, label='Not detrended')
fig.tight_layout()
ax.set_xlabel('Frequency (Hz)')
ax.set_ylabel('PSD')

enter image description here

Upvotes: 4

Related Questions