机器学习-PCA降维原理与实现

一、为什么要进行数据降维

机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据映射到低维度的空间中。之所以要进行数据降维,是因为在原始的高维数据中,存在很多冗余以及噪声信息,通过数据降维,我们可以减少冗余信息,提高识别的精度,同时降低维度也可以提升机器学习的速度。

二、原理

PCA 全称为主成分分析方法(Principal Component Analysis),它的目标是通过某种线性投影,将高维的数据映射到低维的空间中表示,并期望在所投影的维度上数据的方差最大,以此使用较少的数据维度,同时保留住较多的原数据点的特性。

举个🌰,下图中的数据为 2 维,现在想只通过 1 个维度来表示这堆数据,通过将数据投影到 z 轴上,原始的点 { x 1 , x 2 } \{x_1,x_2\} {x1,x2}在新的 z 轴上的数据为 z 1 z_1 z1

image-20200209150316294

那么怎么找到这个投影轴呢?这里的过程比较复杂,感兴趣的同学可以看 [PCA的数学原理(转)],主要的过程就是通过协方差矩阵来求解特征向量从而获取降维后的轴。

假设原始数据表示为 X ∈ R m × n X \in \R^{m×n} XRm×n,数据维度为 n n n ,PCA 算法的流程如下:

  1. 均值标准化

获取每个维度的均值,设 μ j \mu_j μj 为第 j j j 个维度的均值,则
μ j = 1 m ∑ i = 1 m x j ( i ) (1) \mu_j=\frac{1}{m}\sum_{i=1}^{m}x_{j}^{(i)}\tag{1} μj=m1i=1mxj(i)(1)
再对原始的数据进行替换,
x j = x j − μ j (2) x_{j}=x_{j}-\mu_j \tag{2} xj=xjμj(2)

  1. 求解协方差矩阵

经过均值标准化之后的数据的协方差矩阵为
Σ = X T X (3) \Sigma=X^TX\tag{3} Σ=XTX(3)

  1. 获取特征向量

一般来说, Σ \Sigma Σ 会有 n n n 个特征值,对应 n n n 个特征向量,如果需要将原始数据从 n n n 维降低到 k k k 维,则只需要选取特征值最大的 k k k 个特征值对应的特征向量即可,我们将其设为 U U U

  1. 降低数据维度

低维数据可以表示为
Z = X U ∈ R m × k (4) Z=XU \in \R^{m×k}\tag{4} Z=XURm×k(4)

这样就将原始的 n n n 维数据降低为 k k k 维。,这是如果想恢复原始数据怎么办?可以恢复部分维度,被压缩的部分是找不回来的,通过压缩后的数据还原到原始数据的公式为
X approx = Z U T + μ (5) X_{\text{approx}}=ZU^T+\mu\tag{5} Xapprox=ZUT+μ(5)
举个🌰,假设原始数据为 X = ( − 1 − 2 − 1 0 0 0 2 1 0 1 ) X=\left(\begin{array}{cc}{-1} & {-2} \\ {-1} & {0} \\ {0} & {0} \\ {2} & {1} \\ {0} & {1}\end{array}\right) X=1102020011,维度为 n = 2 n=2 n=2,下面我们根据上述过程计算 1 个维度下的值。

