PCA主成分分析

PCA降维算法

目前图像特征的提取主要有两种方法:传统图像特征提取方法 和 深度学习方法。

  1. 传统的特征提取方法:基于图像本身的特征进行提取(PCA);
  2. 深度学习方法:基于样本自动训练出区分图像的特征分类器;

特征选择(feature selection)和特征提取(Feature extraction)都属于降维(Dimension reduction)

特征提取:

特征提取的主要方法:主要目的是为了排除信息量小的特征,减少计算量等:

主成分分析(PCA)

PCA算法是如何实现的

问题的关键在于如何求新的基(a,b,c)?

步骤:

  1. 对原始数据零均值化(中心化),
  2. 求协方差矩阵,
  3. 对协方差矩阵求特征向量和特征值,这些特征向量组成了新的特征空间。

1. PCA——零均值化(中心化):

把所有的变量都去减掉他们的均值,使得减完之后得到的数据集均值为0,其实本质就是一个平移的过程,平移后得到的所有数据的中心是(0,0)

只有“中心化”数据之后,计算得到的方向才能比较好的“概括”原来的数据。
下图描述了“中心化”的几何意义,即将样本集的中心平移到坐标系的原点0上

2. PCA——PCA降维的几何意义

对于一组数据,如果它在某一坐标轴上的方差越大,说明坐标点越分散,该属性就能够比较好地反映源数据。

由于不同维度之间相关性应为0,由此便引出协方差概念

3. PCA——协方差

协方差是用来度量两个随机变量关系的统计量
同一元素的协方差就表示该元素的方差,不同元素之间的协方差就表示它们的相关性
协方差>0 , 表示X和Y正相关
协方差=0 , 表示X和Y不相关(我们要找的就是这个点)
协方差<0 , 表示X和Y负相关

4. PCA——协方差矩阵

定义:

特别的,如果做了中心化,则协方差矩阵为(中心化矩阵的协方差矩阵公式,m为样本个数):

5. PCA——对协方差矩阵求特征值,特征矩阵

A为n阶矩阵(在应用中,A为协方差矩阵),若数λ和n维非0列向量x满足Ax=λx,那么数λ称为A的特征值,x称为A的对应于特征值λ 的特征向量。
式Ax=λx也可写成( A-λE)x=0,E是单位矩阵,并且|A-λE|叫做A 的特征多项式。当特征多项式等于0的 时候,称为A的特征方程,特征方程是一个齐次线性方程组,求解特征值的过程其实就是求解特征方程的解。
对于协方差矩阵A,其特征值( 可能有多个)计算方法为:

6. PCA——对特征值进行排序

7. PCA——评价模型的好坏,k值的确定

通过特征值的计算我们可以得到主成分所占的百分比,用来衡量模型的好坏。
对于前k个特征值所保留下的信息量计算方法如下:

8. PCA——代码实现

1. 手动实现

# -*- coding: utf-8 -*-
"""
使用PCA求样本矩阵X的K阶降维矩阵Z
"""import numpy as npclass CPCA(object):'''用PCA求样本矩阵X的K阶降维矩阵ZNote:请保证输入的样本矩阵X shape=(m, n),m行样例,n个特征'''def __init__(self, X, K):''':param X,训练样本矩阵X:param K,X的降维矩阵的阶数,即X要特征降维成k阶'''self.X = X       #样本矩阵Xself.K = K       #K阶降维矩阵的K值self.centrX = [] #矩阵X的中心化self.C = []      #样本集的协方差矩阵Cself.U = []      #样本矩阵X的降维转换矩阵self.Z = []      #样本矩阵X的降维矩阵Zself.centrX = self._centralized()self.C = self._cov()self.U = self._U()self.Z = self._Z() #Z=XU求得def _centralized(self):'''矩阵X的中心化'''print('样本矩阵X:\n', self.X)centrX = []mean = np.array([np.mean(attr) for attr in self.X.T]) #样本集的特征均值print('样本集的特征均值:\n',mean)centrX = self.X - mean ##样本集的中心化print('样本矩阵X的中心化centrX:\n', centrX)return centrXdef _cov(self):'''求样本矩阵X的协方差矩阵C'''#样本集的样例总数ns = np.shape(self.centrX)[0]#样本矩阵的协方差矩阵CC = np.dot(self.centrX.T, self.centrX)/(ns - 1)print('样本矩阵X的协方差矩阵C:\n', C)return Cdef _U(self):'''求X的降维转换矩阵U, shape=(n,k), n是X的特征维度总数,k是降维矩阵的特征维度'''#先求X的协方差矩阵C的特征值和特征向量a,b = np.linalg.eig(self.C) #特征值赋值给a,对应特征向量赋值给b。函数doc:https://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.linalg.eig.html print('样本集的协方差矩阵C的特征值:\n', a)print('样本集的协方差矩阵C的特征向量:\n', b)#给出特征值降序的topK的索引序列ind = np.argsort(-1*a)#构建K阶降维的降维转换矩阵UUT = [b[:,ind[i]] for i in range(self.K)]U = np.transpose(UT)print('%d阶降维转换矩阵U:\n'%self.K, U)return Udef _Z(self):'''按照Z=XU求降维矩阵Z, shape=(m,k), n是样本总数,k是降维矩阵中特征维度总数'''Z = np.dot(self.X, self.U)print('X shape:', np.shape(self.X))print('U shape:', np.shape(self.U))print('Z shape:', np.shape(Z))print('样本矩阵X的降维矩阵Z:\n', Z)return Zif __name__=='__main__':'10样本3特征的样本集, 行为样例,列为特征维度'X = np.array([[10, 15, 29],[15, 46, 13],[23, 21, 30],[11, 9,  35],[42, 45, 11],[9,  48, 5],[11, 21, 14],[8,  5,  15],[11, 12, 21],[21, 20, 25]])K = np.shape(X)[1] - 1print('样本集(10行3列,10个样例,每个样例3个特征):\n', X)pca = CPCA(X,K)

