Assignment Chef icon Assignment Chef
All German tutorials

Programming lesson

Extraktion von Audio-Merkmalen mit Python: Eine Schritt-für-Schritt-Anleitung für CS 4347

Lerne, wie du Musik- und Sprachdateien analysierst, Zeit- und Frequenzbereichsmerkmale extrahierst und eine ARFF-Datei für maschinelles Lernen erstellst. Dieses Tutorial folgt den Vorgaben der CS 4347 Assignments 1–4 und eignet sich perfekt für Studierende der Datenwissenschaft und Audioverarbeitung

Audio-Merkmale extrahieren Python CS 4347 Assignment Lösung Music Speech Dataset Analyse RMS und ZCR berechnen Spectral Centroid Roll-Off Flatness MFCCs mit Python berechnen ARFF Datei erstellen Python Audioverarbeitung Studium Maschinelles Lernen Audio Musik Sprache Klassifikation Hamming Fenster Python FFT in Python Signalverarbeitung Python Tutorial Weka ARFF Format KI Audio Analyse 2026 Datenwissenschaft Audio

Einführung in die Audio-Merkmal-Extraktion

Die Analyse von Audiosignalen ist ein zentraler Bestandteil des maschinellen Lernens und der Signalverarbeitung. In diesem Tutorial lernst du, wie du mit Python Musik- und Sprachdateien verarbeitest, um charakteristische Merkmale zu extrahieren. Diese Merkmale werden später für Klassifikationsaufgaben wie die Unterscheidung von Musik und Sprache genutzt. Der hier beschriebene Workflow orientiert sich an den CS 4347 Assignments 1–4 und verwendet den bekannten Music & Speech Dataset von Marsyas.

Aktuelle Entwicklungen in der KI, wie Sprachassistenten (Siri, Alexa) oder Musikempfehlungssysteme (Spotify), basieren auf ähnlichen Techniken. Selbst in der Finanzwelt werden Audio-Merkmale zur Analyse von Kundenanrufen eingesetzt. Dieses Tutorial vermittelt dir die Grundlagen, um solche Systeme zu verstehen und eigene Lösungen zu entwickeln.

Warum ist die Extraktion von Audio-Merkmalen wichtig?

Rohdaten in Form von Wellenformen sind für maschinelle Lernmodelle oft zu komplex. Durch die Berechnung von Merkmalen wie RMS, Zero Crossing Rate oder MFCCs reduzierst du die Dimensionalität und extrahierst relevante Informationen. Diese Merkmale dienen als Eingabe für Klassifikatoren wie Support Vector Machines oder neuronale Netze. In der Praxis werden solche Merkmale auch in der Musikindustrie zur automatischen Genreklassifikation oder in der Medizin zur Spracherkennung eingesetzt.

Schritt 1: Einrichtung der Umgebung und Datenvorbereitung

Bevor du mit der Programmierung beginnst, stelle sicher, dass du die benötigten Bibliotheken installiert hast: numpy, scipy und matplotlib. Diese sind für die CS 4347 Assignments zugelassen. Lade den Music & Speech Dataset von der angegebenen URL herunter und entpacke ihn. Lösche die Ordner music/ und speech/ und verwende die Dateien in music-wav/ und speech-wav/. Jede Datei enthält 30 Sekunden Audio mit 16-Bit signed integers bei 22050 Hz.

import numpy as np
import scipy.io.wavfile as wav
import scipy.signal.windows as windows
from scipy.fft import fft
import os

# Ground-Truth-Datei einlesen
gt_file = 'music_speech.mf'
labels = {}
with open(gt_file, 'r') as f:
    for line in f:
        parts = line.strip().split('\t')
        if len(parts) == 2:
            labels[parts[0]] = parts[1]

Schritt 2: Zeitbereichsmerkmale berechnen

Die Zeitbereichsmerkmale werden für jeden Buffer (Block) der Länge 1024 mit 50% Überlappung berechnet. Für jeden Buffer werden der Root-Mean-Square (RMS) und die Zero Crossing Rate (ZCR) ermittelt. Anschließend werden Mittelwert und unkorrigierte Standardabweichung über alle Buffer einer Datei berechnet.

RMS und ZCR verstehen

