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

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

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

 

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



   4个回答 
31

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
5

没做标准化的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



  相关讨论

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

用pca对数据集降维时为什么一定要训练集和测试集?

Truncated SVD和PCA有什么区别吗?

主成分分析法(PCA)算是黑盒算法吗?

PCA算法是一种保距算法吗?

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

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

sklearn pca 数据降维结果不一致

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

sklearn.decomposition.PCA方法中fit, fit_transform, transform应该怎么用

  随便看看

怎么直观理解ROC AUC的概率统计意义?

sklearn模型当中的verbose是什么意思?

numpy.array从行向量转为列向量

matplotlib.pyplot做折线图的时候,显示为虚线,或者点划线?

huber loss是什么?什么时候用?