在数据分析领域,独立成分分析(ICA)和主成分分析(PCA)是两种常用的特征提取技术。它们在处理数据时采用了不同的方法和目标。ICA旨在寻找特征空间中具有高非高斯性的投影方向,而PCA则寻找原始特征空间中对应最大方差的正交方向。这两种技术在数据降维和信号处理中有着广泛的应用。
ICA算法在特征空间中寻找的方向不需要在原始特征空间中正交,但在白化后的特征空间中,这些方向是正交的,且所有方向对应相同的方差。相对地,PCA则在原始特征空间中寻找正交方向,这些方向对应最大的方差。
为了模拟独立源,使用了一个高度非高斯的过程,即具有低自由度的t分布(2自由度的学生t分布),并将它们混合以创建观测数据。在原始观测空间中,PCA识别的方向由橙色向量表示。在PCA空间中,信号表示为对应于PCA向量方差的白化信号。运行ICA相当于在这个空间中找到一个旋转,以识别最大非高斯性的方向。
在下面的代码中,首先导入了必要的库,并生成了样本数据。使用numpy库来生成标准t分布的样本,并将其放大以模拟两个独立的源。然后,通过一个混合矩阵将这些源混合,以生成观测数据。
import numpy as np
from sklearn.decomposition import PCA, FastICA
rng = np.random.RandomState(42)
S = rng.standard_t(1.5, size=(20000, 2))
S[:, 0] *= 2.0 # 放大第一个源
# 混合数据
A = np.array([[1, 1], [0, 2]])
# 混合矩阵
X = np.dot(S, A.T) # 生成观测数据
接下来,使用PCA和ICA对混合数据进行分析。PCA通过寻找原始特征空间中的最大方差方向来恢复信号,而ICA则通过寻找最大非高斯性的方向来恢复信号。
pca = PCA()
S_pca_ = pca.fit(X).transform(X)
ica = FastICA(random_state=rng, whiten='arbitrary-variance')
S_ica_ = ica.fit(X).transform(X)
最后,绘制了原始独立源、观测数据、PCA恢复的信号和ICA恢复的信号。这些图表帮助直观地比较了PCA和ICA在处理相同数据时的不同表现。
import matplotlib.pyplot as plt
def plot_samples(S, axis_list=None):
plt.scatter(S[:, 0], S[:, 1], s=2, marker="o", zorder=10, color="steelblue", alpha=0.5)
if axis_list is not None:
for axis, color, label in axis_list:
x_axis, y_axis = axis / axis.std()
plt.quiver((0, 0), (0, 0), x_axis, y_axis, zorder=11, width=0.01, scale=6, color=color, label=label)
plt.figure()
plt.subplot(2, 2, 1)
plot_samples(S / S.std())
plt.title("真实的独立源")
axis_list = [(pca.components_.T, "orange", "PCA"), (ica.mixing_, "red", "ICA")]
plt.subplot(2, 2, 2)
plot_samples(X / np.std(X), axis_list=axis_list)
plt.legend(loc="upper left")
plt.title("观测数据")
plt.subplot(2, 2, 3)
plot_samples(S_pca_ / np.std(S_pca_))
plt.title("PCA恢复的信号")
plt.subplot(2, 2, 4)
plot_samples(S_ica_ / np.std(S_ica_))
plt.title("ICA恢复的信号")
plt.subplots_adjust(0.09, 0.04, 0.94, 0.94, 0.26, 0.36)
plt.tight_layout()
plt.show()
通过这个示例,可以看到ICA和PCA在处理非高斯分布数据时的不同策略和结果。ICA通过寻找最大非高斯性的方向来恢复信号,而PCA则通过寻找最大方差的方向来恢复信号。这两种方法各有优势,适用于不同的数据分析场景。