吴恩达《机器学习》——PCA降维

news2024/11/24 17:47:53

PCA降维

  • 1. 主成分分析
    • 1.1 数据降维动机
    • 1.2 PCA降维目标问题分析
  • 2. PCA数学原理分析
    • 2.1 求协方差矩阵的碎碎念
    • 2.2 PCA实现方法
  • 3. Python实现
    • 3.1 进行人脸数据压缩

数据集、源文件可以在Github项目中获得
链接: https://github.com/Raymond-Yang-2001/AndrewNg-Machine-Learing-Homework

1. 主成分分析

1.1 数据降维动机

在某些情况下,机器学习使用的数据可能十分巨大,这种情况下,对数据进行压缩就显得十分必要。假设某一数据集包括两个特征维度:圆形的半径和圆形的面积。根据简单的数学知识,这两个特征实际上是互相关联的,从描述圆特征的角度来说,半径和面积并没有什么不同;在机器学习中,完全可以只是用一个特征进行学习。

这就是数据降维,使得数据中某些“冗余”的特征维度被压缩,从而得到更低位的数据表示——当然,这种压缩是建立在尽可能减小数据信息的损失上的。

1.2 PCA降维目标问题分析

假设我们有如下数据:
在这里插入图片描述
如果要对数据进行维度压缩,从二维变成一位,显然水平方向是更适合作为压缩后的维度的。从数学角度来看,是因为水平方向的方差要大于垂直方向,也就意味着,水平方向的特征相对于垂直方向来说,具有更大的特征空间,有更丰富的特征的值的选则,也就是对样本更有区分度。

所以,PCA的优化目标可以总结为如下两个:

  1. 降维后同一维度的方差最大
  2. 不同维度间的相关度为0

如果不同维度的特征间存在相关度,则证明这两个特征间存在某种内在的关联,从一个特征能推理出另一个特征,显然这没有达到降维的最好目标。

2. PCA数学原理分析

为了同时表示同一维度间的方差和不同维度间的相关性,我们引入了协方差矩阵。设数据维度为 D D D,则协方差矩阵为:
C = [ c o v ( x 1 , x 1 ) c o v ( x 1 , x 2 ) ⋯ c o v ( x 1 , x D ) ⋮ ⋮ ⋱ ⋮ c o v ( x D , x 1 ) c o v ( x D , x 2 ) ⋯ c o v ( x D , x D ) ] D × D C=\left[\begin{matrix} cov(x_{1},x_{1}) & cov(x_{1},x_{2}) & \cdots & cov(x_{1},x_{D}) \\ \vdots & \vdots & \ddots & \vdots \\ cov(x_{D},x_{1}) & cov(x_{D},x_{2}) & \cdots & cov(x_{D},x_{D}) \\ \end{matrix}\right]_{D\times D} C= cov(x1,x1)cov(xD,x1)cov(x1,x2)cov(xD,x2)cov(x1,xD)cov(xD,xD) D×D
对角线上的元素表明了同一维度的方差,不同维度间的方差表明了不同维度间的相关性。优化后的理想矩阵为:
C ′ = [ δ 11 0 ⋯ 0 0 δ 22 ⋯ 0 0 0 ⋱ ⋮ 0 0 ⋯ δ R R ] R × R C^{\prime}=\left[\begin{matrix} \delta_{11} & 0 & \cdots & 0 \\ 0 & \delta_{22} & \cdots & 0 \\ 0 & 0 & \ddots & \vdots \\ 0 & 0 & \cdots & \delta_{RR} \\ \end{matrix}\right]_{R\times R} C= δ110000δ220000δRR R×R
并且, X X X为原数据矩阵,形状为 ( N , D ) (N,D) (N,D) P P P为降维变换矩阵。

考虑协方差矩阵的计算:
C ′ = 1 N ( X P ) ⊤ ( X P ) = 1 N P ⊤ X ⊤ X P = P ⊤ ( 1 N X ⊤ X ) P = P ⊤ C P C^{\prime}=\frac{1}{N}(XP)^{\top}(XP)=\frac{1}{N}P^{\top}X^{\top}XP=P^{\top}\left(\frac{1}{N}X^{\top}X\right)P=P^{\top}CP C=N1(XP)(XP)=N1PXXP=P(N1XX)P=PCP
要尽量减少不同维度间的相关度,设 P ⊤ P = I P^{\top}P=I PP=I,即 P P P的列是正交的。