Der RMS-Wert gibt die durchschnittliche Energie des Signals an – ähnlich wie die Lautstärke in einem Song. Die Zero Crossing Rate zählt, wie oft das Signal das Vorzeichen wechselt, und ist ein Indikator für die Rauigkeit des Signals. Musik hat oft eine niedrigere ZCR als Sprache, da Sprache mehr hochfrequente Anteile besitzt.

def compute_time_features(data, buffer_size=1024, hop_size=512):
    num_buffers = (len(data) - buffer_size) // hop_size + 1
    rms_list = []
    zcr_list = []
    for i in range(num_buffers):
        start = i * hop_size
        end = start + buffer_size
        buffer = data[start:end]
        # RMS
        rms = np.sqrt(np.mean(buffer**2))
        rms_list.append(rms)
        # ZCR
        zcr = np.sum(np.abs(np.diff(np.sign(buffer)))) / (2 * buffer_size)
        zcr_list.append(zcr)
    return np.mean(rms_list), np.std(rms_list, ddof=0), np.mean(zcr_list), np.std(zcr_list, ddof=0)

Schritt 3: Frequenzbereichsmerkmale extrahieren

Für die Frequenzbereichsmerkmale wird jeder Buffer zuerst mit einem Hamming-Fenster multipliziert, um Spektraleffekte zu minimieren. Dann wird die diskrete Fourier-Transformation (DFT) durchgeführt. Es werden nur die positiven Frequenzen bis zur Nyquist-Frequenz (N/2) verwendet. Aus dem Spektrum werden drei Merkmale berechnet: Spectral Centroid, Spectral Roll-Off und Spectral Flatness Measure.

Praktische Anwendung: Musik- vs. Spracherkennung

Stell dir vor, du entwickelst eine App, die automatisch erkennt, ob ein Podcast gerade Musik oder Sprache enthält. Die Spectral Flatness kann dabei helfen: Rauschen (wie in Sprache) hat eine hohe Flatness, während Musik mit ausgeprägten Harmonischen eine niedrige Flatness aufweist. Der Spectral Centroid gibt die „Helligkeit“ des Klangs an – Sprache hat oft einen höheren Centroid als Musik.

