PCA主成分分析

1、PCA算法:

PCA过程的实现:(1)numpy可以模拟        (2)sklearn可以实现

1.1、使用numpy模拟PCA过程

import numpy as np

A=np.array([[3,2000],
           [2,3000],
           [4,5000],
           [5,8000],
           [1,2000]],dtype='float')

#使用numpy模拟PCA过程

#数据降维
#1、数据归一化
mean=np.mean(A,axis=0)#axis=0所有行
norm=A-mean
#2、数据缩放 因为两个特征不是一个数量级
scope=np.max(norm,axis=0)-np.min(norm,axis=0)
norm=norm/scope
#3、对协方差矩阵进行奇异值分解,求解其特征向量
U,S,V=np.linalg.svd(np.dot(norm.T,norm))
#4、因为需要将二维数据降为一维,因此取特征矩阵的第一列来构造主成分矩阵
U_reduce=U[:,:1]#等价于U[:,0].reshape(2,1)#提取1列,却返回了1行,所以需要再转换成1列
#5、开始降维
R=np.dot(norm,U_reduce)#要将训练集投影到超平面上,简单地计算训练集矩阵norm和矩阵U_reduce的点积即可

#降维数据还原
#1、升维
Z=np.dot(R,U_reduce.T)
#2、数据缩放和归一化还原
A_restore=np.multiply(Z,scope)+mean#np.multiply是矩阵的点乘运算

与原始矩阵A相比,恢复后的A_restore存在失真,但这是不可避免的

输出R:

1.2、使用sklearn进行PCA过程

#使用sklearn进行PCA过程

from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler

#约定俗成:
#*args:可以理解为长度不固定的列表。
#**kwarg:可以理解为长度不固定的字典
#**argv:获取参数

def std_PCA(**argv):
    scaler=MinMaxScaler()
    pca=PCA(**argv)
    pipeline=Pipeline([('scaler',scaler),('pca',pca)])
    return pipeline

pca=std_PCA(n_components=1)
R2=pca.fit_transform(A)

输出R2:

sklearn降维输出的数值和numpy降维输出的数值符号相反,这不是错误,是降维选择的坐标方向不同而已。

降维数据还原如下:

R2_restore=pca.inverse_transform(R2)#先进行PCA还原,再进行预处理的逆运算

还原的数据:

 原来的数据A:

 2、PCA的物理含义

方形点:原始数据经过预处理后(归一化、缩放)的数据。

圆形点:一维恢复到二维后的数据。

u(1)、u(2):主成分特征向量。

 结论:

(1)圆形点实际上就是方形点在向量 U(1)所在的直线上的投射点,降维就是方形点在主成分特征向量U(1)上的投影。

(2)PCA数据恢复,不是真正的恢复,只是把降维后的坐标转换为原坐标系中的坐标而已。

(3)主成分特征的向量U(1)、U(2)是相互垂直的

(4)方形点和圆形点之间的距离是PCA数据降维后的误差

3、PCA属性

3.1 特征方差贡献率和特征方差

#pca的方法explained_variance_ratio_计算了每个特征方差贡献率,所有总和为1,
#explained_variance_为方差值,通过合理使用这两个参数可以画出方差贡献率图
#或者方差值图,便于观察PCA降维最佳值。

pca1=PCA(n_components=1)
pca1.fit_transform(A)

print("方差值:{0}".format(pca1.explained_variance_))
print("方差解释率:{0}".format(pca1.explained_variance_ratio_))
print("主成分向量数:{0}".format(pca1.n_components_))

 表示第一条轴贡献了99.99999991%,剩下的第二条轴还不到0.00000001%,有理由认为它没什么信息

3.2 如何确定正确数量的维度

方法一、将靠前的主成分方差解释率依次相加,直到得到足够大比例的方差(例如 95%),这时的维度数量就是很好的选择。

pca=PCA()
pca.fit(X)
cumsum=np.cumsum(pca.explained_variance_ratio_)
d=np.argmax(cumsum>=0.95)+1

pca_final=PCA(n_components=d)
pca_final.fit(X)

方法二、n_components设置为0.0到1.0之间的浮点数,表示希望保留的方差比

