Het spectrogram - spectrale veranderingen van geluid in de tijd

Machine Learning voor tijdreeksgegevens in Python

Chris Holdgraf

Fellow, Berkeley Institute for Data Science

Fourier-transformaties

  • Tijdreeksdata kun je zien als een mix van snel en langzaam veranderende dingen
  • Op elk moment kun je de relatieve aanwezigheid van snelle en trage componenten beschrijven
  • De eenvoudigste manier hiervoor heet een Fourier-transformatie
  • Daarmee zet je één tijdreeks om in een array die de reeks beschrijft als een combinatie van oscillaties
Machine Learning voor tijdreeksgegevens in Python

Een Fourier-transformatie (FFT)

Machine Learning voor tijdreeksgegevens in Python

Spectrogrammen: combinaties van venster-FFT's

  • Een spectrogram is een verzameling van venster-FFT's over de tijd
  • Vergelijkbaar met hoe je een rollend gemiddelde berekent:
    1. Kies een venstergrootte en -vorm
    2. Bereken op een tijdpunt de FFT voor dat venster
    3. Schuif het venster één stap op
    4. Agregeer de resultaten
  • Dit heet een Short-Time Fourier Transform (STFT)
Machine Learning voor tijdreeksgegevens in Python

Machine Learning voor tijdreeksgegevens in Python

De STFT berekenen

  • We kunnen de STFT berekenen met librosa
  • Er zijn meerdere parameters die je kunt afstellen (zoals venstergrootte)
  • Voor ons doel zetten we om naar decibel, wat de gemiddelde waarden over alle frequenties normaliseert
  • Daarna kun je het visualiseren met de functie specshow()
Machine Learning voor tijdreeksgegevens in Python

De STFT berekenen met code

# Import the functions we'll use for the STFT
from librosa.core import stft, amplitude_to_db
from librosa.display import specshow
import matplotlib.pyplot as plt

# Calculate our STFT
HOP_LENGTH = 2**4
SIZE_WINDOW = 2**7
audio_spec = stft(audio, hop_length=HOP_LENGTH, n_fft=SIZE_WINDOW)

# Convert into decibels for visualization
spec_db = amplitude_to_db(audio_spec)

# Visualize
fig, ax = plt.subplots()
specshow(spec_db, sr=sfreq, x_axis='time', 
         y_axis='hz', hop_length=HOP_LENGTH, ax=ax)
Machine Learning voor tijdreeksgegevens in Python

Spectrale feature engineering

  • Elke tijdreeks heeft een eigen spectraal patroon.
  • We kunnen die patronen berekenen door het spectrogram te analyseren.
  • Zo beschrijven spectral bandwidth en spectral centroids waar op elk moment de meeste energie zit

Machine Learning voor tijdreeksgegevens in Python

Spectrale features berekenen

# Calculate the spectral centroid and bandwidth for the spectrogram
bandwidths = lr.feature.spectral_bandwidth(S=spec)[0]
centroids = lr.feature.spectral_centroid(S=spec)[0]

# Display these features on top of the spectrogram
fig, ax = plt.subplots()
specshow(spec, x_axis='time', y_axis='hz', hop_length=HOP_LENGTH, ax=ax)
ax.plot(times_spec, centroids)
ax.fill_between(times_spec, centroids - bandwidths / 2, 
                centroids + bandwidths / 2, alpha=0.5)
Machine Learning voor tijdreeksgegevens in Python

Spectrale en temporele features combineren in een classifier

centroids_all = []
bandwidths_all = []
for spec in spectrograms:
    bandwidths = lr.feature.spectral_bandwidth(S=lr.db_to_amplitude(spec))
    centroids = lr.feature.spectral_centroid(S=lr.db_to_amplitude(spec))
    # Calculate the mean spectral bandwidth
    bandwidths_all.append(np.mean(bandwidths))  
    # Calculate the mean spectral centroid
    centroids_all.append(np.mean(centroids))  

# Create our X matrix
X = np.column_stack([means, stds, maxs, tempo_mean, 
                     tempo_max, tempo_std, bandwidths_all, centroids_all])
Machine Learning voor tijdreeksgegevens in Python

Laten we oefenen!

Machine Learning voor tijdreeksgegevens in Python

Preparing Video For Download...