数据降维之PCA方法与python实现

基本数学知识

  • 向量内积:通过内积可以判断两个数据信息之间的相关性
    设两个向量: a 1 → = ( x 1 , y 1 ) , a 2 → = ( x 2 , y 2 ) \overrightarrow{a_{1}}=\left(x_{1}, y_{1}\right), \overrightarrow{a_{2}}=\left(x_{2}, y_{2}\right) a1 =(x1,y1),a2 =(x2,y2),夹角为 θ \theta θ
    a ⃗ ⋅ b ⃗ = ∣ a ⃗ ∣ ∗ ∣ b ⃗ ∣ ∗ cos ⁡ θ \vec{a} \cdot \vec{b}=|\vec{a}| *|\vec{b}| * \cos \theta a b =a b cosθ
  • 矩阵转置:矩阵A的行和列互相交换所产生的矩阵称为A的转置矩阵
    A = [ a 11 a 12 a 21 a 22 ] A=\left[\begin{array}{ll}a_{11} & a_{12} \\ a_{21} & a_{22} \end{array}\right] A=[a11a21a12a22] A T = [ a 11 a 21 a 12 a 22 ] A^{T}=\left[\begin{array}{ll}a_{11} & a_{21} \\ a_{12} & a_{22} \end{array}\right] AT=[a11a12a21a22]
  • 对称矩阵: A = A T A=A^{T} A=AT
  • 矩阵的逆:设A是数域上的一个n阶方阵,若在相同的数域上存在另一个n阶方阵B,使得AB=BA=E,那么称B为A的逆矩阵,记作 A − 1 A^{-1} A1,而A被称为可逆矩阵或非奇异矩阵。如果A不存在逆矩阵,那么A称为奇异矩阵。
  • 特征值、特征向量:定义为: A x = λ x Ax=\lambda x Ax=λx x x x为特征向量, λ \lambda λ为特征值
    ∣ λ E − A ∣ = 0 |{\lambda} E-A|=0 λEA=0 ( λ E − A ) x = 0 ({\lambda} E-A)x=0 (λEA)x=0
  • 特征值分解:矩阵A的n个特征值 λ 1 ≤ λ 2 ≤ . . . ≤ λ n \lambda_{1}≤\lambda_{2}≤...≤\lambda_{n} λ1λ2...λn,以及这n个特征值所对应的特征向量 w 1 , w 2 , . . . w n {w_1,w_2,...w_n} w1,w2,...wn,如果这n个特征向量线性无关,那么矩阵A就可以用下式的特征分解表示: A = W Σ W − 1 A=W{\Sigma}W^{-1} A=WΣW1
    W是这n个特征向量所张成的n×n维矩阵,并对n个特征向量标准化,而Σ为这n个特征值为主对角线的n×n维矩阵。若A为实对称矩阵,另有
    A = W Σ W T A=W{\Sigma}W^{T} A=WΣWT

SVD

  • 特征值分解只可以在方阵中进行处理,不能应用的非方阵中 .特征值分解可以利用到降维的处理中,提升使用效率,但是大多数矩阵都是非方阵形式,所以不可能进行特征值分解: A = W Σ W T A=W\Sigma W^{T} A=WΣWT,这里应运而生SVD(奇异值)分解 ,可以解决非方阵使用特征值分解的方法,这种方法被称作奇异值分解。
  • 奇异值分解(SVD, singular value decomposition),一种对矩阵较好的分解形式