def compute_freq_features(buffer, sr=22050):
    windowed = buffer * windows.hamming(len(buffer))
    spectrum = fft(windowed)
    # Nur positive Frequenzen (0 bis N/2)
    N = len(spectrum)
    mag = np.abs(spectrum[:N//2])
    # Spectral Centroid
    freqs = np.linspace(0, sr/2, N//2)
    centroid = np.sum(freqs * mag) / np.sum(mag)
    # Spectral Roll-Off (85%)
    cumsum = np.cumsum(mag)
    rolloff = np.where(cumsum >= 0.85 * cumsum[-1])[0][0]
    # Spectral Flatness
    geometric_mean = np.exp(np.mean(np.log(mag + 1e-10)))
    arithmetic_mean = np.mean(mag)
    flatness = geometric_mean / arithmetic_mean
    return centroid, rolloff, flatness

Schritt 4: ARFF-Datei erstellen

Die extrahierten Merkmale werden in eine ARFF-Datei geschrieben, die für maschinelles Lernen in Weka oder anderen Tools verwendet werden kann. Die ARFF-Datei enthält einen Header mit den Attributnamen und die Datenzeilen. Jede Zeile repräsentiert eine Audiodatei mit den Mittelwerten und Standardabweichungen der Merkmale sowie der Klasse (music oder speech).

def write_arff(results, output_file='results.arff'):
    with open(output_file, 'w') as f:
        f.write('@RELATION music_speech\n')
        f.write('@ATTRIBUTE RMS_MEAN NUMERIC\n')
        f.write('@ATTRIBUTE ZCR_MEAN NUMERIC\n')
        f.write('@ATTRIBUTE SC_MEAN NUMERIC\n')
        f.write('@ATTRIBUTE SRO_MEAN NUMERIC\n')
        f.write('@ATTRIBUTE SFM_MEAN NUMERIC\n')
        f.write('@ATTRIBUTE RMS_STD NUMERIC\n')
        f.write('@ATTRIBUTE ZCR_STD NUMERIC\n')
        f.write('@ATTRIBUTE SC_STD NUMERIC\n')
        f.write('@ATTRIBUTE SRO_STD NUMERIC\n')
        f.write('@ATTRIBUTE SFM_STD NUMERIC\n')
        f.write('@ATTRIBUTE class {music,speech}\n')
        f.write('@DATA\n')
        for row in results:
            f.write(','.join(f'{v:.6f}' for v in row[:-1]) + f',{row[-1]}\n')

Schritt 5: MFCCs berechnen (Assignment 2)

In Assignment 2 werden Mel-Frequenz-Cepstral-Koeffizienten (MFCCs) berechnet. Diese sind besonders nützlich für die Spracherkennung. Der Prozess umfasst eine Pre-Emphasis-Filterung, Fensterung, DFT, Mel-Filterbank und DCT. Für jeden Buffer werden 26 MFCCs berechnet, dann über alle Buffer gemittelt und die Standardabweichung ermittelt.

MFCCs und ihre Bedeutung

MFCCs simulieren das menschliche Gehör, das bei tiefen Frequenzen empfindlicher ist. Sie sind der Standard in der Sprachverarbeitung und werden auch in der Musikanalyse eingesetzt. In der Finanzbranche werden MFCCs genutzt, um Handelsgespräche zu analysieren.

def compute_mfcc(data, sr=22050, n_mfcc=26):
    # Pre-emphasis
    emphasized = np.append(data[0], data[1:] - 0.95 * data[:-1])
    # Framing mit Hamming-Fenster
    frames = []
    for i in range(0, len(emphasized)-1024+1, 512):
        frame = emphasized[i:i+1024] * windows.hamming(1024)
        frames.append(frame)
    # DFT und Mel-Filter
    mel_filter = create_mel_filterbank(sr, 1024, 26)
    mfccs = []
    for frame in frames:
        spectrum = np.abs(fft(frame)[:512])
        mel_energy = np.dot(mel_filter, spectrum)
        log_energy = np.log10(mel_energy + 1e-10)
        mfcc = scipy.fftpack.dct(log_energy, type=2, norm='ortho')
        mfccs.append(mfcc)
    mfccs = np.array(mfccs)
    means = np.mean(mfccs, axis=0)
    stds = np.std(mfccs, axis=0, ddof=0)
    return np.concatenate([means, stds])

Schritt 6: Visualisierung der Filter

Um die Filter zu verstehen, kannst du die Dreiecksfilter plotten. Dies hilft, die Mel-Skalierung zu visualisieren. Die Plots zeigen den gesamten Frequenzbereich und eine Vergrößerung von 0–300 Hz.

import matplotlib.pyplot as plt

def plot_filters(mel_filter, sr, n_fft):
    freqs = np.linspace(0, sr/2, n_fft//2)
    plt.figure(figsize=(10,4))
    for i in range(mel_filter.shape[0]):
        plt.plot(freqs, mel_filter[i])
    plt.xlabel('Frequenz (Hz)')
    plt.ylabel('Amplitude')
    plt.title('Mel-Filterbank (0-11025 Hz)')
    plt.savefig('mel_filters_full.png')
    plt.figure(figsize=(10,4))
    for i in range(mel_filter.shape[0]):
        plt.plot(freqs[:150], mel_filter[i,:150])
    plt.xlabel('Frequenz (Hz)')
    plt.ylabel('Amplitude')
    plt.title('Mel-Filterbank (0-300 Hz)')
    plt.savefig('mel_filters_zoom.png')

Zusammenfassung und nächste Schritte

In diesem Tutorial hast du gelernt, wie du aus Audiodateien Zeit- und Frequenzbereichsmerkmale sowie MFCCs extrahierst. Diese Merkmale sind essentiell für die Klassifikation von Musik und Sprache. Mit dem erstellten ARFF-Datei kannst du nun maschinelles Lernen anwenden, zum Beispiel mit Weka oder scikit-learn.

Für die Abgabe der CS 4347 Assignments 1–4 musst du deinen Python-Code und die ARFF-Datei als ZIP-Datei einreichen. Achte darauf, dass dein Code gut dokumentiert ist und die geforderten Ausgaben (6 Nachkommastellen) enthält. Viel Erfolg!

„Die Extraktion von Audio-Merkmalen ist der erste Schritt, um Maschinen das Hören beizubringen – eine Fähigkeit, die in der heutigen KI-Welt unverzichtbar ist.“