pca=PCA(n_components=0.95)
X_reduced=pca.fit_transform(X)

方法三、解释方差可视化

 3.3 增量PCA(IPCA)

from sklearn.datasets import fetch_openml
mnist=fetch_openml("mnist_784",data_home="C:/Users/EDZ/PycharmProjects/datasets/")
X_mnist=mnist.data

方法一、使用NumPy的array_split()函数拆分数据 

import numpy as np
from sklearn.decomposition import IncrementalPCA

n_batches=100
inc_pca=IncrementalPCA(n_components=154)
for x_batches in np.array_split(X_mnist,n_batches):
    inc_pca.partial_fit(x_batches)
X_mnist_reduced=inc_pca.transform(X_mnist)

 方法二、使用NumPy的memmap类

这个类允许你巧妙地操控一个存储在磁盘二进制文件里的大型数组,就好似它也完全在内存里 一样,而这个类(memmap)仅在需要时加载内存中需要的数据。由于IncrementalPCA在任何时间都只使用数组的一小部分,因此内存的使用情况仍然受控。

x_mm=np.memmap(filename,dtype='float32',mode='readonly',shape=(m,n))

n_batches=100
batch_size=x_mm/n_batches
inc_pca=IncrementalPCA(n_components=154,batch_size=batch_size)
inc_pca.fit()

 3.4 随机PCA

可以快速找到前d个主成分的近似值。计算复杂度是是O(m×d2)+O(d3)

rnd_pca=PCA(n_components=164,svd_solver='randomized')
X_reduced=rnd_pca.fit_transform(X)

3.5 核PCA

核技巧:将低维数据映射到高维的空间

from sklearn.decomposition import KernelPCA

rbf_PCA=KernelPCA(n_components=2,kernel="rbf",gamma=0.04)
X_reduced=rbf_PCA.fit_transform(X)

3.5.1 选择核函数核调整超参数

方法一、用GridSearchCV搜索最优参数

kPCA是一种无监督的学习算法,因此没有明显的性能指标来帮助选择最佳的核函数和超参数值。

降维是监督式学习任务的准备步骤,所以可以结合起来用网格搜索来选择最佳的核函数和超参数值。

from sklearn.decomposition import KernelPCA
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression

clf=Pipeline([('kcpa',KernelPCA(n_components=2)),
              ('log_reg',LogisticRegression)])
param_grid=[{
    'kcpa__gamma':np.linspace(0.03,0.05,10),
    'kcpa__kernel':['rbf','Sigmoid']
}]
grid_search=GridSearchCV(clf,param_grid=param_grid)
grid_search.fit(x,y)

#获得最优参数
grid_search.best_params_

方法二、找到使重建原像和原始图像误差最小的核和超参数

from sklearn.decomposition import KernelPCA

rbf_cpa=KernelPCA(n_components=2,kernel='rbf',gamma=0.0433,fit_inverse_transform=True)
X_reduced=rbf_cpa.fit_transform(X)
X_preimage=rbf_cpa.inverse_transform(X_reduced)
#默认情况下为fit_inverse_transform=False,并且KernelPCA没有inverse_transform()方法。只有在设置fit_inverse_transform=True
#时才会创建该方法。

#计算原像与重建原像的误差
from sklearn.metrics import mean_squared_error
mean_squared_error(X,X_preimage)

然后用网格搜索寻找最小误差的参数

5.6 局部线性嵌入LLE——流形学习技术

局部线性嵌入(LLE)是另一种非常强大的非线性降维(NLDR)技术

LLE首先测量每个算法如何与其最近的邻居线性相关,然后为训练集寻找一个能最大程度保留这些局部关系的低维表示。这使得它特别擅长展开弯曲的流形,特别是没有太多噪声时。

LLE算法主要分为三步:

        第一步是求K近邻的过程,这个过程使用了和KNN算法一样的求最近邻的方法。

        第二步,就是对每个样本求它在邻域里的K个近邻的线性关系,得到线性关系权重系数W。

        第三步就是利用权重系数来在低维里重构样本数据 

from sklearn.manifold import LocallyLinearEmbedding

lle=LocallyLinearEmbedding(n_components=2,n_neighbors=10)
X_reduced = lle.fit_transform(X)

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值