算法理论

  • 矩阵的奇异值分解是指,将一个非零的m×n实矩阵A, A ∈ R m × n A∈R_{m×n} ARm×n,表示为以下三个实矩阵乘积形式 的运算,即进行矩阵的因子分解: A = U Σ V T A=U\Sigma V^{T} A=UΣVT
  • 其中U是m阶正交矩阵,V是n阶正交矩阵,Σ是由降序排列的非负的对角元素组成的m×n矩形对角 矩阵,满足:
    U U T = I V V T = I Σ = diag ⁡ ( σ 1 , σ 2 , ⋯   , σ p ) σ 1 ≥ σ 2 ≥ ⋯ ≥ σ p ≥ 0 p = min ⁡ ( m , n ) \begin{array}{l} U U^{T}=I \\ V V^{T}=I \\ \Sigma=\operatorname{diag}\left(\sigma_{1}, \sigma_{2}, \cdots, \sigma_{p}\right) \\ \sigma_{1} \geq \sigma_{2} \geq \cdots \geq \sigma_{p} \geq 0 \\ p=\min (m, n) \end{array} UUT=IVVT=IΣ=diag(σ1,σ2,,σp)σ1σ2σp0p=min(m,n)
  • U Σ V T UΣV^{T} UΣVT 称为矩阵A的奇异值分解, σ i σ_i σi称为矩阵A的奇异值,U的列向量称为左奇异向量,V的列向量称 为右奇异向量。
  • 注意奇异值分解不要求矩阵A是方阵。
  • 正常求上面的U,V,Σ不便于求,我们可以利用如下性质:
    A A T = U Σ V T V Σ T U T = U Σ Σ T U T A A^{T}=U \Sigma V^{T} V \Sigma^{T} U^{T}=U \Sigma \Sigma^{T} U^{T} AAT=UΣVTVΣTUT=UΣΣTUT
    A T A = V Σ T U T U Σ V T = V Σ T Σ V T A^{T} A=V \Sigma^{T} U^{T} U \Sigma V^{T}=V \Sigma^{T} \Sigma V^{T} ATA=VΣTUTUΣVT=VΣTΣVT
  • 这里 Σ Σ T ΣΣ^{T} ΣΣT Σ T Σ Σ^{T}Σ ΣTΣ在矩阵的角度上来讲,它们是不相等的,因为它们的维数不同 Σ Σ T ΣΣ^{T} ΣΣT∈R_{m×m},而 Σ T Σ Σ^{T}Σ ΣTΣ∈R_{n×n},但是它们在主对角线的奇异值是相等的
    Σ Σ T = ( σ 1 2 0 0 0 0 σ 2 2 0 ⋮ 0 0 ⋱ 0 0 … 0 σ m 2 ) m × m \Sigma\Sigma^{T} = \left ( \begin{matrix} \sigma_{1}^{2} & 0 & 0 & 0 \\ 0 & \sigma_{2}^{2} & 0 & \vdots \\ 0 & 0 & \ddots & 0 \\ 0 & \ldots & 0 & \sigma_{m}^{2} \end{matrix} \right )_{m×m} ΣΣT=σ120000σ22000000σm2m×m
    Σ T Σ = ( σ 1 2 0 0 0 0 σ 2 2 0 ⋮ 0 0 ⋱ 0 0 … 0 σ n 2 ) n × n \Sigma^{T}\Sigma = \left ( \begin{matrix} \sigma_{1}^{2} & 0 & 0 & 0 \\ 0 & \sigma_{2}^{2} & 0 & \vdots \\ 0 & 0 & \ddots & 0 \\ 0 & \ldots & 0 & \sigma_{n}^{2} \end{matrix} \right )_{n×n} ΣTΣ=σ120000σ22000000σn2n×n
  • 奇异值分解是一种矩阵因子分解方法,是线性代数概念,但在统计学习中被广泛使用,成为其重要 工具。
  • 应用:主成分分析、潜在语义分析
  • 矩阵的奇异值分解一定存在,但不唯一。奇异值分解可以看做矩阵数据压缩的一种方法。

SVD小例子

实现一张图的(R,G,B)通道简单分解,相当于打码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from PIL import Image
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import Binarizer
from sklearn.decomposition import PCA,TruncatedSVD

class SVD_():
    def __init__(self):
        pass

    def restore1(self,u,sigma,v,k):
        #refactoring image
        a = np.dot(u[:,:k],np.diag(sigma[:k])).dot(v[:k,:])
        a[a<0] = 0
        a[a>255] = 255
        return np.rint(a).astype('uint8')

    def main_(self):
        A = Image.open(r'data/godness.jpg')
        a = np.array(A)
        u_r,sigma_r,v_r = np.linalg.svd(a[:,:,0])
        u_g,sigma_g,v_g = np.linalg.svd(a[:,:,1])
        u_b,sigma_b,v_b = np.linalg.svd(a[:,:,2])
        plt.figure(facecolor='w',figsize=(10,10))
        #Number of singular values in sequence from 1 to 20
        K = 20
        for k in range(1,K+1):
            R = self.restore1(u_r,sigma_r,v_r,k)
            G = self.restore1(u_g,sigma_g,v_g,k)
            B = self.restore1(u_b,sigma_b,v_b,k)
            I = np.stack((R,G,B),axis=2)
            plt.subplot(5,4,k)
            plt.imshow(I)
            plt.axis('off')
            plt.title('奇异值个数:%d'%k)
        plt.suptitle('SVD与图像分解',fontsize=20)
        plt.tight_layout(0.1,rect=(0,0,1,0.92))
        plt.show()

