CCIPCA:直观协方差无关增量式主成分分析算法

     CCIPCA是由密西根州立大学翁巨扬教授于2003年,在TPAMI上发表的论文,与传统的主成分分析(PCA)不同,CCIPCA在一个样本集的主成分过程中,不需要对样本的协方差矩阵进行评估,因此,存在Covariance-free这个特性。

 一、PCA(主成分分析) 

    我们回顾一下PCA算法:

    PCA算法对样本序列进行降维的原理,按照Pattern Reccognition And Maching Learning第十二章中定义有:"PCA can be defined as the orthogonal prejection of the data onto a lower dimentional linear space, known as the pricipal subspace, such that the variance of the projected data is maximized",翻译过来就是:将数据正交化投影到一个低维线性空间(主成分空间),使得投影后的数据方差最大。

     假定,现有一个数据集x_{1},x_{2},...,x_{n}, n=1,..., N,每个数据的维度为D。我们的目标是将数据投影到一个只有M(<D)维的空间,同时保证投影后的方差最大。我们先假设M已经给定,后面再讨论如何以一种合适的方式来决定投影后数据的维度。

    首先,考虑将数据投影到一个一维的空间,我们采用一个D维的向量u_{1}来表示投影后子空间的方向,由于我们仅仅对u_{1}所代表方向感兴趣,所以将u_{1}的模长设置为1,即u_{1}^{T}u_{1}=1,这样,将数据集中所有数据投影到u_{1}上之后,数据集的方差为:

                                                                \frac{1}{N}(u_{1}^{T}x_{n}-u_{1}^{T}\overline{x})=u_{1}^{T}Su_{1}

    其中S为数据集的方差矩阵:

                                                                 S = \frac{1}{N}\sum_{n=1}^{N}(x_{n}-\overline{x})                      

    现在问题就转换成求u_{1}^{T}u_{1}=1条件下,u_{1}^{T}Su_{1}的最大值,这里引入拉格朗日乘子:

                                                                f = u_{1}^{T}Su_{1} + \lambda _{1}(1-u_{1}^{T}u_{1})

   极大值和极小值应该位于导数为0的位置,因此,将f对u_{1}求偏导,并令其等于0得到:

                                                                 Su_{1} = \lambda _{1}u_{1}

    两边再同时乘以u_{1}^{^{T}}有:

                                                                 u_{1}^{T}Su_{1} = \lambda _{1}

    可以看到,投影后数据的方差等于\lambda _{1},也即是,如果u_{1}为方差矩阵最大特征值对应的特征向量,投影后的方差也最大,因此PCA算法计算,也即是计算样本方差矩阵的特征值及对应特征向量。    

二、CCIPCA算法推导

       假设,我们顺序的获取一个样本序列:u(1),u(2),...。每一个u(k),k= 1, 2, 3, .....为一个d维向量,然后将前n个样本减去均值,计算其协方差矩阵:

                                                            A(n)=\frac{1}{n}\sum_{i=1}^{n}(x_{i}(n)x_{i}^{T}(n))

     x_{i}(n)为样本减去均值后的残差量,按照PCA计算过程有:

                                                                 \lambda\alpha _{n} =A(n)\alpha _{n}

     其中,   \lambdaA(n) 的特征值,\alpha _{n}为对应特征向量,如果假定特征向量\alpha _{n}的模长近似等于特征值 \lambda大小,有:

                                                                 \alpha _{n} =\frac{A(n)\alpha _{n}}{||\alpha _{n}||}

     这里,最关键的步骤来了,PCA在计算特征值和特征向量时,样本集是已知的,也即是数据集中的所有样本都已知,计算过程直接就是求取样本集协方差矩阵的特征值和特征向量,这里需要计算协方差矩阵,计算量较大,同时,在实际应用场景中,数据序列的获取是序列的,比如,摄像头获取图片,也是一帧一帧获取的,完整数据集是无法得到的。

     因此,CCIPCA 采用了一种不计算协方差矩阵的方式,逐个样本对数据集的均值和特征向量进行更新,当前特征值计算是对特征值上一个状态的进一步评估:

                        \alpha _{i}(n) =\frac{n-1-a}{n}\alpha _{i} (n)+ \frac{1+a}{n}x_{i}(n)x_{i}^{T}(n)\frac{\alpha _{i} (n)}{||\alpha _{i}(n) ||}

                           x_{i+1}(n)=x_{i}(n)-x_{i}^{T}(n)\frac{\alpha _{i} (n)}{||\alpha _{i}(n) ||}\frac{\alpha _{i} (n)}{||\alpha _{i}(n) ||}

    其中a为遗忘方程,第二个式子理解过程可以参考一下Gram-Schimdt方法,相当于是剔除当前残差量在前一个特征向量上的投影量,相当于是去除掉当前残差量与当前特征向量之间的关联,这样,就降低了特征向量之间关联,使得特征向量间彼此正交,CCIPCA算法的目的是找到最判别的前k个特征向量,进而实现对数据的降维处理。

    具体流程如下:

     下面就是采用CCIPCA对yale库提取63个最判别特征向量的提取效果如图1所示,对应代码:MirrorYuChen/Developmental-Networks: Some Research C++ Codes on DN, following the works of Juyang Weng professor (github.com)

                                                                                             图1 CCIPCA算法

    C++版本的代码就不贴了,这里我贴一下我用python写的部分关键代码:   

def update(self, x):
        assert(x.shape[0] == 1)           
        
        # compute the mean imcrementally
        self._mean = float(self._n - 1) / self._n * self._mean + float(1) / self._n * x
        
        if self._n > 1:
            u = x - self._mean                 # reduce the mean vector
            [w1, w2] = self._amnestic(self._n)   # conpute the amnestic parameters
            k = min(self._n, self._output_dim)
            for i in range(k):  # update all eigenVectors
                v = self._eigenVectors[i,:].copy()  # get the current eigenVector
                if(i == k - 1):
                    v = u.copy()
                    vn = v / np.linalg.norm(v) # normalize the vector
                else:                    
                    v = w1 * v + w2 * np.dot(u, v.T)/ np.linalg.norm(v) * u # update the eigenVector
                    vn = v / np.linalg.norm(v) # normalize the vector

                u = u -  np.dot(u, vn.T) * vn # remove the projection of u on the v
                self._eigenVectors[i,:] = v.copy()  
                
        self._n += 1  # update the mean of the data   

  对Mninst数据集提取20个特征向量,效果如图2所示。

     

                                                   图2 CCIPCA 对Mnist数据集提取前20个最判别特征向量

    如果有需要完整代码的,请留言,哈哈哈哈~~~~~

    三、IBDPCA算法 

  

                                                            图3 IBDPCA算法工作原理示意图(摘自文献[3]) 

   IBDPCA算法相当于就是将图像每一行和每一列都视为一个单独的数据,然后进行CCIPCA,提取K个最判别特征向量。这样,IBDPCA在提取到最判别特征分量之后,计算n个样本X在特征分量上投影。

    python源码已经上传github: https://github.com/1976277169/CCIPCA/tree/master

    未完待续~~~

参考文献:

[1] Abramson N, Braverman D, Sebestyen G. Pattern Recognition and Machine Learning[M]. Springer, 2006.

[2] Weng J, Zhang Y, Hwang W S. Candid covariance-free incremental principal component analysis[J]. IEEE Transactions on Pattern Analysis & Machine Intelligence, 2003, 25(8):1034-1040.

[3] 王肖锋, 张明路, 刘军. 基于增量式双向主成分分析的机器人感知学习方法研究, 2017年11月27日[J]. 电子与信息学报, 2018, 40(3):618-625.

      

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值