PCA 之前的标准化与缩放

机器算法验证 聚类 主成分分析 scikit-学习
2022-03-20 19:13:20

我知道有很多关于PCA预处理的内容,但我还是有些困惑。

我有一个包含一些明确模式的数据集:1 个变量是一个人是否有经济资源(是/否),另一个是金融资源的数量(对于没有资源的人 = 0),然后其他变量是倾向于与财政资源的数量相关。该数据集还包含几个虚拟变量,以及一些介于 0 和 5 之间的离散变量。

我假设我会找到两个集群:一个用于没有资源的人,另一个用于有资源的人。

当应用带有两个组件的 PCA 时,我有两种方法: - Scale,然后应用 PCA - Normalize,然后应用 PCA

这导致完全不同的结果。我知道缩放是 PCA 的标准预处理步骤。但是规范化有意义吗?我想我已经做了一些接近稀疏 PCA 的事情,我首先捕获了最重要的模式,然后拟合了 PCA。你能给我一些关于这方面的见解吗?

请注意,我的 PCA 的目标是可视化聚类算法的结果。

图 1 - 具有缩放比例的前 2 个组件

缩放

图 2 - 归一化的前 2 个组件

规范化

2个回答

由于主成分的计算方式,缩放(我称之为居中和缩放)对于 PCA 非常重要。PCA 是通过奇异值分解来解决的,它可以找到最能代表平方意义上的数据的线性子空间我用斜体表示的两部分是我们分别居中和缩放的原因。

线性子空间是线性代数中的一个重要研究课题,PCA 的线性子空间最重要的结果是它必须经过原点,即点 [0, 0, ..., 0]。因此,例如,如果您正在测量一个国家的 GDP 和人口之类的东西,那么您的数据可能离原点很远,并且很难被任何线性子空间近似。通过使我们的数据居中,我们保证它们存在于原点附近,并且可以用低维线性子空间来近似它们。在您的情况下,您的数据似乎都是正数,因此在预处理之前它们肯定不会以 0 为中心。

这是一个远离原点的 2D 数据集的示例,它在居中之前获得了无用的第一个组件:

中心PCA 缩放很重要,因为 SVD 在平方和意义上近似,所以如果一个变量的比例与另一个变量不同,它将主导 PCA 过程,而低 D 图实际上只是可视化该维度。

我将用python中的一个例子来说明。

我们先搭建一个环境:

import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import scale, normalize
import matplotlib.pyplot as plt
plt.ion()

# For reproducibility 
np.random.seed(123)

我们将生成 4 维标准正态/不相关的数据,但有一个附加变量随机取 0 或 5 的值,给出我们希望可视化的 5 维数据集:

N = 200
P = 5
rho = 0.5

X = np.random.normal(size=[N,P])
X = np.append(X, 3*np.random.choice(2, size = [N,1]), axis = 1)

我们将首先在没有任何预处理的情况下进行 PCA:

# No preprocessing:
pca = PCA(2)
low_d = pca.fit_transform(X)
plt.scatter(low_d[:,0], low_d[:,1])

这产生了这个情节: 未加工

我们清楚地看到了两个集群,但数据是完全随机生成的,完全没有结构!

归一化改变了情节,但我们仍然看到 2 个集群:

# normalize
Xn = normalize(X)
pca = PCA(2)
low_d = pca.fit_transform(Xn)
plt.scatter(low_d[:,0], low_d[:,1])

归一化

二元变量与其他变量的规模不同这一事实产生了一种可能不一定存在的集群效应。这是因为 SVD 比其他变量更多地考虑它,因为它对平方误差的贡献更大。这可以通过缩放数据集来解决:

# Scale
Xs = scale(X)
low_d = pca.fit_transform(Xs)
plt.scatter(low_d[:,0], low_d[:,1])

缩放

我们终于(正确地)看到数据完全是随机噪声。

我猜想在您的情况下,您的 0-5 变量可能会主导 0-1 虚拟变量,从而导致不应该存在的聚类(是否会发生 0-5 变量累积在刻度的边缘?) .

编辑:我最近遇到了空间符号协方差矩阵的概念,它似乎可以进行我们讨论的归一化,以生成稳健的协方差矩阵。特征分析随后将产生归一化 PCA 算法,本文将对此进行讨论。

我想指出 sklearnnormalizescale使用不同的默认轴。normalize默认为axis=1scale默认为axis=0. 跟随@John Madden 很好的例子,但是如果我们进行标准化axis=0,这两个集群也会消失。在此处输入图像描述

import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import scale, normalize
import matplotlib.pyplot as plt

# For reproducibility 
np.random.seed(123)

N = 200
P = 5
rho = 0.5

X = np.random.normal(size=[N,P])
X = np.append(X, 3*np.random.choice(2, size = [N,1]), axis = 1)

X = normalize(X, axis=0)

# No preprocessing:
pca = PCA(2)
low_d = pca.fit_transform(X)
plt.scatter(low_d[:,0], low_d[:,1])
plt.show()