【火爐煉AI】機器學習054-用ICA做盲源分離
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
盲源分離是指在訊號的理論模型和源訊號無法精確獲知的情況下,如何從混疊訊號中分離出各源訊號的過程。盲源分離的目的是求得源訊號的最佳估計。說的通俗一點,就相當於,假如有十個人同時說話,我用錄音機把他們說的話都錄下來,得到的肯定是10種聲音的混雜,那麼怎麼將這種混雜聲音分離成單個人的說話聲音?解決類似這種問題就是盲源分離。
獨立成分分析(Independent Components Analysis, ICA)解決的是原始資料分解的問題,常常用於盲源分離問題中。在我上一篇文章【火爐煉AI】機器學習053-資料降維絕招-PCA和核PCA中提到PCA雖然具有各種優點,但是也有幾個缺點,比如不能對非線性組織的資料集降維,針對這個缺點解決方法是用核PCA代替PCA,另外一個缺點是不能用於解決資料集不滿足高斯分佈的情況,這種情況的資料降維要用獨立成分分析ICA來完成。
獨立成分分析師從多維統計資料中尋找潛在因子或成分的一種方法,ICA與PCA等降維方法的區別在於,它尋找滿足統計獨立和非高斯的成分。其數學原理和邏輯可以參考博文:獨立成分分析ICA系列2:概念、應用和估計原理
1. 載入資料集
首先載入資料集,本次所用的資料集位於檔案mixture_of_signals.txt中,這個檔案中有四列資料,代表四個不同的訊號源,共2000個樣本
data_path="E:\PyProjects\DataSet\FireAI\mixture_of_signals.txt"
df=pd.read_csv(data_path,header=None,sep=' ')
print(df.info()) # 檢視資料資訊,確保沒有錯誤
print(df.head())
print(df.tail())
dataset_X=df.values
print(dataset_X.shape)
複製程式碼
繪圖後,可以看出這些資料的分佈情況:
2. 用傳統PCA來分離訊號
假如我們用PCA來進行盲源分離,可以看看效果怎麼樣,程式碼為:
# 如果用PCA來進行分離,看看結果如何
from sklearn.decomposition import PCA
pca = PCA(n_components=4)
pca_dataset_X = pca.fit_transform(dataset_X)
pd.DataFrame(pca_dataset_X).plot(title='PCA_dataset')
複製程式碼
上面雖然繪製了PCA分離之後的各種訊號,但是訊號夾雜在一起難以分辨,故而我編寫了一個函式將其分開顯示
def plot_dataset_X(dataset_X):
rows,cols=dataset_X.shape
plt.figure(figsize=(15,20))
for i in range(cols):
plt.subplot(cols,1,i+1)
plt.title('Signal_'+str(i))
plt.plot(dataset_X[:,i])
複製程式碼
3. 用ICA來分離訊號
下面看看用獨立成分分析方法得到的分離後訊號:
# 如果用ICA進行訊號分離
from sklearn.decomposition import FastICA
ica = FastICA(n_components=4)
ica_dataset_X = ica.fit_transform(dataset_X)
pd.DataFrame(ica_dataset_X).plot(title='ICA_dataset')
複製程式碼
同理,為了顯示方便,將各種訊號單獨畫圖,如下:
可以看出,經過ICA分離之後得到的訊號非常有規律,而PCA分離後的訊號有些雜亂,表面ICA的盲源分離效果較好。
########################小**********結###############################
1,用ICA可以解決盲源分離問題,所得到的分離效果要比PCA要好得多。
2,實際上,生活中的真實資料集大部分都不是服從高斯分佈,它們一般服從超高斯分佈或亞高斯分佈,故而很多問題用PCA得到的效果不太理想,返回用ICA能夠得到比較好的結果。
#################################################################
注:本部分程式碼已經全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