ICA e il problema delle feste cocktail nella vita reale

ICA e il dilemma dei cocktail party nella vita reale

Perché l’Analisi dei Componenti Indipendenti fallisce il suo esperimento mentale canonico e cosa possiamo imparare da questo fallimento.

Una metafora del cocktail party (Immagine dell'autore)

L’Analisi dei Componenti Indipendenti (ICA) è diventata una tecnica comune di decomposizione e pre-elaborazione dei dati dai significativi sviluppi degli anni ’90¹. ICA è un metodo di separazione delle sorgenti cieche (BSS): alcune sorgenti indipendenti vengono mescolate in modo cieco e i segnali risultanti del mix sono ricevuti da un certo numero di osservatori. Gli approcci ICA lavorano per scomporre i segnali osservati e trovare sorgenti indipendenti cercando un cambio di base che minimizzi l’informazione reciproca tra i componenti scomposti o che massimizzi la “non gaussianità” dei dati proiettati su quei componenti.

Ci sono già molti tutorial disponibili su ICA e la sua applicazione: questo articolo non è un’altra introduzione a ICA. Invece, è un commento sul problema motivante che quasi sempre accompagna le spiegazioni di ICA.

Ogni introduzione a ICA utilizza il Problema del Cocktail Party come illustrazione del problema BSS che ICA è destinato a risolvere.² Il Problema del Cocktail Party è un esperimento mentale evocativo e motivante per ICA. C’è solo un piccolo problema: ICA fallirà spettacolarmente in un vero cocktail party e le ragioni per cui fallirà dovrebbero veramente influenzare il modo in cui ICA viene applicato.

ICA e il Cocktail Party

Una stanza affollata. Gruppi di persone in festa – cocktail in mano – parlano contemporaneamente in conversazione. Come possono gli ascoltatori separare il chiacchiericcio misto in voci distinte e magari concentrarsi su un singolo oratore? Questo è il contesto del Problema del Cocktail Party, l’esempio canonico usato per introdurre ICA. Immaginiamo che diversi microfoni siano posizionati in diverse parti della stanza. ICA, si dice, ci rivela come scomporre i segnali registrati in componenti indipendenti rappresentativi di oratori distinti alla festa.

Il problema BSS è formulato da un problema di miscelazione in cui alcune sorgenti indipendenti y vengono mischiate in segnali osservati x

per N campioni temporali. A è una matrice di miscelazione e le sorgenti e osservazioni sono indicate con j e i. Per le poche equazioni incluse in questo articolo, sto usando la notazione di sommatoria di Einstein.

Il modulo di decomposizione di Scikit-learn include una buona implementazione pronta all’uso di FastICA, che possiamo usare per illustrare come funziona in un esempio a bassa dimensionalità. Creeremo alcune sorgenti indipendenti costituite da sinusoidi con fase sfasata che oscillano a diverse frequenze, le misceleremo casualmente e poi applicheremo FastICA per cercare di scomporle. Quello che vediamo è che, a parte la scala, il segno e la permutazione, FastICA fa un buon lavoro nel recuperare i segnali originali delle sorgenti (e quindi, in un problema fisico in cui conosciamo la posizione dei microfoni, potremmo recuperare la direzione/posizione degli oratori).

import numpy as npfrom sklearn.decomposition import FastICAimport matplotlib.pyplot as pltrng = np.random.default_rng(8675309)t = np.linspace(0, 10, 10000)x = np.array([    np.sin(2 * np.pi * t),     np.sin(2 * np.pi / 2 * t + 1),     np.sin(2 * np.pi / 2 * 2 * t + 2)])mixing = rng.uniform(-1, 1, [3, 3])# verifichiamo che la miscelazione generata casualmente sia invertibileassert np.linalg.matrix_rank(mixing) == 3demixing_true = np.linalg.inv(mixing)y = np.matmul(mixing, x)fica = FastICA(3)z = fica.fit_transform(np.transpose(y))z = np.transpose(z)z /= np.reshape(np.max(z, 1), (3, 1))fig, ax = plt.subplots(3, 1, figsize = (8, 5))for ii in range(3):    ax[0].plot(t, x[ii])    ax[1].plot(t, y[ii])    ax[2].plot(t, z[ii])ax[0].set_title("Sorgenti Indipendenti")ax[1].set_title("Segnali Mischiati Casualmente e Linearmente")ax[2].set_title("Componenti ICA (Corrispondenti a Segno e Scaling Lineare)")plt.tight_layout()
FastICA per segnali istantaneamente misti

Enumeriamo alcune delle ipotesi del modello della festa in stile cocktail:

  • Nel locale della festa in stile cocktail, supponiamo che ci siano più osservatori (es. microfoni) rispetto alle fonti (es. altoparlanti), che è una condizione necessaria affinché il problema non sia sotto-determinato.
  • Le fonti sono indipendenti e non distribuite normalmente.
  • A è una matrice costante: la miscelazione è istantanea e immutabile.

Il problema BSS è “cieco”, quindi notiamo che le fonti y e la miscelazione A sono sconosciute e cerchiamo una matrice chiamata matrice di demiscelazione W, che è una generalizzazione dell’inversa di A. Gli algoritmi ICA sono strategie per derivare W.

Pronto per la miscelazione (Immagine dell'autore)

Una festa di cocktail nella vita reale

Cosa succederebbe se allestissimo effettivamente un’array di microfoni durante una festa e provassimo a eseguire un’ICA su un audio registrato? Succede che l’ICA “out-of-the-box” fallirà quasi certamente miseramente nel separare gli altoparlanti!

Rivisitiamo una delle ipotesi del nostro modello: nello specifico la miscelazione istantanea. A causa della velocità finita del suono, l’audio che proviene dai punti degli altoparlanti arriverà a ciascun microfono nella stanza con ritardi temporali diversi.

La velocità del suono è di circa 343 m/s alla festa, quindi un microfono distante 10 m da un altoparlante registrerà un ritardo di circa 0,03 secondi. Sebbene questo possa sembrare quasi istantaneo per un essere umano alla festa, per una registrazione dell’ordine di 10 kHz ciò si traduce in un ritardo di centinaia di campioni digitali.

Provate a fornire questa miscela “cieca” di altoparlanti con ritardi temporali all’ICA “vanilla” e i risultati non saranno belli. Ma aspettate un attimo, ci sono esempi di ICA utilizzata per demiscelare audio⁴? Sì, ma questi problemi di esempio sono miscelati digitalmente e istantaneamente e pertanto sono coerenti con le ipotesi modello dell’ICA. Le registrazioni del mondo reale sono soggette non solo a ritardi temporali, ma anche a trasformazioni temporali più complesse (di questo parleremo più avanti).

Possiamo riprendere il nostro esempio di esempio sopra e introdurre un ritardo casuale tra le fonti e i microfoni di registrazione per vedere come FastICA comincia a decadere man mano che le ipotesi del modello vengono violate.

 rng = np.random.default_rng(8675309)t = np.linspace(0, 11, 11000)x = np.array([ np.sin(2 * np.pi * t), np.sin(2 * np.pi / 2 * t + 1), np.sin(2 * np.pi / 2 * 2 * t + 2)])mixing = rng.uniform(-1, 1, [3, 3])# verifichiamo che la miscelazione a nostra scelta sia invertibileassert np.linalg.matrix_rank(mixing) == 3demixing_true = np.linalg.inv(mixing)delays = rng.integers(100, 500, (3, 3))y = np.zeros(x.shape)for source_i in range(3): for signal_j in range(3): x_ = x[source_i, delays[source_i, signal_j]:] y[signal_j, :len(x_)] += mixing[source_i, signal_j] * x_t = t[:10000]x = x[:, :10000]y = y[:, :10000]fica = FastICA(3)z = fica.fit_transform(np.transpose(y))z = np.transpose(z)z /= np.reshape(np.max(z, 1), (3, 1))fig, ax = plt.subplots(3, 1, figsize = (8, 5))for ii in range(3): ax[0].plot(t, x[ii]) ax[1].plot(t, y[ii]) ax[2].plot(t, z[ii])ax[0].set_title("Fonti indipendenti")ax[1].set_title("Segnali misti casualmente, linearmente e con ritardo temporale")ax[2].set_title("Componenti ICA (correlazione tra segno e scala lineare)")plt.tight_layout()  
FastICA per segnali misti ritardati: si nota che i componenti demistificati divergono dalle forme dei segnali di origine.

Problemi di Temporizzazione

Vale la pena esaminare un po’ più nel dettaglio perché l’ICA non può gestire questi ritardi temporali. Dopotutto, stiamo già affrontando una miscelazione sconosciuta, non dovremmo essere in grado di gestire una piccola perturbazione temporale? Andando ancora oltre, l’ICA su dati strutturati è invariante per permutazione! È possibile mescolare l’ordine di campionamento o di pixel in serie temporali o set di dati per immagini e ottenere gli stessi risultati dall’ICA. Quindi, di nuovo, perché l’ICA non sarebbe robusto a questi ritardi temporali?

Il problema nella festa del cocktail nel mondo reale è che c’è un diverso ritardo temporale per ogni coppia di altoparlanti e microfoni. Pensate a ogni campione digitale da un altoparlante come un disegno da una variabile casuale. Quando non ci sono ritardi, ogni microfono ascolta lo stesso disegno/campione nello stesso momento. Tuttavia, nel mondo reale ogni microfono registra un disegno/campione ritardato diverso dello stesso altoparlante e così come la matrice di miscelazione A è sconosciuta, così anche il ritardo temporale. E, naturalmente, il problema reale è ancora peggiore di un singolo valore di ritardo: le riverberazioni, gli echi e l’attenuazione diffonderanno ulteriormente i segnali di origine prima che arrivino ai microfoni.

Aggiorniamo la nostra formulazione del modello per rappresentare questo complicato ritardo temporale. Supponendo che l’acustica sottostante della stanza non cambi davvero e che i microfoni e gli altoparlanti rimangano nello stesso posto, possiamo scrivere:

dove k indica un indice discreto di ritardo temporale e la matrice di miscelazione A è ora una funzione matriciale che varia da k = 0…T³. In altre parole, l’osservazione effettiva al i-esimo microfono è una miscelazione lineare delle fonti che risale a T campioni. Inoltre, possiamo notare che il problema un po’ più semplice di un singolo ritardo temporale per coppia sorgente/microfono (senza effetti acustici più complicati) è un sotto-caso della formulazione del modello sopra, in cui la matrice A assume una forma non zero in un valore di k per coppia di indici (i, j).

Quelli inclini alla matematica o immersi nella stregoneria arcana del trattamento dei segnali noteranno che il modello del mondo reale⁴ del problema della festa del cocktail sta iniziando a assomigliare molto a una convoluzione. Infatti, questa è un’analoga discreta di una convoluzione funzionale e tramite la trasformata di Fourier possiamo arrivare a una versione dello spazio delle frequenze possibilmente più gestibile del nostro problema.

C’è molto da analizzare qui. La rappresentazione convoluzionale della festa del cocktail rivela in modo conciso perché l’ICA è destinato al fallimento in un trattamento ingenuo del problema BSS. Una registrazione audio multisenso del mondo reale è quasi certamente un problema di deconvoluzione, non un problema di demistificazione lineare. Potrebbe comunque essere gestibile approssimare una soluzione al problema (discuteremo alcune strategie di seguito), ma non bisogna presumere che l’ICA fornisca una demistificazione significativa spaziale nel dominio temporale senza molto altro lavoro.

Possiamo riprendere il nostro esempio di prova un’altra volta e simulare una convoluzione rudimentale progettando una convoluzione non lineare di un ritardo e una lunghezza assoluti casuali. In questo caso possiamo davvero vedere i componenti di FastICA che si staccano significativamente dai segnali di origine originali.

rng = np.random.default_rng(8675309)t = np.linspace(0, 11, 11000)x = np.array([    np.sin(2 * np.pi * t),     np.sin(2 * np.pi / 2 * t + 1),     np.sin(2 * np.pi / 2 * 2 * t + 2)])mixing = rng.uniform(-1, 1, [3, 3])# verifichiamo che la nostra miscelazione random sia invertibileassert np.linalg.matrix_rank(mixing) == 3demixing_true = np.linalg.inv(mixing)delays = rng.integers(100, 500, (3, 3))impulse_lengths = rng.integers(200, 400, (3, 3))y = np.zeros(x.shape)for source_i in range(3):    for signal_j in range(3):        impulse_length = impulse_lengths[source_i, signal_j]        impulse_shape = np.sqrt(np.arange(impulse_length).astype(float))        impulse_shape /= np.sum(impulse_shape)        delay = delays[source_i, signal_j]        for impulse_k in range(impulse_length):            x_ = x[source_i, (delay + impulse_k):]            y[signal_j, :len(x_)] += (                mixing[source_i, signal_j]                 * x_ * impulse_shape[impulse_k]            )t = t[:10000]x = x[:, :10000]y = y[:, :10000]fica = FastICA(3)z = fica.fit_transform(np.transpose(y))z = np.transpose(z)z /= np.reshape(np.max(z, 1), (3, 1))fig, ax = plt.subplots(3, 1, figsize = (8, 5))for ii in range(3):    ax[0].plot(t, x[ii])    ax[1].plot(t, y[ii])    ax[2].plot(t, z[ii])ax[0].set_title("Sorgenti Indipendenti")ax[1].set_title("Segnali Casualmente Convoloti")ax[2].set_title("Componenti ICA (Si allineano al segno e alla scala lineare)")plt.tight_layout()
FastICA per Segnali Convoluti: Si nota che i componenti smistati si discostano significativamente dalle forme del segnale di origine.

Tuttavia, la versione nello spazio delle frequenze inizia a somigliare sempre di più a un problema di modello ICA, almeno come problema di miscelazione lineare. Non è perfetto: la funzione della matrice di miscelazione trasformata di Fourier non è stazionaria nello spazio delle frequenze. Tuttavia, è probabilmente qui che vorremmo approfondire il problema ed è infatti il punto di partenza di strategie di deconvoluzione più generiche.

Il “Mondo Reale” e ICA

Qualunque cosa tu faccia, non utilizzare ICA per la separazione delle sorgenti audio in un cocktail party. Ci sono però situazioni reali in cui ICA è utile?

Consideriamo una delle applicazioni più comuni di ICA: la featurizzazione e la decomposizione dell’elettroencefalografia (EEG). I segnali EEG sono registrazioni di serie temporali di potenziali elettrici dagli elettrodi sul cuoio capelluto (e talvolta dagli elettrodi nel cervello). Esiste un’industria emergente che applica ICA ai dati EEG preelaborati al fine di identificare fonti indipendenti di segnali di potenziale elettrico nel cervello e nel corpo.

Nel caso delle registrazioni EEG, l’assunzione del modello ICA di miscelazione istantanea è sicuramente soddisfatta: i segnali elettrici si propagano quasi istantaneamente rispetto alla scala di lunghezza di una testa umana e alla frequenza di campionamento, che è tipicamente nell’ordine delle decine o centinaia di Hz. Questo è un buon segno per ICA qui e, infatti, i componenti indipendenti generalmente separano alcune caratteristiche spazialmente significative. I movimenti degli occhi e i movimenti muscolari (dove la conducibilità della pelle propaga il segnale al cuoio capelluto) sono spesso componenti chiaramente distinti. Altri componenti producono pattern di attivazioni degli elettrodi sul cuoio capelluto che sembrano significativi, queste attivazioni sono ritenute il risultato di raccolte di neuroni che agiscono come sorgenti di dipoli radianti nel cervello. La posizione e l’orientamento tridimensionale di tali sorgenti possono essere ulteriormente inferiti con una mappatura precisa delle posizioni degli elettrodi sul cuoio capelluto.

Abbiamo stabilito che l’assunzione di miscelazione istantanea è soddisfatta qui, ma cosa succede alle altre assunzioni del modello? Se gli elettrodi non si muovono sul cuoio capelluto e il soggetto è altrimenti stazionario, allora una miscelazione costante potrebbe essere anche una ragionevole assunzione. Stiamo misurando più canali rispetto alle sorgenti? ICA non genererà più componenti indipendenti rispetto ai canali di segnale registrati, ma se ci sono molte più sorgenti vere di quelle che è possibile distinguere, attribuire un significato spaziale ai componenti potrebbe essere problematico.

Infine, le sorgenti sono indipendenti? Qui le cose possono diventare molto complicate! Le sorgenti di dipoli radianti non sono ovviamente singoli neuroni ma rappresentano l’attività di spiking collettiva di molti, molti neuroni. In che misura crediamo – alla scala temporale di campionamento dell’EEG – che questi cluster di neuroni coerenti siano indipendenti l’uno dall’altro? Dieci anni fa Makeig e Onton hanno offerto una vasta discussione e indagine su questo argomento⁶. L’idea principale è che si ritiene che le sorgenti siano patches localmente coerenti di neuroni corticali: la forza delle connessioni vicine rispetto alle connessioni distanti induce sia potenziale elettrico simile alle “onde nello stagno” (centrate in sorgenti localizzate) e riduce presumibilmente la dipendenza tra patches spazialmente separate. Detto questo, è stato osservato un interesse intermittente nell’esaminare la miscelazione convolutiva nell’EEG tramite ICA nel dominio complesso⁷ ⁸.

Deconvoluzione e ICA

Posso utilizzare in qualche modo ICA per risolvere il problema di deconvoluzione che l’esempio del cocktail party del mondo reale illustra? Torniamo alla rappresentazione nello spazio delle frequenze del problema di deconvoluzione BSS. Ricordiamo che è molto simile a qualcosa che ICA può gestire… la matrice di miscelazione è una trasformazione lineare, il problema principale è che non è stazionaria come funzione della frequenza. Se facciamo alcune ipotesi sulla convoluzione (cieca), potremmo adattare ICA al problema di deconvoluzione.

Supponiamo che la miscelazione nello spazio delle frequenze varii in modo continuo e “lento” come funzione della frequenza. Con “lento” intendiamo che una piccola variazione nell’argomento della frequenza induce una variazione (più) piccola nella miscelazione. Stiamo usando un po’ di terminologia vaga qui, ma l’idea generale è che, avendo abbastanza campioni, potremmo dividere il problema BSS in sottoinsiemi dello spazio delle frequenze ed eseguire ICA in ogni sottoinsieme assumendo una miscelazione stazionaria all’interno dei sottoinsiemi di frequenza. Ad esempio, sappiamo che globalmente la miscelazione varia con la frequenza, ma forse varia abbastanza lentamente da poter assumere che sia stazionaria in finestre spettrali. Quindi, tra, ad esempio, 10 e 15 kHz, useremo un insieme di campioni trasformati tramite Fourier per stimare una miscelazione statica singola in quella finestra di frequenza.

In teoria possiamo provare a interpolare tra le soluzioni ICA statiche sull’intero spettro di frequenza. Quindi, se abbiamo la nostra soluzione di demixing ICA da 10-15 kHz e un’altra soluzione per 15-20 kHz, potremmo ideare uno schema di interpolazione centrando le due soluzioni a 12.5 kHz e 17.5 kHz e quindi inferire una qualche funzione di mixing della frequenza tra questi due punti.

Tuttavia ci sono alcune ambiguità che devono essere risolte. Prima di tutto, le matrici di demixing non sono solo vettori ma hanno una struttura di gruppo aggiuntiva a cui potremmo voler prestare attenzione. In secondo luogo, le componenti della soluzione ICA sono invarianti rispetto alla permutazione e alla scala… in altre parole, pensando di nuovo a ICA come a un cambiamento di base, qualsiasi riorganizzazione o cambiamento di segno/magnitudine delle direzioni della base sarà una soluzione altrettanto buona. Quindi le strategie per fare questo tipo di ICA distribuita nello spazio delle frequenze possono ridursi a come risolvere un problema di corrispondenza e coerenza tra le soluzioni ICA in insiemi di frequenze adiacenti.

Cocktail misti (Immagine dell'autore)

Featurizzazione spensierata e attenta

C’è, sperabilmente, una lezione più ampiamente applicabile in tutto ciò. ICA può essere una tecnica di decomposizione molto potente, anche quando c’è qualche ambiguità riguardo alla soddisfazione delle sue assunzioni di modello. Infatti, come ricercatore, mi rivolgo quasi sempre a FastICA per la riduzione di dimensione invece di — o almeno in confronto a — PCA. Mi piace particolarmente sperimentare con FastICA per dati più astratti senza un’interpretazione formale di BSS.

Perché l’ICA può essere utilizzata più genericamente? Perché gli algoritmi stessi sono solo approssimazioni astratte delle soluzioni di BSS. FastICA fa ciò che promette: trova un cambio di base rispetto al quale le componenti dei dati sono massimamente non gaussiane — come dedotto (più o meno) dalla curtosi. Se questa trasformazione coincidesse con fonti indipendenti fisicamente significative, allora sarebbe fantastico! Se non lo fa, può comunque essere una trasformazione utile nello stesso senso in cui viene utilizzata in modo astratto PCA. PCA e FastICA sono anche molto vagamente correlati, se pensiamo a ciascuno come a un cambio di base che ottimizza una statistica di secondo e quarto ordine, rispettivamente.

Tuttavia è necessario prestare attenzione nel leggere più di quanto potrebbe essere supportato dai risultati di ICA. Vogliamo dire che le componenti ICA sono massimamente indipendenti o non gaussiane: certo, nessun problema! Ma possiamo dire che le componenti ICA siano fonti fisicamente significative e distintive? Solo se c’è un problema di modello BSS sottostante che soddisfa le assunzioni che abbiamo stabilito qui. Le componenti ICA astrattamente potrebbero ben indicare relazioni utili nascoste sotto strati di non linearità e convoluzioni. Dobbiamo solo fare attenzione a non sovraccaricare la nostra interpretazione di ICA senza convalidare le assunzioni del modello.

Riferimenti e Note a piè di pagina

[1] Le due varianti storicamente più importanti di ICA — FastICA e Infomax ICA — risalgono a:

  1. Hyvärinen e E. Oja, A Fast Fixed-Point Algorithm for Independent Component Analysis (1997), Neural Computation

A. Bell e T. Sejnowski, An Information-Maximization Approach to Blind Separation and Blind Deconvolution (1995), Neural Computation

[2] C. Maklin, Independent Component Analysis (ICA) In Python (2019), Towards Data Science

[3] J. Dieckmann, Introduction to ICA: Independent Component Analysis (2023), Towards Data Science

[4] Qui stiamo leggermente abusando della notazione ignorando i confini della registrazione audio, ad esempio quando t=0. Non preoccupatevi! Dopotutto, tutto è un abuso notazionale della matematica.

[5] È mai un modello perfettamente vero nel “mondo reale?” No, risponde Dr. Box. Rob Thomas, stanco di essere molestato, concorda.

[6] S. Makeig e J. Onton, Caratteristiche dell’ERP e dinamiche dell’EEG: Una prospettiva ICA (2012), The Oxford Handbook of Event-Related Potential Components

[7] J. Anemüller, T. J. Sejnowski e S. Makeig, Analisi complessa dei componenti indipendenti dei dati elettroencefalografici nel dominio delle frequenze (2003), Neural Networks

[8] A. Hyvärinen, P. Ramkumar, L. Parkkonen e R. Hari, Analisi dei componenti indipendenti delle trasformate di Fourier a breve termine per l’analisi spontanea dell’EEG/MEG (2009), NeuroImage