Procesamiento de audio es uno de los dominios de aplicación más importantes del procesamiento de señales digitales (DSP) y el aprendizaje automático. El modelado de entornos acústicos es un paso esencial para desarrollar sistemas de procesamiento de audio digital como: reconocimiento de voz, mejora del habla, cancelación de eco acústico, etc.

Los entornos acústicos están llenos de ruido de fondo que puede tener múltiples fuentes. Por ejemplo, cuando se sienta en una cafetería, camina por la calle o conduce su automóvil, escucha sonidos que pueden considerarse como interferencia o ruido de fondo. Dichas interferencias no necesariamente siguen el mismo modelo estadístico y, por lo tanto, una mezcla de modelos puede ser útil para modelarlos.

Esos modelos estadísticos también pueden ser útiles para clasificar los entornos acústicos en diferentes categorías, por ejemplo, un auditorio tranquilo (clase 1) o una habitación ligeramente más ruidosa con ventanas cerradas (clase 2) y una tercera opción con Windows Open (Clase 3). En cada caso, el nivel de ruido de fondo se puede modelar utilizando una mezcla de fuentes de ruido, cada una con una probabilidad diferente y con un nivel acústico diferente.

Otra aplicación de tales modelos está en la simulación del ruido acústico en diferentes entornos en función de los cuales las soluciones de aprendizaje DSP y de aprendizaje automático pueden diseñarse para resolver problemas acústicos específicos en sistemas de audio prácticos, como la cancelación de interferencia, la cancelación de eco, el reconocimiento del habla, la mejora del habla, etc. .

Foto Matoo.studio en Sin estelares

Un modelo estadístico simple que puede ser útil en tales escenarios es el Modelo de mezcla gaussiana (GMM) en el que se supone que cada una de las diferentes fuentes de ruido sigue una distribución gaussiana específica con una cierta varianza. Se puede suponer que todas las distribuciones tienen una media cero y aún son suficientemente precisas para esta aplicación, como también se muestra en esta artículo.

Cada una de las distribuciones GMM tiene su propia probabilidad de contribuir al ruido de fondo. Por ejemplo, podría haber un ruido de fondo consistente que ocurre la mayor parte del tiempo, mientras que otras fuentes pueden ser intermitentes, como el ruido que viene a través de Windows, etc. Todo esto debe considerarse en nuestro modelo estadístico.

En la figura a continuación se muestra un ejemplo de datos de GMM simulados (normalizados al tiempo de muestreo) en la figura a continuación en la que hay dos fuentes de ruido gaussianas, ambas de media pero con dos variaciones diferentes. En este ejemplo, la señal de varianza más baja ocurre con mayor frecuencia con una probabilidad del 90%, por lo tanto, los picos intermitentes en los datos generados que representan la señal con mayor varianza.

En otros escenarios y dependiendo de la aplicación, podría ser el otro lado en el que la señal de ruido de alta varianza ocurre con más frecuencia (como se mostrará en un ejemplo posterior en este artículo). Pitón El código utilizado para generar y analizar datos GMM también se mostrará más adelante en este artículo.

En cuanto a un lenguaje de modelado más formal, supongamos que la señal de ruido de fondo que se recopila (usando un micrófono de alta calidad, por ejemplo) se modela como realizaciones de variables aleatorias independientes e idénticamente distribuidas (IID) que siguen un GMM como se muestra a continuación.

El problema de modelado se reduce a estimar los parámetros del modelo (es decir, P1, σ²1 y σ²2) utilizando los datos observados (IID). En este artículo, usaremos el Método de momentos (Mamá) Estimador para tal propósito.

Para simplificar aún más las cosas, podemos suponer que se conocen las variaciones de ruido (σ²1 y σ²2) y que solo se estimará el parámetro de mezcla (P1). El estimador de MOM se puede usar para estimar más de un parámetro (es decir, P1, σ²1 y σ²2) como se muestra en el Capítulo 9 del libro: «Procesamiento de señales estadísticas: teoría de la estimación ”, por Steven Kay. Sin embargo, en este ejemplo, asumiremos que solo P1 es desconocido y se estimará.

Dado que ambos gaussianos en el GMM son media cero, comenzaremos con el segundo momento e intentaremos obtener el parámetro desconocido P1 en función del segundo momento como sigue.

Tenga en cuenta que otro método simple para obtener los momentos de una variable aleatoria (por ejemplo, segundo o superior) es mediante el uso de la función de generación de momento (MGF). Un buen libro de texto en teoría de probabilidad que cubre tales temas, y más es: «Introducción a la probabilidad de ciencia de datos«, Por Stanley H. Chan.

Antes de continuar, nos gustaría cuantificar este estimador en términos de las propiedades fundamentales de los estimadores como el sesgo, la varianza, la consistencia, etc. Verificaremos esto más tarde numéricamente con un ejemplo de Python.

Comenzando con el sesgo estimador, podemos mostrar que el estimador anterior de P1 es imparcial de la siguiente manera.

Luego podemos proceder a derivar la varianza de nuestro estimador de la siguiente manera.

También está claro en el análisis anterior que el estimador es consistente ya que es imparcial y también su varianza disminuye cuando el tamaño de la muestra (N) aumenta. También utilizaremos la fórmula anterior de la varianza del estimador P1 en nuestro ejemplo numérico de Python (que se muestra en detalle más adelante en este artículo) al comparar la teoría con resultados numéricos prácticos.

¡Ahora presentemos un código de Python y hagamos algunas cosas divertidas!

Primero, generamos nuestros datos que siguen un GMM con medias cero y desviaciones estándar igual a 2 y 10, respectivamente, como se muestra en el código a continuación. En este ejemplo, el parámetro de mezcla P1 = 0.2, y el tamaño de la muestra de los datos equivalen a 1000.