首先计算均值,我们发现每列数据的均值为 0,那么则可以直接进行协方差矩阵的计算
Σ = 1 5 ( − 1 − 1 0 2 0 − 2 0 0 1 1 ) ( − 1 − 2 − 1 0 0 0 2 1 0 1 ) = ( 6 5 4 5 4 5 6 5 ) \Sigma=\frac{1}{5}\left(\begin{array}{ccccc}{-1} & {-1} & {0} & {2} & {0} \\ {-2} & {0} & {0} & {1} & {1}\end{array}\right) \left(\begin{array}{cc}{-1} & {-2} \\ {-1} & {0} \\ {0} & {0} \\ {2} & {1} \\ {0} & {1}\end{array}\right)=\left(\begin{array}{cc}{\frac{6}{5}} & {\frac{4}{5}} \\ {\frac{4}{5}} & {\frac{6}{5}}\end{array}\right) Σ=51(1210002101)1102020011=(56545456)
然后求其特征值和特征向量,具体求解方法不再详述,可以参考相关资料。求解后特征值为
λ 1 = 2 , λ 2 = 2 / 5 \lambda_{1}=2, \lambda_{2}=2 / 5 λ1=2,λ2=2/5
其对应的特征向量分别是
c 1 = ( 1 1 ) , c 2 = ( − 1 1 ) c_{1}=\left(\begin{array}{l}{1} \\ {1}\end{array}\right), c_{2}=\left(\begin{array}{c}{-1} \\ {1}\end{array}\right) c1=(11),c2=(11)
其中对应的特征向量分别是一个通解, c 1 c_{1} c1 c 2 c_{2} c2 可取任意实数。那么标准化后的特征向量为
( 1 / 2 1 / 2 ) , ( − 1 / 2 1 / 2 ) \left(\begin{array}{c}{1 / \sqrt{2}} \\ {1 / \sqrt{2}}\end{array}\right),\left(\begin{array}{c}{-1 / \sqrt{2}} \\ {1 / \sqrt{2}}\end{array}\right) (1/2 1/2 ),(1/2 1/2 )
由于需要降低到 1 维,所以我们取特征值 λ 1 \lambda_1 λ1 对应的特征向量作为矩阵 U = ( 1 / 2 1 / 2 ) U=\left(\begin{array}{c}{1 / \sqrt{2}} \\ {1 / \sqrt{2}}\end{array}\right) U=(1/2 1/2 ),降维后的数据为
Z = ( − 1 − 2 − 1 0 0 0 2 1 0 1 ) ( 1 / 2 1 / 2 ) = ( − 3 / 2 − 1 / 2 0 3 / 2 1 / 2 ) Z =\left(\begin{array}{cc}{-1} & {-2} \\ {-1} & {0} \\ {0} & {0} \\ {2} & {1} \\ {0} & {1}\end{array}\right)\left(\begin{array}{c}{1 / \sqrt{2}} \\ {1 / \sqrt{2}}\end{array}\right)=\left(\begin{array}{c}-3/\sqrt{2} \\ -1/\sqrt{2} \\ 0 \\ 3/\sqrt{2} \\ 1/\sqrt{2}\end{array}\right) Z=1102020011(1/2 1/2 )=3/2 1/2 03/2 1/2
注意⚠️:通过前面的方法我们知道还需要手动设置一个 k k k 值,那么怎么选择最优的 k k k 值呢,一般来说,选取的 k k k 值通常要保留 99% 的方差, k k k 值的选取可以参考下面的过程:

  1. k = 1 → n − 1 k=1 \to n-1 k=1n1

  2. 通过式 ( 3 ) 、 ( 4 ) 、 ( 5 ) (3)、(4)、(5) (3)(4)(5)计算 U , z ( 1 ) , z ( 2 ) , … , z ( m ) , x approx ( 1 ) , x approx ( 2 ) , … , x approx ( m ) U,z^{(1)},z^{(2)},\ldots,z^{(m)},x_{\text{approx}}^{(1)},x_{\text{approx}}^{(2)},\ldots,x_{\text{approx}}^{(m)} U,z(1),z(2),,z(m),xapprox(1),xapprox(2),,xapprox(m)

  3. 校对是否满足以下条件
    1 m ∑ i = 1 m ∥ x ( i ) − x approx ( i ) ∥ 2 1 m ∑ i = 1 m ∥ x ( i ) ∥ 2 ≤ 0.01 \frac{\frac{1}{m} \sum_{i=1}^{m}\left\|x^{(i)}-x_{\text {approx}}^{(i)}\right\|^{2}}{\frac{1}{m} \sum_{i=1}^{m}\left\|x^{(i)}\right\|^{2}}\leq0.01 m1i=1mx(i)2m1i=1mx(i)xapprox(i)20.01
    如果满足上述条件,则可以选择该 k k k

三、实现

3.1 Python 手动实现

