principal components analysis(PCA)

PCA,即主成分分析,是一个很常见的降维方法(属于无监督学习),过去看到它总是对它避而远之,今天下定决心把它搞懂。

首先来看该篇博文对为什么要有降维原理技术的缘由和背景进行解释(这是一篇出色的博文)

在介绍PCA之前,先明确几点

首先,数据其实就是特征表示。在坐标轴上,一个点(即一个数据)由其不同坐标轴(或维度)的特征值决定。简单来说,一个data就是一个vector。

   | X | Y |...| Z |  <--- 特征(维度)
    --- --- --- ---
d1 |   |   |...|   |
d2 |   |   |...|   |
...

dn |   |   |...|   |

其中X,Y,....,Z为特征,而d1,d2,...,dn为数据。可以看书数据其实是由对应的特征值组成的。


再如上述图,可以看出该数据有两个特征cell1和cell2,故用cell1和cell2就可表示该数据了。

我们使用PCA的目的是将数据从n维特征降到k维特征。数据在拥有n维特征时,坐标空间拥有n个相互正交的basis,而在降成拥有k维特征时,坐标空间拥有k个相互正交的basis。本来由n个数值(这里已知每个数值是代表哪个特征,可解释)来表示成一个数据,现可由k个数值来表示一个数据。这k个数值不可解释,我们只知道它们可以最大程度地表示该数据。

下面还是借用该博文来进一步阐明PCA的原理


第一点我们已经在上面说明过了,从n维到k维度,即从n个正交坐标到k个正交坐标.
第二点,为什么要保留方差大的维度(坐标轴)呢?来看一个直观的图。

因为cell2方向上的方差很小,可以认为数据信息的冗余度(Redundancy)很大,因为方差小,代表数据集中在均值附近,可用均值来代替这些方差值。而cell1方向上方差很大,故可以将这些数据映射到cell1轴上,如下图所示。

第三点,提出了协方差(Covariance)的概念主要是为了reduce redundant information。关于协方差,具体可以看这篇博文。


如果两个随机变量协方差很大,说明他们produce a lot of redundancy,只保留其中一个即可。如果两个随机变量的随机变量的协方差很小,接近于0,那么它们可看做是不相关的。

接下来我们引入协方差矩阵和散度矩阵:
首先看看协方差的定义

注意,对于概率论来讲,X是随机变量,协方差是针对X的样本(xi)来计算的。但是实际应用时,X是代表特征的包含数据的向量,我们称之为特征矢量,就如最上面所看的X特征的列向量。

协方差矩阵


协方差矩阵一般用大小C来表示


散度矩阵


这里最重要的是注意数据集X的表示。它与最开始上面的数据表示反过来,即矩阵X的每一列代表一个数据,而每一行代表一个特征(维度)

  | d1 | d2 |...| dn |
   ---- ---- --- ----
X |    |    |...|    |
Y |    |    |...|    |
...
Z |    |    |...|    |

从这里可以看出散度矩阵等于协方差矩阵/(n-1),其中n为数据集数。
注意,我们通常使用散度矩阵来得到协方差矩阵的。

得到数据集X的协方差矩阵后,我们就有了一个明确的目标,即减小不同特征(维度)之间的冗余度(Redundancy)。换句话说,就是让covariance(Xi,Xj)(i≠j)接近于0,即使协方差矩阵除对角线以外的元素都为0。

协方差对角化有两个方法:
(1)特征值对角化法
(2)SVD分解法


这里我们有

我们现在来验证一下它的正确性:



在这里符号 ' 表示中心化,接着

矩阵P是矩阵Q的转置后去前k个向量。故有

故最后

即新的数据集Y的协方差是一个k×k的对角阵。


同样的,



其中:k表示取前k个值,(相应的维度也发生变化)

super note!!
根据代码来看,最后的出的新数据Y是等于PX',即新数据是原始数据降维投影到新坐标后再中心化或先中心化后再投影的。即

PCA的python实现代码

##Python实现PCA
import numpy as np

def pca(X,k):#k is the components you want

  #mean of each feature
  n_samples, n_features = X.shape

  mean=np.array([np.mean(X[:,i]) for i in range(n_features)])

  #normalization
  norm_X=X-mean

  #scatter matrix
  scatter_matrix=np.dot(np.transpose(norm_X),norm_X)

  #Calculate the eigenvectors and eigenvalues
  eig_val, eig_vec = np.linalg.eig(scatter_matrix)

  eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(n_features)]

  # sort eig_vec based on eig_val from highest to lowest
  eig_pairs.sort(reverse=True)

  # select the top k eig_vec
  feature=np.array([ele[1] for ele in eig_pairs[:k]])

  #get new data
  data=np.dot(norm_X,np.transpose(feature))

  return data

X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
print(pca(X,1))

最后一点感悟:果然还是要先把“内功”给修炼好,不然学习这些会很花时间,学习PCA就将近花了一天时间。

你可能感兴趣的:(principal components analysis(PCA))