PCA 的思路和推导

      PCA是一种较为常用的降维技术,PCA的思想是将n维特征映射到k维上,这k维是全新的正交特征。这k维特征称为主元,是重新构造出来的k维特征。在PCA中,数据从原来的坐标系转换到新的坐标系下,新的坐标系的选择与数据本身是密切相关的。其中,第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴选取的是与第一个坐标轴正交且具有最大方差的方向,依次类推,我们可以取到这样的k个坐标轴。

     

1、PCA的操作流程大致如下:

  • 去平均值,即每一位特征减去各自的平均值
  • 计算协方差矩阵
  • 计算协方差矩阵的特征值与特征向量
  • 对特征值从大到小排序
  • 保留最大的个特征向量

  • 将数据转换到个特征向量构建的新空间中

    PCA推导

        以下面这幅图开始我们的推导:


    上面是二维空间中的一组数据,很明显,数据的分布让我们很容易就能看出来主成分的轴(简称主轴)的大致方向。下面的问题就是如何通过数学计算找出主轴的方向。来看这张图:


    现在要做的事情就是寻找u1的方向,对于这点,我想好多人都有经验,这不就是以前用最小二乘法拟合数据时做的事情吗!对,最小二乘法求出来的直线(二维)的方向就是u1的方向!那u2的方向呢?因为这里是二维情况,所以u2方向就是跟u1垂直的方向,对于高维数据,怎么知道u2的方向?经过下面的理论推导,各个主轴都能确定下来。

        给定一组数据:(如无说明,以下推导中出现的向量都是默认是列向量

                   

    将其中心化后表示为:

            

             

    中心化后的数据在第一主轴u1方向上分布散的最开,也就是说在u1方向上的投影的绝对值之和最大(也可以说方差最大),计算投影的方法就是将x与u1做内积,由于只需要求u1的方向,所以设u1是单位向量。

    也就是最大化下式:

                                   

    也即最大化:

                       

    解释:平方可以把绝对值符号拿掉,光滑曲线处理起来方便。

    两个向量做内积可以转化成矩阵乘法:

                        

    所以目标函数可以表示为:

                                         

    括号里面就是矩阵乘法表示内积,转置以后的行向量乘以列向量得到一个数。因为一个数的转置还是其本身,所以又可以将目标函数化为:

                                     

    这样就可以把括号去掉!去掉以后变成:

                                      

    由于u1和i无关,可以把它拿到求和符外面:

                                     

    注意,其实括号里面是一个矩阵乘以自身的转置,这个矩阵形式如下:

                                    

    X矩阵的第i列就是xi,于是有:

                                     

    所以目标函数最后化为:

                                    

    上式到底有没有最大值呢?如果没有前面的1/n,那就是就是一个标准的二次型!并且XX'(为了方便,用'表示转置)得到的矩阵是一个半正定的对称阵!为什么?首先XX'是对称阵,因为(XX')'=XX',下面证明它是半正定,什么是半正定?就是所有特征值大于等于0。

    假设XX'的某一个特征值为,对应的特征向量为,则有:

                                                                                 

                                                                     

                                                                    

                          

                                                          

    证明完毕!对于半正定阵的二次型,存在最大值!现在问题就是如何求目标函数的最大值?以及取最大值时u1的方向?下面介绍两种方法。

    方法一  拉格朗日乘数法

    目标函数和约束条件构成了一个最大化问题:

                                                          

    构造拉格朗日函数:

                                       

    对u1求导

                                      

    显然,u1即为XX'特征值对应的特征向量!XX'的所有特征值和特征向量都满足上式,那么将上式代入目标函数表达式即可得到

                                          

    所以,如果取最大的那个特征值,那么得到的目标值就最大。有可能你会有疑问,为什么一阶导数为0就是极大值呢?那么再求二阶导数:


    二阶导数半负定,所以,目标函数在最大特征值所对应的特征向量上取得最大值!所以,第一主轴方向即为第一大特征值对应的特征向量方向。第二主轴方向为第二大特征值对应的特征向量方向,以此类推,证明类似。

PCA推导

    以下面这幅图开始我们的推导:


上面是二维空间中的一组数据,很明显,数据的分布让我们很容易就能看出来主成分的轴(简称主轴)的大致方向。下面的问题就是如何通过数学计算找出主轴的方向。来看这张图:


现在要做的事情就是寻找u1的方向,对于这点,我想好多人都有经验,这不就是以前用最小二乘法拟合数据时做的事情吗!对,最小二乘法求出来的直线(二维)的方向就是u1的方向!那u2的方向呢?因为这里是二维情况,所以u2方向就是跟u1垂直的方向,对于高维数据,怎么知道u2的方向?经过下面的理论推导,各个主轴都能确定下来。

    给定一组数据:(如无说明,以下推导中出现的向量都是默认是列向量

               

将其中心化后表示为:

        

         

中心化后的数据在第一主轴u1方向上分布散的最开,也就是说在u1方向上的投影的绝对值之和最大(也可以说方差最大),计算投影的方法就是将x与u1做内积,由于只需要求u1的方向,所以设u1是单位向量。

也就是最大化下式:

                               

也即最大化:

                   

解释:平方可以把绝对值符号拿掉,光滑曲线处理起来方便。

两个向量做内积可以转化成矩阵乘法:

                    

所以目标函数可以表示为:

                                     

括号里面就是矩阵乘法表示内积,转置以后的行向量乘以列向量得到一个数。因为一个数的转置还是其本身,所以又可以将目标函数化为:

                                 

这样就可以把括号去掉!去掉以后变成:

                                  

由于u1和i无关,可以把它拿到求和符外面:

                                 

注意,其实括号里面是一个矩阵乘以自身的转置,这个矩阵形式如下:

                                

X矩阵的第i列就是xi,于是有:

                                 

所以目标函数最后化为:

                                

上式到底有没有最大值呢?如果没有前面的1/n,那就是就是一个标准的二次型!并且XX'(为了方便,用'表示转置)得到的矩阵是一个半正定的对称阵!为什么?首先XX'是对称阵,因为(XX')'=XX',下面证明它是半正定,什么是半正定?就是所有特征值大于等于0。

假设XX'的某一个特征值为,对应的特征向量为,则有:

                                                                             

                                                                 

                                                                

                      

                                                      

证明完毕!对于半正定阵的二次型,存在最大值!现在问题就是如何求目标函数的最大值?以及取最大值时u1的方向?下面介绍两种方法。

方法一  拉格朗日乘数法

目标函数和约束条件构成了一个最大化问题:

                                                      

构造拉格朗日函数:

                                   

对u1求导

                                  

显然,u1即为XX'特征值对应的特征向量!XX'的所有特征值和特征向量都满足上式,那么将上式代入目标函数表达式即可得到

                                      

所以,如果取最大的那个特征值,那么得到的目标值就最大。有可能你会有疑问,为什么一阶导数为0就是极大值呢?那么再求二阶导数:


二阶导数半负定,所以,目标函数在最大特征值所对应的特征向量上取得最大值!所以,第一主轴方向即为第一大特征值对应的特征向量方向。第二主轴方向为第二大特征值对应的特征向量方向,以此类推,证明类似。

### 点云曲率法线计算方法及其原理 #### 法线计算的重要性与应用场景 对于点云而言,法线是一个非常重要的属性,在多种场景下发挥着不可或缺的作用。在点云渲染过程中,法线信息决定了光线如何反射,进而影响最终视觉效果的真实感;而在点云重建方面,则利用法线方向来估算点到隐式曲面的距离,这对于构建精确的三维模型至关重要[^2]。 #### 法线估计的具体实现方式 一种常见的做法是从局部邻域内的点出发,通过拟合平面或其他几何形状的方式来推导出该位置处的最佳逼近平面,并以此为基础求解对应的单位法向量。具体操作上可以采用主成分分析(PCA)技术,先找到一组能最大程度表示当前点附近空间分布特性的坐标轴系,其中最短的那个即代表了此处的法线方向[^3]。 #### 曲率计算的意义及其实现手段 曲率反映了物体表面弯曲程度的变化情况,它可以帮助识别不同类型的几何结构特征,比如平坦区、边缘或是尖角等部位。Open3D库提供了便捷的功能接口来进行此类运算——通过对每一个顶点周围的邻居节点执行协方差矩阵分解并从中提取最大特征值λ_max以及次大特征值λ_mid之后,即可按照特定公式得出相应的平均曲率H=(λ_max+λ_mid)/2 高斯曲率K= λ_max * λ_mid 。这样的过程有助于后续开展诸如目标检测、分类等一系列高级任务[^1]。 #### 处理噪声数据平滑化策略 实际采集来的原始点云往往含有不同程度上的随机扰动项,它们会干扰正常的法线估计流程甚至造成错误的结果输出。为此,有必要引入专门针对这类问题设计的技术方案,例如基于移动最小二乘法(Moving Least Squares, MLS) 的滤波器就是这样一个有效工具。其基本思路是在保持整体轮廓不变的前提下尽可能去除细碎突起部分的影响,使得经过处理后的样本集更加规整有序,有利于提高后续建模精度的同时也减少了可能出现的人工痕迹现象[^4]。 ```python import open3d as o3d # 加载点云文件 pcd = o3d.io.read_point_cloud("path_to_your_file.ply") # 执行法线估计 pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30)) # 可视化带法线的方向箭头 o3d.visualization.draw_geometries([pcd], point_show_normal=True) # 计算曲率 (假设已安装必要的依赖包) from sklearn.decomposition import PCA import numpy as np def compute_curvature(pcd): points = np.asarray(pcd.points) normals = np.asarray(pcd.normals) kdtree = o3d.geometry.KDTreeFlann(pcd) curvatures = [] for i in range(len(points)): [_, idx, _] = kdtree.search_knn_vector_3d(points[i], knn=20) local_points = points[idx,:] pca = PCA(n_components=3) pca.fit(local_points) eigenvalues = pca.explained_variance_ H = 0.5*(eigenvalues[0]+eigenvalues[1]) K = eigenvalues[0]*eigenvalues[1] curvatures.append((H,K)) return np.array(curvatures) curvs = compute_curvature(pcd) print('Curvature:', curvs[:5]) # 输出前五个点的曲率值供查看 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值