'''
@Author: huzhu
@Date: 2019-11-20 09:18:15
@Description: 
'''
import numpy as np
import matplotlib.pyplot as plt 

def load_data(file_name, delim='\t'):
    fr = open(file_name)
    str_arr = [line.strip().split(delim) for line in fr.readlines()]
    dat_arr = [list(map(float,line)) for line in str_arr]
    return np.mat(dat_arr)

def pca(data_mat, topNfeat = 999999):
    '''
    @description: PCA
    @return: low_data_mat, recon_mat
    '''
    mean_val = np.mean(data_mat, axis = 0)
    mean_removed = mean_val - data_mat
    # get the covrariance matrix
    cov_mat = np.cov(mean_removed, rowvar=0)
    # get the eigenvalue and eigenvector
    eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
    # sort, sort goes smallest to largest
    eigen_val_ind = np.argsort(eigen_vals)
    # cut off unwanted dimensions
    eigen_val_ind = eigen_val_ind[:-(topNfeat+1):-1]
    print(eigen_val_ind)
    # reorganize eig vects largest to smallest
    red_eigen_vecs = eigen_vecs[:,eigen_val_ind] 
    print(red_eigen_vecs)
    # low dimension data
    low_data_mat = mean_removed * red_eigen_vecs
    # transfor low data to original dimension
    recon_mat = (low_data_mat * red_eigen_vecs.T) + mean_val
    return low_data_mat, recon_mat

if __name__ == '__main__':
    data_mat = load_data("testSet.txt")
    low_data_mat, recon_mat = pca(data_mat, 1)
    plt.figure()
    plt.scatter(data_mat[:,0].flatten().A[0], data_mat[:,1].flatten().A[0], marker='^', s = 90)
    plt.scatter(recon_mat[:,0].flatten().A[0], recon_mat[:,1].flatten().A[0], marker='o', s = 50, c = "red")
    plt.show()

降维后的结果如下图所示。

PCA

3.2 库函数实现

import numpy as np
from sklearn.decomposition import PCA
X = np.array([[-1, -2], [-1, 0], [0, 0], [2, 1], [0, 1]])
pca = PCA(n_components=1)
newX = pca.fit_transform(X)
print(newX)
print(pca.explained_variance_ratio_)

结果为

[[ 2.12132034]
 [ 0.70710678]
 [-0.        ]
 [-2.12132034]
 [-0.70710678]]
[0.83333333]

可以看到和我们上述举例的数据相同(符号相反是求解特征向量的时候符号不同所导致的)。

完整代码和数据可以参考 [我的 github]

四、参考

[1] https://zhuanlan.zhihu.com/p/21580949

[2] https://www.jianshu.com/p/8642d5ea5389

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,根据提供的引用内容,没有给出pca降维原理示意图的描述或者引用。但是,我可以通过文字来给你解释一下pca降维原理PCA(Principal Component Analysis,主成分分析)的主要思想是将n维特征映射到k维上,其中k维是全新的正交特征,也被称为主成分。这些主成分是在原有n维特征的基础上重新构造出来的。PCA的目标是通过保留数据中的主要信息来降低数据的维度。具体来说,PCA通过线性变换将原始数据投影到一个新的坐标系中,使得投影后的数据具有最大的方差。这样可以保留尽可能多的信息,并且可以减少数据的冗余。降维后的数据可以用更少的维度来表示,从而减少计算和储的成本。PCA的核心计算是通过特征值分解来获得主成分,并且特征值越大的主成分所包含的信息越多。因此,选择保留的主成分个数或者降维后的维度可以根据主成分的方差和比例来确定。PCA在sklearn中使用简单,一般只需要指定需要降维到的维度或者降维后的主成分的方差和占原始维度所有特征方差和的比例阈值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [图解机器学习算法(14) | PCA降维算法详解(机器学习通关指南·完结)](https://blog.csdn.net/ShowMeAI/article/details/123408773)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [数据降维1:主成分分析法思想及原理(配图版)](https://blog.csdn.net/zhaodedong/article/details/103775967)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值