优化问题如下:
{ max ⁡ t r ( P ⊤ C P ) P ⊤ P = I \left\{ \begin{aligned} &\max{\rm{tr}{(P^{\top}CP)}} \\ &P^{\top}P=I\\ \end{aligned} \right. {maxtr(PCP)PP=I

采用拉格朗日算子,得到无条件的极值问题:
f ( P ) = t r ( P ⊤ C P ) + λ ( I − P ⊤ P ) f(P)=\rm{tr}(P^{\top}CP)+\lambda(I-P^{\top}P) f(P)=tr(PCP)+λ(IPP)
f ( P ) f(P) f(P)求导:
∂ t r ( P ⊤ C P ) ∂ P = ∂ t r ( P P ⊤ C ) ∂ P = ( P ⊤ C ) ⊤ = C ⊤ P \frac{\partial{tr(P^{\top}CP)}}{\partial{P}}=\frac{\partial{tr(PP^{\top}C)}}{\partial{P}}=(P^{\top}C)^{\top}=C^{\top}P Ptr(PCP)=Ptr(PPC)=(PC)=CP
∂ λ ( I − P ⊤ P ) ∂ P = − λ P \frac{\partial{\lambda(I-P^{\top}P)}}{\partial{P}}=-\lambda P Pλ(IPP)=λP
这里用到了迹和矩阵导数的求导的一些知识,不理解得到话可以自行查阅一些线性代数的知识。
∂ f ( P ) ∂ P = C ⊤ P + λ P \frac{\partial{f(P)}}{\partial{P}}=C^{\top}P+\lambda P Pf(P)=CP+λP
由于 C C C是对阵矩阵,所以:
∂ f ( P ) ∂ P = C P − λ P \frac{\partial{f(P)}}{\partial{P}}=CP-\lambda P Pf(P)=CPλP
∂ f ( P ) ∂ P = 0 ⇒ C P = λ P \frac{\partial{f(P)}}{\partial{P}}=0 \Rightarrow CP=\lambda P Pf(P)=0CP=λP
到这里就可以看出, P P P实际上是 C C C的特征向量(矩阵)。事实上,对称矩阵特征值不等的特征向量是正交的。

另外,有:
P ⊤ C P = P ⊤ λ P P^{\top}CP=P^{\top}\lambda P PCP=PλP
由于特征值矩阵 λ \lambda λ是一个对角矩阵(除了对角线均为0),所以 C = P ⊤ λ P = λ P ⊤ P = λ C=P^{\top}\lambda P=\lambda P^{\top}P=\lambda C=PλP=λPP=λ

可以发现, λ \lambda λ实际上就代表了各个维度的方差,也就是说特征值=方差。选择大方差的维度保留就是保留特征值较大的维度。

2.1 求协方差矩阵的碎碎念

先前我们提到,求对一个 ( n _ s a m p l e = N , n _ f e a t u r e = D ) (n\_sample=N, n\_feature=D) (n_sample=N,n_feature=D)的矩阵 X X X求协方差矩阵,公式如下:
C = 1 N X ⊤ X C=\frac{1}{N}X^{\top}X C=N1XX
接下来将进行理论推导,为什么协方差要这么求:

从概率论的知识可知,两个随机变量 X , Y X,Y X,Y的协方差如下:
c o v ( X , Y ) = E [ ( X − μ X ) ( Y − μ Y ) ] cov(X,Y)=\mathbb{E}[(X-\mu_{X})(Y-\mu_{Y})] cov(X,Y)=E[(XμX)(YμY)]
其中, μ X , μ Y \mu_{X},\mu_{Y} μX,μY分别是两个随机变量的均值。

我们在对数据进行PCA之前,先要对数据进行规范化,使得其均值为0,通常采用方法是减去均值,即 X n e w = X − μ X X_{new}=X-\mu_{X} Xnew=XμX,这样在计算协方差的时候,我们可以得到:
c o v ( X , Y ) = E ( X Y ) cov(X,Y)=\mathbb{E}(XY) cov(X,Y)=E(XY)
这里, X , Y X,Y X,Y都是数据的某一维度。转换成矩阵运算,我们可以得到:
C o v = 1 N X ⊤ X Cov=\frac{1}{N}X^{\top}X Cov=N1XX

当然,我们如果考虑对样本进行无偏估计,在求期望的时候,均值会改写为 E ( X ) = 1 N − 1 X i \mathbb{E(X)}=\frac{1}{N-1}X_{i} E(X)=N11Xi,(不熟悉的话可以回顾一下概率论的相关知识),这样我们得到的协方差矩阵是:
C o v = 1 N − 1 X ⊤ X Cov=\frac{1}{N-1}X^{\top}X Cov=N11XX
在numpy库中,采用的计算方法就是这种。

2.2 PCA实现方法

由上文可知,实现PCA的步骤如下:

  1. 对输入求协方差矩阵 C C C
  2. 求矩阵 C C C的特征值和特征向量,按照特征值降序排序
  3. 保留k个维度,选取前k个特征向量组成矩阵 P P P
  4. 新的数据矩阵为 C ′ = X P C^{\prime}=XP C=XP

3. Python实现

import numpy as np


class PCA:
    """
    ----------------------------------------------------------------------------
    Attributes:
    components_: ndarray with shape of (n_features, n_components)
        Principal axes in feature space, representing the directions of maximum
        variance in the data.

    explained_variance_ : ndarray of shape (n_components,)
        The amount of variance explained by each of the selected components.

    explained_variance_ratio_ : ndarray of shape (n_components,)
        Percentage of variance explained by each of the selected components.
    """
    def __init__(self, n_components):
        self.n_components = n_components
        self.explained_variance_ = None
        self.explained_variance_ratio_ = None
        self.components_ = None

        self.__mean = None

    def fit(self, x):
        """
        :param x: (n,d)
        :return:
        """
        self.__mean = x.mean(axis=0)
        x_norm = x - self.__mean
        x_cov = (x_norm.T @ x_norm) / (x.shape[0] - 1)
        vectors, variance, _ = np.linalg.svd(x_cov)
        # (n_feature, n_components)
        self.components_ = vectors[:, :self.n_components]
        if len(self.components_.shape) == 1:
            self.components_ = np.expand_dims(vectors[:, :self.n_components], axis=1)
        self.explained_variance_ = variance[:self.n_components]
        self.explained_variance_ratio_ = self.explained_variance_ / variance.sum()

    def transform(self, x):
        """
        :param x: (n, n_feature)
        :return:
        """
        if self.__mean is not None:
            x = x - self.__mean
        x_transformed = x @ self.components_
        return x_transformed

数据集可视化
在这里插入图片描述
进行PCA降维,可视化数据

from PCA import PCA
m_pca = PCA(1)
m_pca.fit(x)
x_reduced = m_pca.transform(x)
print("The principal axes of components is: {}\n"
      "The variance of each components is: {}\n"
      "The variance ratio of selected components is: {}"
      .format(m_pca.components_.tolist(), m_pca.explained_variance_.tolist(), m_pca.explained_variance_ratio_.tolist()))
The principal axes of components is: [[-0.7690815341368202], [-0.6391506816469459]]
The variance of each components is: [2.1098781795840327]
The variance ratio of selected components is: [0.8706238489732337]

在这里插入图片描述

3.1 进行人脸数据压缩

展示人脸数据

faces = loadmat('data/ex7faces.mat')
face_x = faces['X']
face_x.shape
(5000, 1024)

可以看到共5000张人脸数据,维度是1024维度。
在这里插入图片描述
使用PCA降维到100维度

from PCA import PCA
face_pca = PCA(n_components=100)
face_pca.fit(face_x)
face_r = face_pca.transform(face_x)

在这里插入图片描述
可以看到保留了大部分的人脸特征。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/144166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一些实用的办公工具分享给你

ABBYY FineReader 这是一个可以转换PDF格式的图片文字识别软件,下载之后可以免费试用七天,或者选择去它的网站上传PDF进行识别转换,一天最多可以转换10次,且一次只能转换3个页面。 【操作方法】 打开软件,点击“图像…

(day3)自学Java——面向对象

非原创,为方便自己后期复习 目录 1.类和对象 2.封装 3.就近原则和this关键字 4.构造方法 5.标准的javabean类 6.三种情况的对象内存图 7.基本数据类型和引用数据类型 8.this的内存原理 9.面向对象综合训练 (1)文字版格斗游戏 (2)两个对象数组练习 (3)对…

产品上新|语音识别+主题抽取,Magic Data多人会议数据集助您打造领先智能会议系统

2020年以来,新冠加快了线下向线上搬迁的速度,使得线上办公、在线教育、远程会议得到飞速普及和发展。艾媒咨询数据显示,2021年中国视频会议行业市场规模达148.2亿元。各类视频会议产品价格较低、操作便捷高效,普及率越来越高&…

vsftp开启登录,上传,下载,删除等操作审计日志

vsftp开启登录,上传,下载,删除等操作审计日志 背景 今天业务告知说有人把前天下午和昨天一天的ftp上面的附件被人删除了,首先我是非常的惊讶,居然会发生这种事,但是好在这个ftp不是我们负责的,…

驱动之设备模型

1. 起源与新方案 1.1 起源 仅devfs,导致开发不方便以及一些功能难以支持 热插拔不支持一些针对所有设备的同意操作(如电源管理)不能自动mknod用户查看不了设备信息设备信息硬编码,导致驱动代码通用性差,即没有分离设…

终章:学习路线

说明 该文章来源于徒弟lu2ker转载至此处,更多文章可参考:https://github.com/lu2ker/ 文章目录说明一些废话成果路线第一阶段要点第二阶段要点第三阶段要点第四阶段要点最后一些废话 截至这篇文章前已经有150star了,虽然比不上大佬们K级的量…

【链表】leetcode203.移除链表元素(C/C++/Java/Js)

leetcode203.移除链表元素1 题目2 思路 (两种方式)2.1 在原来链表上进行删除2.2 设置一个虚拟头结点删除3 代码3.1 C (两种方式)3.2 C版本(两种方式)3.3 Java版本(两种方式)3.4 JavaScript版本4…

Vue的组件、组件的创建、data、methods

一、组件 组件是vue的重要的特征之一,可以扩展html的功能,也可以封装代码实现重复使用。 二、组件的创建 1. 非脚手架方式下创建 ​ 第一步:使用Vue.extend创建组件 ​ 第二步:使用Vue.component注册组件 ​ …

OpenGov(三):新波卡治理机制有哪些可期待?

OpenGov维持波卡开创的信念投票,与以前相同的方式进行,使用WebAssembly和几个链上投票机制。也就是说,OpenGov通过降低障碍,来更好地管理网络的日常决策,将流程推向去中心化。真正的重点是使提案的范围与通过治理流程的…

企业数字化转型到底是什么?

企业的数字化转型单单是从基础设施上变更,更要从企业数据从文化上入手,培养企业的数据文化,以数据驱动来促进业务发展。大家都把数据基础设施讲的很详细了,那么我就从企业的数据化转型当中的数据文化是什么?以下来为大…

Python类型注解(十)

python学习之旅(十) 👍查看更多可以关注查看首页或点击下方专栏目录 一.为什么需要类型注解 在代码中提供数据类型的注解(显式的说明),使用时能获得相关提示 帮助第三方IDE工具(如PyCharm)对代码进行类型推…

想从事网络信息安全的工作,该如何自学?

前言 【一一帮助网络安全入门和提升学习点这里一一】 由于我之前写了不少网络安全技术相关的文章,不少读者朋友知道我是从事网络安全相关的工作,于是经常有人私信问我: 我刚入门网络安全,该怎么学?要学哪些东西&#…

第56篇-利用jsRpc获取某博的登录参数

声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖! 文章目录 一、前言二、JsRpc的基本使用1.准备工作2.简单使用三、使用jsRpc获取微博登录参数1.网站分析2.构建rpc一、前言 以前使用…

记录 一次 小米路由器4C 刷openwrt 过程

前言 起因是4C的性能不太行,用久了网络也不稳定,且100M带宽跑不满,然后就换了路由器,闲置的这个准备哪来跑个Linux挂个bot来着,结果可好,刷完发现内存小的可怜呀,架构也不是主流的(…

低代码助力工业软件发展,提升智能制造“软”实力

在《“十四五”智能制造发展规划》中,将工业软件作为加强自主供给的一个重点任务进行单独部署,强调了工业软件的工业属性,明确了工业软件对于智能制造的核心支撑作用,凸显了我国补足工业软件短板、以工业软件助推智能制造发展的决…

跨境资讯 | 亚马逊三站点将更新供应链标准,1月19日生效

让我们一起来看看今日都有哪些新鲜事吧!01 亚马逊将更新供应链标准 亚马逊美国站、欧洲站和日本站发布公告称2023年1月19日将更新供应链标准,在亚马逊销售的产品必须符合这些新标准。作为定期审查的一部分,这些标准每三年更新一次。亚马逊表…

虹科案例 | 解决ASRS系统的痛点问题居然这么简单?(下)

ASRS中的定位器 在考虑传感技术时,重要的是每种技术都能够以最高程度的重复性和精确度保持绝对分量,并非所有的方法都是一样托盘梭子和立式起重机在任何时候都要求绝对位置。 托盘梭子: 过道位置 行位置 垂直起重机: 高度 线性…

Java中解决lambda表达式内部访问在其外部定义的变量-使用mapToInt

场景 Java8新特性-Stream对集合进行操作的常用API: Java8新特性-Stream对集合进行操作的常用API_霸道流氓气质的博客-CSDN博客_streamapi对集合修改 上面介绍Stream的相关使用示例。 如果遇到在lambda表达式内部访问在其外部定义的变量,比如一个求和…

MATLAB-surf/ezsurf函数绘制三维图形

(1)surf 函数的用法和 mesh函数类似,MATLAB中 surf函数专门用于绘制三维着色曲面图和 surfc是通过矩形区域来观测数学函数的函数。surf和 surfc能够产生由X、Y、Z指定的有色参数化曲面,即三维有色图。具体调用方法如下。1、surf(Z…

JDBC数据库连接

下载jdbc jar包,中央仓库下载https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.24项目导入右键jar包,然后add as library数据库操作3.1连接数据库package com.heima.jdbc;import java.sql.Connection; import java.sql.DriverManager…