Спектрограмма: спектральные изменения звука во времени

Машинное обучение для данных временных рядов на Python

Chris Holdgraf

Fellow, Berkeley Institute for Data Science

Преобразования Фурье

  • Временны́е ряды можно описать как сочетание быстро- и медленноменяющихся компонентов
  • В каждый момент времени можно оценить относительный вклад быстрых и медленных составляющих
  • Простейший способ сделать это — преобразование Фурье
  • Оно преобразует один временно́й ряд в массив, описывающий его как комбинацию колебаний
Машинное обучение для данных временных рядов на Python

Преобразование Фурье (FFT)

Машинное обучение для данных временных рядов на Python

Спектрограммы: комбинации оконных преобразований Фурье

  • Спектрограмма — это набор оконных преобразований Фурье, вычисленных последовательно во времени
  • Принцип аналогичен скользящему среднему:
    1. Выберите размер и форму окна
    2. В каждой временно́й точке вычислите FFT для этого окна
    3. Сдвиньте окно на один шаг
    4. Агрегируйте результаты
  • Называется краткосрочным преобразованием Фурье (STFT)
Машинное обучение для данных временных рядов на Python

Машинное обучение для данных временных рядов на Python

Вычисление STFT

  • Вычислить STFT можно с помощью librosa
  • Доступны различные параметры настройки (например, размер окна)
  • Для удобства преобразуем значения в децибелы — это нормализует средние значения всех частот
  • Визуализировать результат можно с помощью функции specshow()
Машинное обучение для данных временных рядов на Python

Вычисление STFT в коде

# 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)
Машинное обучение для данных временных рядов на Python

Конструирование спектральных признаков

  • Каждый временно́й ряд обладает уникальным спектральным паттерном.
  • Эти паттерны можно извлечь, анализируя спектрограмму.
  • Например, спектральная ширина полосы и спектральные центроиды показывают, где сосредоточена основная энергия в каждый момент времени

Машинное обучение для данных временных рядов на Python

Вычисление спектральных признаков

# 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)
Машинное обучение для данных временных рядов на Python

Объединение спектральных и временны́х признаков в классификаторе

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])
Машинное обучение для данных временных рядов на Python

Давайте потренируемся!

Машинное обучение для данных временных рядов на Python

Preparing Video For Download...