if __name__=='__main__':
	svd = SVD_()
	svd.main_()

PCA

  • PCA是一种无监督学习的降维技术
  • 信噪比:信噪比就是信号与噪声的方差比,在信号处理中认为信号具有较大方差,而噪声的方差应尽量小,因此,信噪比越大越好
  • 做法:将所有的样本点向一条直线进行投影;让投影后样本的方差达到最大,即让投影后的样本尽量分散

算法理论

计算过程

这里先举个小例子理解PCA的计算过程:

x2.50.52.21.93.12.3211.51.1
y2.40.72.92.23.02.71.61.11.60.9
  • 第一步分别求 x x x y y y的平均值,然后对于所有样例都减去对应均值(这里只减去了均值,还应该对数据除以方差,进行归一化处理),得到:
x0.69-1.310.390.091.290.490.19-0.81-0.31-0.71
y0.49-1.210.990.291.090.79-0.31-0.81-0.31-1.01
  • 第二步,求特征协方差矩阵:
    c o v = ( c o v ( x , x ) c o v ( x , y ) c o v ( y , x ) c o v ( y , y ) ) = ( 0.616555556 0.615444444 0.615444444 0.716555556 ) c o v=\left(\begin{array}{cc} cov(x,x) & cov(x,y) \\ cov(y,x) & cov(y,y) \end{array}\right)=\left(\begin{array}{cc} 0.616555556 & 0.615444444 \\ 0.615444444 & 0.716555556 \end{array}\right) cov=(cov(x,x)cov(y,x)cov(x,y)cov(y,y))=(0.6165555560.6154444440.6154444440.716555556)
  • 第三步,对协方差矩阵求特征值与特征向量:
    e i g _ v a l u e s = ( 0.0491 1.284 ) eig\_values= \left(\begin{array}{cc} 0.0491 \\ 1.284 \end{array}\right) eig_values=(0.04911.284)
    e i g _ v e c t o r s = ( − 0.7352 − 0.67787 0.67789 − 0.7352 ) eig\_vectors=\left(\begin{array}{cc} -0.7352 & -0.67787 \\ 0.67789 & -0.7352 \end{array}\right) eig_vectors=(0.73520.677890.677870.7352)
  • 第四步,将特征值从大到小顺序排序,选择其中最大的 k k k个,然后将其 k k k个特征向量分别作为列向量组成特征向量矩阵。
    这里的特征只有两个,选取最大的那个,即1.284,对应特征向量为 ( − 0.67787 , − 0.7352 ) T (-0.67787,-0.7352)^T (0.67787,0.7352)T
  • 第五步,将样本点投影到选取的特征向量上,假设样本个数为 m m m,特征数为 n n n,减去均值后的样本矩阵为 W m × n W_{m×n} Wm×n,协方差矩阵 c o v n × n cov_{n×n} covn×n,选取的 k k k个特征向量组成的矩阵为 E V n × k EV_{n×k} EVn×k,则投影后的数据为:
    d a t a m × k = W m × n ⋅ E V n × k data_{m×k}=W_{m×n} \cdot EV_{n×k} datam×k=Wm×nEVn×k
    所以,这里投影后的数据计算是:
    d a t a 10 × 1 = W 10 × 2 ⋅ E V 2 × 1 data_{10×1}=W_{10×2} \cdot EV_{2×1} data10×1=W10×2EV2×1
    计算得到:
    d a t a = ( − 0.82797 , 1.77758 , − 0.992197 , … , 0.438046 , 1.22382056 ) data=(-0.82797,1.77758,-0.992197,\ldots,0.438046,1.22382056) data=(0.82797,1.77758,0.992197,,0.438046,1.22382056)

这样,原始数据就从2维变成了1维。

理论基础

投影