# Import the Python libraries that we will need in this GMM example
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

# GMM data generation
mu = 0 # both gaussians in GMM are zero mean
sigma_1 = 2 # std dev of the first gaussian
sigma_2 = 10 # std dev of the second gaussian
norm_params = np.array([[mu, sigma_1],
                        [mu, sigma_2]])
sample_size = 1000
p1 = 0.2 # probability that the data point comes from first gaussian
mixing_prob = [p1, (1-p1)]
# A stream of indices from which to choose the component
GMM_idx = np.random.choice(len(mixing_prob), size=sample_size, replace=True, 
                p=mixing_prob)
# GMM_data is the GMM sample data
GMM_data = np.fromiter((stats.norm.rvs(*(norm_params[i])) for i in GMM_idx),
                   dtype=np.float64)

Luego trazamos el histograma de los datos generados versus la función de densidad de probabilidad como se muestra a continuación. La figura muestra la contribución de ambas densidades gaussianas en el GMM general, con cada densidad escalada por su factor correspondiente.

El código de Python utilizado para generar la figura anterior se muestra a continuación.

x1 = np.linspace(GMM_data.min(), GMM_data.max(), sample_size)
y1 = np.zeros_like(x1)

# GMM probability distribution
for (l, s), w in zip(norm_params, mixing_prob):
    y1 += stats.norm.pdf(x1, loc=l, scale=s) * w

# Plot the GMM probability distribution versus the data histogram
fig1, ax = plt.subplots()
ax.hist(GMM_data, bins=50, density=True, label="GMM data histogram", 
        color = GRAY9)
ax.plot(x1, p1*stats.norm(loc=mu, scale=sigma_1).pdf(x1),
        label="p1 × first PDF",color = GREEN1,linewidth=3.0)
ax.plot(x1, (1-p1)*stats.norm(loc=mu, scale=sigma_2).pdf(x1),
        label="(1-p1) × second PDF",color = ORANGE1,linewidth=3.0)
ax.plot(x1, y1, label="GMM distribution (PDF)",color = BLUE2,linewidth=3.0)

ax.set_title("Data histogram vs. true distribution", fontsize=14, loc="left")
ax.set_xlabel('Data value')
ax.set_ylabel('Probability')
ax.legend()
ax.grid()

Después de eso, calculamos la estimación del parámetro de mezcla P1 que derivamos anteriormente usando MOM y que se muestra aquí nuevamente a continuación como referencia.

El código Python utilizado para calcular la ecuación anterior utilizando nuestros datos de muestra GMM se muestra a continuación.

# Estimate the mixing parameter p1 from the sample data using MoM estimator
p1_hat = (sum(pow(x,2) for x in GMM_data) / len(GMM_data) - pow(sigma_2,2))
         /(pow(sigma_1,2) - pow(sigma_2,2))

Para evaluar adecuadamente este estimador, usamos Monte Carlo Simulación generando múltiples realizaciones de los datos GMM y estimar P1 para cada realización como se muestra en el código de Python a continuación.

# Monte Carlo simulation of the MoM estimator
num_monte_carlo_iterations = 500
p1_est = np.zeros((num_monte_carlo_iterations,1))

sample_size = 1000
p1 = 0.2 # probability that the data point comes from first gaussian
mixing_prob = [p1, (1-p1)]
# A stream of indices from which to choose the component
GMM_idx = np.random.choice(len(mixing_prob), size=sample_size, replace=True, 
          p=mixing_prob)
for iteration in range(num_monte_carlo_iterations):
  sample_data = np.fromiter((stats.norm.rvs(*(norm_params[i])) for i in GMM_idx))
  p1_est[iteration] = (sum(pow(x,2) for x in sample_data)/len(sample_data) 
                       - pow(sigma_2,2))/(pow(sigma_1,2) - pow(sigma_2,2))

Luego, verificamos el sesgo y la varianza de nuestro estimador y comparamos con los resultados teóricos que derivamos anteriormente como se muestra a continuación.

p1_est_mean = np.mean(p1_est)
p1_est_var = np.sum((p1_est-p1_est_mean)**2)/num_monte_carlo_iterations
p1_theoritical_var_num = 3*p1*pow(sigma_1,4) + 3*(1-p1)*pow(sigma_2,4) 
                         - pow(p1*pow(sigma_1,2) + (1-p1)*pow(sigma_2,2),2)
p1_theoritical_var_den = sample_size*pow(sigma_1**2-sigma_2**2,2)
p1_theoritical_var = p1_theoritical_var_num/p1_theoritical_var_den
print('Sample variance of MoM estimator of p1 = %.6f' % p1_est_var)
print('Theoretical variance of MoM estimator of p1 = %.6f' % p1_theoritical_var)
print('Mean of MoM estimator of p1 = %.6f' % p1_est_mean)

# Below are the results of the above code
Sample variance of MoM estimator of p1 = 0.001876
Theoretical variance of MoM estimator of p1 = 0.001897
Mean of MoM estimator of p1 = 0.205141

Podemos observar de los resultados anteriores que la media de la estimación de P1 es igual a 0.2051, que está muy cerca del parámetro verdadero P1 = 0.2. Esta media se acerca aún más al parámetro verdadero a medida que aumenta el tamaño de la muestra. Por lo tanto, hemos demostrado numéricamente que el estimador es imparcial como lo confirma los resultados teóricos realizados anteriormente.

Además, la varianza de muestra del estimador P1 (0.001876) es casi idéntica a la varianza teórica (0.001897) que es hermosa.

¡Siempre es un momento feliz cuando la teoría coincide con la práctica!

Todas las imágenes en este artículo, a menos que se indique lo contrario, son del autor.

Por automata