主成分分析(PCA)的原理与实现

主成分分析(PCA)的原理与实现

问题背景
Iris 鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常被用作示例。如下图所示,数据集内包含 3 类共 150 条记录,每类各 50 个数据,每条记录都有 4 项特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度,可以通过这4个特征预测鸢尾花卉属于(iris-setosa, iris-versicolour, iris-virginica)中的哪一品种。如何预测并可视化?
在这里插入图片描述

再比如,人脸是由许多像素组成的高维数据。高维数据很难处理,因为不能用二维数据的散点图等简单技术进行可视化。如何对人脸图片进行压缩和预处理操作?

数据降维

假设我们现在正在收集数据,我们的数据集产生了多个变量、多个特征,所有这些都会在不同方面影响结果。我们可能会选择删除某些特征,但这意味着会丢失信息。

因此我们开源使用另一种减少特征数量(减少数据维数)的方法,通过提取重要信息并删除不重要的信息来创建新的特征,这样,我们的信息就不会丢失,但起到减少特征的作用,而我们模型的过拟合几率也会减少。

PCA简介

主成分分析(Principal Component Analysis,PCA)是最常用的一种降维方法,通常用于高维数据集的探索与可视化,还可以用作数据压缩和预处理等(例如:用于人脸识别的预处理,PCA+SVM即可实现简单的人脸识别,准确度可以达到81%)。

PCA的数学原理

PCA就是去找主成分,而主成分的标准具备两个条件:一是互不相关(注意不相关可不等于互相独立,这里只保证没有线性关系);二是用来描述数据的时候,方差尽可能大,也就是数据投影过去之后,离得尽可能远。

第一个条件,互不相关,就是要找一组主成分使得彼此之间的协方差为0。协方差就是一种用来度量两个随机变量关系的统计量。同一元素的协方差就表示该元素的方差, 不同元素之间的协方差就表示它们的相关性,此条件的数学证明如下:
在这里插入图片描述
如果两个属性都做了去中心化处理(即X-X.mean,使数据的平均值为0,物理意义是将数据的重点移动到坐标原点),则协方差矩阵为(中心化矩阵的协方差矩阵公式)
在这里插入图片描述

多维协方差矩阵:
在这里插入图片描述
协方差衡量了(X,Y,X)之间任意两属性之间的关系,以X,Y二者举例:

当cov(X,Y)>0时,表示X和Y正相关

当cov(X,Y)= 0时,表示X和Y不相关

当cov(X,Y)<0时,表示X和Y负相关

到这里,我们便完成了协方差矩阵对角化。顺便可以求出矩阵的特征值和特征向量,之后根据矩阵的特征值和特征向量进行协方差相似对角化,这样,我们只要把特征值从大到小,对应的特征向量从上到下排列,则用前K行组成的矩阵乘以原始矩阵X, 就得到了我们需要的降维后的数据矩阵Y。

PCA求解步骤

输入:数据集或者图片,需要降到k维

1、加载数据,并将数据去中心化(即把X和Y的均值变为0),此时两个基的协方差cov(X,Y)为0,两个基之间没有相关性;

2、计算协方差矩阵C,即C=1/mX_normX_norm.T,np表示为np.dot(X.T,X)/X.shape[0];

3、计算C的特征值与特征向量,把特征值从大到小排列,对应的特征向量从上往下排列;

4、将协方差矩阵相似对角化;

5、取特征向量的前K个(n_components=k),得到k个基

6、用这k个基与X矩阵相乘,得到降维后的k维矩阵Y

在这里插入图片描述
代码块

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
'''
iris=load_iris()
print(iris)
'''

#方法一,numpy

class PCA():
    def __init__(self,n_components):  #components:成分
        self.n_components=n_components

    def fit_transform(self,X):  #iris.data.shape=[150,4]
        self.n_feature=X.shape[1]   #[150,4]中的4指四类属性,即 'feature_names': ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

        #求协方差矩阵
        X=X-X.mean(axis=0)  #样本归一化,并将均值归0
        self.covariance=np.dot(X.T,X)/X.shape[0]  #covariance;协方差

        #求协方差矩阵的特征值和特征向量
        eig_vals,eig_vectors=np.linalg.eig(self.covariance)  #eig_vals:特征值,eig_vectors:特征向量, np.linalg.eig:使用eig函数求解特征值、特征向量

        #获取降序排列特征值的序号
        idx=np.argsort(-eig_vals) #argsort()函数,返回的是数组值从小到大的索引值

        #降维矩阵
        self.components_=eig_vectors[:,idx[:self.n_components]]

        #对X降维
        return np.dot(X,self.components_)

#调用
pca=PCA(n_components=2)
iris=load_iris()
X=iris.data
newX=pca.fit_transform(X)
print(newX)
#print(iris.target)

'''
#方法二:调用sklearn中已经集成好了的PCA工具
from sklearn.decomposition import PCA

#调用
pca=PCA(n_components=2)
iris=load_iris()
X=iris.data
newX=pca.fit_transform(X)
print(newX)

'''

#可视化
color=['red','blue','orange']
plt.figure()
for i in [0,1,2]:
    plt.scatter(newX[iris.target==i,0],newX[iris.target==i,1],c=color[i],label=iris.target_names[i])
plt.legend()
plt.title('PCA of iris datasets')
plt.xlabel('pc_0')
plt.ylabel('pc_1')
plt.show()

参考资料:
1、https://mp.weixin.qq.com/s/uAlBtGTmtBSjcnp9bWQr5Q
2、https://mp.weixin.qq.com/s/Xt1vLQfB20rTmtLjiLsmww
3、https://www.jb51.net/article/181205.htm
4、https://mp.weixin.qq.com/s/PXzJN7hvDYE_P0XCAuyTHw

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值