在这里插入图片描述
红色点表示样例 x ( i ) x^{(i)} x(i),蓝色点表示 x ( i ) x^{(i)} x(i) u u u上的投影, u u u 是直线的斜率也是直线的方向向量,而且是单位向量。蓝色点是 x ( i ) x^{(i)} x(i) u u u 上的投影点,离原点的距离是 < x ( i ) , u > <x^{(i)},u> <x(i),u>(即 x ( i ) T u x^{(i)^{T}}u x(i)Tu或者 u T x ( i ) ) u^{T}x^{(i)}) uTx(i)),由于这些样本点(样例)的每一维特征均值都为 0,因此投影到 u 上的样本点(只有一个到原点的距离值)的均值仍然是 0。

最大方差理论

PCA的思想是要让投影后的点方差越大越好

  • 若样本没有进行中心化, max ⁡ u ∑ i [ u T ( x i − x ˉ ) ] 2 \max _{u} \sum_{i}\left[u^{T}\left(x_{i}-\bar{x}\right)\right]^{2} umaxi[uT(xixˉ)]2
  • 若样本进行中心化后, max ⁡ u ∑ i [ u T ( x i ) ] 2 \max _{u} \sum_{i}\left[u^{T}\left(x_{i}\right)\right]^{2} umaxi[uT(xi)]2

这里以中心化后的式子进行推导:
1 m ∑ i = 1 m ( x ( i ) T u ) 2 = 1 m ∑ i = 1 m u T x ( i ) x ( i ) T u = u T ( 1 m ∑ i = 1 m x ( i ) x ( i ) T ) u \frac{1}{m} \sum_{i=1}^{m}\left(x^{(i) T} u\right)^{2}=\frac{1}{m} \sum_{i=1}^{m} u^{T} x^{(i)} x^{(i)^{T}} u=u^{T}\left(\frac{1}{m} \sum_{i=1}^{m} x^{(i)} x^{(i) T}\right) u m1i=1m(x(i)Tu)2=m1i=1muTx(i)x(i)Tu=uT(m1i=1mx(i)x(i)T)u
括号中间部分是协方差矩阵,这里用 λ \lambda λ表示 1 m ∑ i = 1 m ( x ( i ) T u ) 2 \frac{1}{m} \sum_{i=1}^{m}\left(x^{(i) T} u\right)^{2} m1i=1m(x(i)Tu)2,用 Σ \Sigma Σ表示 ( 1 m ∑ i = 1 m x ( i ) x ( i ) T ) \left(\frac{1}{m} \sum_{i=1}^{m} x^{(i)} x^{(i) T}\right) (m1i=1mx(i)x(i)T),得到: λ = u T Σ u \lambda=u^{T} \Sigma u λ=uTΣu
由于 u u u是单位向量,则有 u T u = 1 u^Tu=1 uTu=1 u λ = λ u = u u T Σ u = Σ u u \lambda=\lambda u=u u^{T} \Sigma u=\Sigma u uλ=λu=uuTΣu=Σu,即 Σ u = λ u \Sigma u=\lambda u Σu=λu

  • 这样就得到 λ \lambda λ Σ \Sigma Σ的特征值, u u u是特征向量。因此,我们只需要对协方差矩阵进行特征值分解,得到的前 k 大特征值对应的特征向量就是最佳的 k 维新特征,而且这 k 维新特征是正交的。得到前 k 个 u 以后,样例通过变换可以得到新的样本。

PCA实现

import numpy as np
import pandas as pd
from sklearn.decomposition import PCA

def pca(X,k):
    m_samples,n_feayures = X.shape
    #Centralization De-mean Mean for zero
    mean = np.mean(X,axis=0)
    normX = X - mean
    #transpose a matrix
    cov_mat = np.dot(np.transpose(normX),normX)
    vals,vecs = np.linalg.eig(cov_mat)
    eig_pairs = [(np.abs(vals[i]),vecs[i]) for i in range(n_feayures)]
    #Eigenvalues from large to small
    eig_pairs = eig_pairs.sort(reverse=True)
    #Get the number of dimensions
    feature = np.array(eig_pairs[0][k])
    #Data restoration
    data = np.dot(normX,np.transpose(feature))
    #sklearn pca
    p = PCA(n_components=k)
    a = p.fit_transform(X)
    #sklearn的pca使用
    pca_sklearn = PCA(n_components=K)
    x_ = pca.fit_transform(X)
  
if __name__=='__main__':
    X = np.array([[-1,1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
    pca(X,1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梚枫_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值