Tulisan kali ini membahas hal yang sama persis dengan tulisan sebelumnya yakni tentang ICA. Letak perbedaannya adalah pada tulisan sebelumnya (bisa dilihat di link ini) saya menggunakan Octave. Sedangkan pada kesempatan kali ini saya mencoba menggunakan Python. Jadi, isi tulisan kali ini hanya berisi pengaplikasian Python code pada ICA saja tanpa disertai dengan penjelasan terkait ICA itu sendiri. Tidak ada alasan khusus kenapa saya menuliskan ICA menggunakan Python meski sangat banyak sekali code tentang ICA di internet yang lebih cepat dan efisien. Ini hanyalah sekedar tulisan seorang "beginner" yang sedang belajar tentang Python untuk Scientific Computing. Oke let's start!
Simpan code berikut dengan nama "ica.py". Code ini kita anggap sebagai modul ICA dimana modul ini nantinya akan dipanggil.
import numpy as np
import numpy.linalg as LA
from scipy.linalg import sqrtm
def fG(wn,xw):
a1 = 1
u = np.dot(xw.transpose(),wn)
g = np.tanh(a1*u)
dg = (1-g**2)*a1
dg = np.dot(np.ones((wn.shape[0],1)),np.sum(dg,axis=0).reshape(1,dg.shape[1]))
return g, dg
def fast_ica(x):
# centering
xc = x - np.tile(np.mean(x,axis=1).reshape(x.shape[0],1),(1,x.shape[1]))
# whitening
D,E = LA.eig(np.cov(xc,bias=1))
D = np.diag(D)
xw = np.dot(np.dot(E,LA.inv(np.sqrt(D))),np.dot(E.transpose(),xc))
# Algoritma Fast ICA
wn = np.random.rand(xc.shape[0],xc.shape[0])
for i in range(5000):
w_plus = np.dot(xw,fG(wn,xw)[0]) - fG(wn,xw)[1]*wn
wn1 = np.dot(w_plus,np.real(LA.inv(sqrtm(np.dot(w_plus.transpose(),w_plus)))))
if 1 - np.min(np.abs(np.diag(np.dot(wn,np.transpose(wn1))))) < np.spacing(1):
print 'W konvergen pada iterasi ke - %i' % (i+1)
break
else:
wn = wn1
Aest = np.dot(np.dot(LA.inv(E.transpose()),np.sqrt(D)),np.dot(LA.inv(E),wn1))
# Estimasi s
Sest = np.dot(LA.inv(Aest),x)
return Sest, Aest
import numpy.linalg as LA
from scipy.linalg import sqrtm
def fG(wn,xw):
a1 = 1
u = np.dot(xw.transpose(),wn)
g = np.tanh(a1*u)
dg = (1-g**2)*a1
dg = np.dot(np.ones((wn.shape[0],1)),np.sum(dg,axis=0).reshape(1,dg.shape[1]))
return g, dg
def fast_ica(x):
# centering
xc = x - np.tile(np.mean(x,axis=1).reshape(x.shape[0],1),(1,x.shape[1]))
# whitening
D,E = LA.eig(np.cov(xc,bias=1))
D = np.diag(D)
xw = np.dot(np.dot(E,LA.inv(np.sqrt(D))),np.dot(E.transpose(),xc))
# Algoritma Fast ICA
wn = np.random.rand(xc.shape[0],xc.shape[0])
for i in range(5000):
w_plus = np.dot(xw,fG(wn,xw)[0]) - fG(wn,xw)[1]*wn
wn1 = np.dot(w_plus,np.real(LA.inv(sqrtm(np.dot(w_plus.transpose(),w_plus)))))
if 1 - np.min(np.abs(np.diag(np.dot(wn,np.transpose(wn1))))) < np.spacing(1):
print 'W konvergen pada iterasi ke - %i' % (i+1)
break
else:
wn = wn1
Aest = np.dot(np.dot(LA.inv(E.transpose()),np.sqrt(D)),np.dot(LA.inv(E),wn1))
# Estimasi s
Sest = np.dot(LA.inv(Aest),x)
return Sest, Aest
Kemudian, simpan lagi code di bawah ini dengan nama "main.py"
import numpy as np
import matplotlib.pyplot as plt
import time
import ica
t0 = time.time()
fs = 10**4
t = np.arange(0,2,1./fs)
f1 = 5 # frekuensi sinyal 1
f2 = 20 # frekuensi sinyal 2
f3 = 2 # frekuensi sinyal 3
s1 = np.sin(2*np.pi*f1*t) # sinyal 1
s2 = np.sin(2*np.pi*f2*t) # sinyal 2
s3 = np.sin(2*np.pi*f3*t) # sinyal 3
# tiga sinyal dalam satu matrik
s = np.array([s1,s2,s3])
# plot sinyal asli
plt.figure()
for i in range(3):
plt.subplot(3,1,i+1)
plt.plot(t,s[i])
# Mixing matrix
A = np.random.rand(3,3)
# sinyal tercampur
x = np.dot(A,s)
# plot sinyal tercampur
plt.figure()
for i in range(3):
plt.subplot(3,1,i+1)
plt.plot(t,x[i])
# Fast ICA
Sest, Aest = ica.fast_ica(x)
# plot sinyal estimasi
plt.figure()
for i in range(3):
plt.subplot(3,1,i+1)
plt.plot(t,Sest[i])
t1 = time.time()
plt.show()
print 'Elapsed time %.5f seconds.' % (t1-t0)
import matplotlib.pyplot as plt
import time
import ica
t0 = time.time()
fs = 10**4
t = np.arange(0,2,1./fs)
f1 = 5 # frekuensi sinyal 1
f2 = 20 # frekuensi sinyal 2
f3 = 2 # frekuensi sinyal 3
s1 = np.sin(2*np.pi*f1*t) # sinyal 1
s2 = np.sin(2*np.pi*f2*t) # sinyal 2
s3 = np.sin(2*np.pi*f3*t) # sinyal 3
# tiga sinyal dalam satu matrik
s = np.array([s1,s2,s3])
# plot sinyal asli
plt.figure()
for i in range(3):
plt.subplot(3,1,i+1)
plt.plot(t,s[i])
# Mixing matrix
A = np.random.rand(3,3)
# sinyal tercampur
x = np.dot(A,s)
# plot sinyal tercampur
plt.figure()
for i in range(3):
plt.subplot(3,1,i+1)
plt.plot(t,x[i])
# Fast ICA
Sest, Aest = ica.fast_ica(x)
# plot sinyal estimasi
plt.figure()
for i in range(3):
plt.subplot(3,1,i+1)
plt.plot(t,Sest[i])
t1 = time.time()
plt.show()
print 'Elapsed time %.5f seconds.' % (t1-t0)
Langkah terakhir, jalankan "main.py" di komputer anda.
Di Ubuntu, saya lebih suka menggunakan Ipython. Jadi biasanya cukup ketik
In [1]: %run main.py
W konvergen pada iterasi ke - 6
Elapsed time 0.98528 seconds.
W konvergen pada iterasi ke - 6
Elapsed time 0.98528 seconds.
Klo melalui terminal,
user@my-pc$ python main.py
W konvergen pada iterasi ke - 7
Elapsed time 0.49387 seconds.
Contoh gambar yang muncul adalah seperti di bawah ini
Elapsed time 0.49387 seconds.
Contoh gambar yang muncul adalah seperti di bawah ini
Sinyal sinyal sebelum dicampur |
Sinyal sinyal hasil pencampuran |
Sinyal hasil permisahan menggunakan ICA |
Untuk code-nya bisa didownload di link ini.
Selamat mencoba
No comments:
Post a Comment