2. 利用numpy库封装好的函数简化代码

#coding=utf-8import numpy as np
class PCA():def __init__(self,n_components):self.n_components = n_componentsdef fit_transform(self,X):self.n_features_ = X.shape[1]# 求协方差矩阵X = X - X.mean(axis=0)self.covariance = np.dot(X.T,X)/X.shape[0]# 求协方差矩阵的特征值和特征向量eig_vals,eig_vectors = np.linalg.eig(self.covariance)# 获得降序排列特征值的序号idx = np.argsort(-eig_vals)# 降维矩阵self.components_ = eig_vectors[:,idx[:self.n_components]]# 对X进行降维return np.dot(X,self.components_)# 调用
pca = PCA(n_components=2)
X = np.array([[-1,2,66,-1], [-2,6,58,-1], [-3,8,45,-2], [1,9,36,1], [2,10,62,1], [3,5,83,2]])  #导入数据,维度为4
newX=pca.fit_transform(X)
print(newX)                  #输出降维后的数据

3. 利用sklearn库简化

#coding=utf-8import numpy as np
from sklearn.decomposition import PCA
X = np.array([[-1,2,66,-1], [-2,6,58,-1], [-3,8,45,-2], [1,9,36,1], [2,10,62,1], [3,5,83,2]])  #导入数据,维度为4
pca = PCA(n_components=2)   #降到2维
pca.fit(X)                  #训练
newX=pca.fit_transform(X)   #降维后的数据
# PCA(copy=True, n_components=2, whiten=False)
print(pca.explained_variance_ratio_)  #输出贡献率
print(newX)                  #输出降维后的数据

9. PCA——鸢尾花实例

我们通过Python的sklearn库来实现鸢尾花数据 进行降维,数据本身是4维的,降维后变成2维。
其中样本总数为150,鸢尾花的类别有三种。

#!/usr/bin/env python
# encoding=gbkimport matplotlib.pyplot as plt
import sklearn.decomposition as dp
from sklearn.datasets.base import load_irisx,y=load_iris(return_X_y=True) # 加载数据,x表示数据集中的属性数据,y表示数据标签
pca=dp.PCA(n_components=2) # 加载PCA算法,设置降维后主成分数目为2
reduced_x=pca.fit_transform(x) # 对原始数据进行降维,保存在reduced_x中
red_x,red_y=[],[]
blue_x,blue_y=[],[]
green_x,green_y=[],[]
for i in range(len(reduced_x)): # 按鸢尾花的类别将降维后的数据点保存在不同的表中if y[i]==0:red_x.append(reduced_x[i][0])red_y.append(reduced_x[i][1])elif y[i]==1:blue_x.append(reduced_x[i][0])blue_y.append(reduced_x[i][1])else:green_x.append(reduced_x[i][0])green_y.append(reduced_x[i][1])
plt.scatter(red_x,red_y,c='r',marker='x')
plt.scatter(blue_x,blue_y,c='b',marker='D')
plt.scatter(green_x,green_y,c='g',marker='.')
plt.show()

结果:

10. PCA——算法优缺点

优点:

  1. 完全无参数限制的。在PCA的计算过程中完全不需要人为的设定参数或是根据任何经验模型对计算 进行干预,最后的结果只与数据相关,与用户是独立的。
  2. 用PCA技术可以对数据进行降维,同时对新求出的“主元”向量的重要性进行排序,根据需要取前面 最重要的部分,将后面的维数省去,可以达到降维从而简化模型或是对数据进行压缩的效果。同时 最大程度的保持了原有数据的信息。
  3. 计算方法简单,易于在计算机上实现。

缺点:

  1. 如果用户对观测对象有一定的先验知识,掌握了数据的一些特征,却无法通过参数化等方法对处理 过程进行干预,可能会得不到预期的效果,效率也不高。

本文链接:https://my.lmcjl.com/post/2571.html

展开阅读全文

4 评论

留下您的评论.