PCA降维之前为什么要先标准化?

  统计/机器学习 数据预处理 数据降维    浏览次数:9603        分享

当数据维数很高的时候,我们可以用PCA降维,但是降维前通常我们要对数据进行标准化,为什么要这样做?这有什么好处?

 

机器小白   2017-03-21 13:25



   4个回答 
27

PCA(主成分分析)所对应的数学理论是SVD(矩阵的奇异值分解)。而奇异值分解本身是完全不需要对矩阵中的元素做标准化或者去中心化的。

但是对于机器学习,我们通常会对矩阵(也就是数据)的每一列先进行标准化。

PCA通常是用于高维数据的降维,它可以将原来高维的数据投影到某个低维的空间上并使得其方差尽量大。如果数据其中某一特征(矩阵的某一列)的数值特别大,那么它在整个误差计算的比重上就很大,那么可以想象在投影到低维空间之后,为了使低秩分解逼近原数据,整个投影会去努力逼近最大的那一个特征,而忽略数值比较小的特征。因为在建模前我们并不知道每个特征的重要性,这很可能导致了大量的信息缺失。为了“公平”起见,防止过分捕捉某些数值大的特征,我们会对每个特征先进行标准化处理,使得它们的大小都在相同的范围内,然后再进行PCA。

此外,从计算的角度讲,PCA前对数据标准化还有另外一个好处。因为PCA通常是数值近似分解,而非求特征值、奇异值得到解析解,所以当我们使用梯度下降等算法进行PCA的时候,我们最好先要对数据进行标准化,这是有利于梯度下降法的收敛。

SofaSofa数据科学社区DS面试题库 DS面经

清风   2017-03-23 11:11

这个给力!估计很多人跟我一样,只注意到第二点。但是我觉得你写得第一点更重要! - 汪王往望   2017-04-15 11:33
谢谢!学习了! - PG Two   2017-09-08 13:09
应该说是数据都需要标准化,让每个维度的重要性一样。如果已知某维度比较重要,可以再乘上系数。然后再是PCA的问题。 - Zealing   2018-03-15 12:47
谢谢分享! - ccc225   2018-05-20 09:43
试了下,有些数据集做不做标准化,PCA的结果差距是非常大的。如果不做标准化,数值较大的特征会对结果产生更大的影响。对于手头某个数据集: n_components = 14 标准化前 explained_variance_ratio = [0.99708 0.00291 0.00001 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ] 标准化后: explained_variance_ratio = [0.17403 0.11963 0.09637 0.07923 0.07411 0.07285 0.07014 0.06593 0.06344 0.06011 0.05312 0.04306 0.02798 0. - cy1019x   2019-04-29 11:37
3

没做标准化的PCA是找covariance matrix的eigenvector,标准化后的PCA是找correlation matrix的eigenvector。如清风说的第一点,如果没有做标准化,eigenvector会偏向方差最大的变量,偏离理论上的最佳值。

举例说明。假设一个2维Gaussian,correlation matrix是[1 0.4;0.4 1], $std(x_1)=10, std(x_2)=1$。理论上最佳的分解向量是椭圆的长轴,如果没有做标准化,PCA算出的向量和长轴会有偏差。标准化后偏差会减到很小。


#standarization of PCA
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
np.set_printoptions(precision=3)
np.random.seed(0)
n=1000000
mu=[0,0]
corr=np.array([[1.,.4],[.4,1.]])
std_vector=[10.,1]

A_ori=np.random.multivariate_normal(mu,corr,n)
A_scaled=np.matmul(A_ori,np.diag(std_vector))
scaler = StandardScaler()
scaler.fit(A_scaled)
A_standarized=scaler.transform(A_scaled)

pca = PCA()
pca.fit(A_scaled)
pca1 = PCA()
pca1.fit(A_standarized)

print('Correlation Coefficient matrix is:')
print(corr)
print('std vector is:')
print(std_vector)

print('Covariance matrix is:')
print(np.cov(A_scaled.T))

print('---Before standarization---')
print('Components:')
print(pca.components_)
print('Sigular values:')
print(pca.explained_variance_)

print('---After standarization---')
print('Components:')
print(pca1.components_)
print('Sigular values:')
print(pca1.explained_variance_)

# draw PCA components
t1=np.linspace(-20,20,100)
t2=t1*std_vector[1]/std_vector[0]

plt.figure(figsize=[10,5])
plt.subplot(121)
plt.hist2d(A_scaled[:,0],A_scaled[:,1],100,alpha=0.7)
plt.plot(t1,t2,'--k')
c=pca.components_
r=np.sqrt(pca.explained_variance_)
plt.arrow(0,0,c[0,0]*r[0],c[0,1]*r[0],color='red',head_width=.3)
plt.arrow(0,0,c[1,0]*r[1],c[1,1]*r[1],color='blue',head_width=.3)
# plt.axis('equal')
plt.title('before standarized')

t1=np.linspace(-20,20,100)
cov=np.cov(A_standarized.T)
t2=t1*cov[1,1]
plt.subplot(122)
plt.hist2d(A_standarized[:,0],A_standarized[:,1],100,alpha=0.7)
plt.plot(t1,t2,'--k')
c=pca1.components_
r=np.sqrt(pca1.explained_variance_)
plt.arrow(0,0,c[0,0]*r[0],c[0,1]*r[0],color='red',head_width=.2)
plt.arrow(0,0,c[1,0]*r[1],c[1,1]*r[1],color='blue',head_width=.2)
# plt.axis('equal')
plt.title('after standarized')
plt.show()
SofaSofa数据科学社区DS面试题库 DS面经

Zealing   2019-04-30 21:17

2

PCA实现的方式其实有四种:

  • 标准化数据后的协方差矩阵
  • 标准化数据后的相关系数矩阵
  • 未标准化数据后的相关系数矩阵
  • 标准化数据后的svd方式

这四种方式是等价的。

SofaSofa数据科学社区DS面试题库 DS面经

zhanglu   2018-03-28 12:58

1

不标准化的PCA就是TruncatedSVD,其实不标准化也行吧。

SofaSofa数据科学社区DS面试题库 DS面经

奶瓶他哥   2019-04-26 16:33



  相关主题

Truncated SVD和PCA有什么区别吗?   1回答

利用PCA降维,降到几维比较合适?   1回答

除了PCA,还有什么降维的方法?   11回答

PCA会降低分类器的精度吗?   3回答

PCA的目标函数   1回答

一个关于PCA与eigenvector的问题   2回答

为什么PCA被称作非监督式学习?   2回答

PCA降维中的特征值和特征向量   2回答

PCA算法是一种保距算法吗?   1回答

PCA与非负矩阵分解(NMF)的异同?   0回答

PCA需要正态性作为提前假设吗?   1回答

PCA和SVD是一回事吗?   1回答



回答问题时需要注意什么?

我们谢绝在回答前讲“生动”的故事。

我们谢绝“这么简单,你自己想”、“书上有的,你认真看”这类的回答;如果你认为对方的提问方式或者内容不妥,你可以直接忽略该问题,不用进行任何作答,甚至可以对该问题投反对票。

我们谢绝答非所问。

我们谢绝自己不会、硬要回答。

我们感激每一个用户在编写答案时的努力与付出!