Independent Component Analysis (ICA)



By Prof. Seungchul Lee
http://iai.postech.ac.kr/
Industrial AI Lab at POSTECH

Table of Contents

1. The Cocktail Party ProblemĀ¶

You're at a crowded party. The music is loud, people are laughing, and a dozen different conversations are happening all around you. However, despite the hubbub, you're able to focus on the one voice you want to hear.



(No reason to shout. Though background noise can be distracting, the brain has the remarkable ability to track conversation and scale down unwanted noise. Courtesy of the National Archives)



Consider two conversations in a room that are happening simultaneously. How is it that the two different acoustic signals of converstaion one and two can be separated out?


$$ \begin{align*} x_1 &= a_{11}s_1 + a_{12}s_2\\ x_2 &= a_{21}s_1 + a_{22}s_2 \end{align*} $$
InĀ [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

import IPython.display as ipd
import librosa.display
InĀ [2]:
ipd.Audio('.\data_files\The_Phantom_Of_The_Opera.wav')
Out[2]:
InĀ [3]:
ipd.Audio('.\data_files\Barack_Obama.wav')
Out[3]:
InĀ [4]:
s1, sr = librosa.load('.\data_files\The_Phantom_Of_The_Opera.wav')
s2, sr = librosa.load('.\data_files\Barack_Obama.wav')
InĀ [5]:
s1 = np.asmatrix(s1).reshape(-1,1)
s2 = np.asmatrix(s2).reshape(-1,1)

m = 300000;
s1 = s1[0:m, :]
s2 = s2[0:m, :]

S = np.hstack([s1, s2])

A = np.matrix([[1/2], [2/3]])
mixed = S*A
InĀ [6]:
ipd.Audio(np.ravel(mixed), rate = sr)
Out[6]:

2. ICAĀ¶

Observed random vector $x$ is modelled by a linear variable model


$$ x_i = \sum_{j=1}^{m} a_{ij}s_j, \qquad i = 1,\cdots, n$$

or in matrix form

$$ x= As $$

where

  • the 'mixing' matrix $A$ is constant
  • the $s_i$ are latent random variables called the independent components
  • Estimate both $A$ and $s_i$, observing only $x$

  • must assume:

    • $s_i$ are mutually independent
    • $s_i$ are non-gaussian
  • At first, we might simply say that the solution of this is trivial and it is given by


$$ s = A^{-1}x$$

$\quad \;$ However, we do not know $A$ and the signal $s$.

  • PCA and ICA (pictorial explanation)







3. Sound ExampleĀ¶

InĀ [7]:
from sklearn.decomposition import FastICA
InĀ [8]:
A = np.matrix([[1/2, 2/3], 
               [4/5, 1/4]]);
mixed = S*A
InĀ [9]:
ica = FastICA(n_components = 2)
ica_sig = ica.fit_transform(mixed)  # Reconstruct signals
InĀ [10]:
ipd.Audio(ica_sig[:,0], rate=sr)
Out[10]:
InĀ [11]:
ipd.Audio(ica_sig[:,1], rate=sr)
Out[11]:

5. Image ExampleĀ¶

InĀ [12]:
S1 = plt.imread('./data_files/Suhin.jpg')
S2 = plt.imread('./data_files/nature.jpg')

plt.figure(figsize = (10,10))
plt.subplot(1,2,1), plt.imshow(S1), plt.axis('off')
plt.subplot(1,2,2), plt.imshow(S2), plt.axis('off')
plt.show()
InĀ [13]:
A = np.matrix([[3/4, 1/5],
              [1/2, 2/3]])

X1 = A[0,0]*S1 + A[0,1]*S2
X2 = A[1,0]*S1 + A[1,1]*S2
InĀ [14]:
plt.figure(figsize = (10,10))
plt.subplot(1,2,1), plt.imshow(np.uint8(X1)), plt.axis('off')
plt.subplot(1,2,2), plt.imshow(np.uint8(X2)), plt.axis('off')
plt.show()
InĀ [15]:
m, n, k = X1.shape

x1 = X1.reshape(-1, 1)
x2 = X2.reshape(-1, 1)

mixed = np.hstack([x1, x2])

ica = FastICA(n_components = 2)
ica_img = ica.fit_transform(mixed)  # Reconstruct signals
InĀ [16]:
ica_img.shape
Out[16]:
(300000, 2)
InĀ [17]:
img_01 = ica_img[:,0]
img_01 = img_01 - img_01.min()
img_01 = img_01*255/img_01.max()
img_01 = img_01.reshape(m, n, 3)
InĀ [18]:
img_02 = ica_img[:,1]
img_02 = img_02 - img_02.min()
img_02 = img_02*255/img_02.max()
img_02 = img_02.reshape(m, n, 3)
InĀ [19]:
plt.figure(figsize = (10,10))
plt.subplot(1,2,1), plt.imshow(np.uint8(img_01)), plt.axis('off')
plt.subplot(1,2,2), plt.imshow(np.uint8(img_02)), plt.axis('off')
plt.show()
InĀ [20]:
%%javascript
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')