24/11/7 算法笔记 PCA主成分分析

假如我们的数据集是n维的,共有m个数据(x^{(1)},x^{(2)},...,x^{(m)})。我们希望将这m个数据的维度从n维降到k维,希望这m个k维的数据集尽可能的代表原始数据集。我们知道数据从n维降到k维肯定会有损失,但是我们希望损失尽可能的小。那么如何让这k维的数据尽可能表示原来的数据呢?

        我们先看看最简单的情况,也就是n=2,K=1,也就是将数据从二维降维到一维。数据如下图。我们希望找到某一个维度方向,它可以代表这两个维度的数据。图中列了两个向量方向,u1和u2,那么哪个向量可以更好的代表原始数据集呢?从直观上也可以看出,u1比u2好。

可以有两种解释,第一种解释是样本点到这个直线的距离足够近,第二种解释是样本点在这个直线上的投影能尽可能的分开。

        假如我们把K从1维推广到任意维,我们希望降维的标准为:样本点到这个超平面的距离足够近,或者说样本点在这个超平面上的投影能尽可能的分开。

PCA(主成分分析)是一种统计技术,它通过正交变换将一组可能相关的变量转换为一组线性不相关的变量,称为主成分。这些主成分按照方差的大小排序,第一个主成分具有最大的方差,第二个主成分具有第二大的方差,依此类推。以下是PCA的工作原理和关键步骤:

1. 标准化数据

由于PCA对数据的尺度敏感,因此在进行PCA之前,通常需要对数据进行标准化处理,使得每个特征的均值为0,标准差为1。这一步是必要的,因为PCA依赖于协方差矩阵,而协方差矩阵会因特征的尺度差异而产生偏差。

2. 计算协方差矩阵

在数据标准化之后,计算数据的协方差矩阵。协方差矩阵是一个方阵,其元素表示不同特征之间的协方差。对于数据集 XX(假设已经中心化),协方差矩阵 ΣΣ 定义为:

其中 n 是样本数量。

3. 计算协方差矩阵的特征值和特征向量

协方差矩阵的特征值和特征向量可以提供关于数据结构的重要信息。特征值表示每个特征的方向上的数据方差量,而特征向量表示这些特征的方向。

4. 选择主成分

根据特征值的大小,选择最大的 k 个特征值对应的特征向量。这些特征向量代表了数据中最重要的 k 个主成分。特征值的大小表示了每个主成分的重要性或方差贡献。

5. 构造新的特征空间

使用选定的特征向量作为新特征空间的基,将原始数据投影到这个新的特征空间上。这个过程实际上是将原始数据集转换为一个新的数据集,其中每个数据点由 k 个主成分的线性组合表示。

6. 解释结果

新数据集中的每个维度(即每个主成分)都代表了原始数据集中的某种结构或模式。通常,第一个主成分捕获了数据中最大的方差,第二个主成分捕获了第二大的方差,且与第一个主成分正交。

PCA的应用

  • 降维:通过减少数据的维度来简化数据集,同时保留最重要的信息。
  • 数据可视化:将高维数据投影到二维或三维空间,以便可视化。
  • 去噪:通过去除小的特征值对应的成分来减少数据中的噪声。
  • 特征提取:在机器学习中,PCA可以作为预处理步骤,提取更有意义的特征。

下面是他的代码:

import numpy as np
from scipy.linalg import svd

class PCA:
    def __init__(self, n_components=None, whiten=False, copy=True):
        self.n_components = n_components
        self.whiten = whiten
        self.copy = copy

    def fit(self, X, y=None):
        X = np.asarray(X)
        if X.ndim == 1:
            X = X[:, np.newaxis]
        
        # Center the data
        self.mean_ = np.mean(X, axis=0)
        X = X - self.mean_

        # Perform SVD
        U, S, V = svd(X, full_matrices=False)
        if self.n_components is None:
            self.n_components_ = V.shape[1]
        else:
            self.n_components_ = min(self.n_components, V.shape[1])

        # Store the components
        self.components_ = V[:self.n_components_]

        # Store the explained variance
        self.explained_variance_ = S[:self.n_components_]**2 / X.shape[0]
        
        return self

    def transform(self, X):
        check_is_fitted(self)
        X = np.asarray(X)
        if X.shape[1] != self.mean_.shape[0]:
            raise ValueError("Shape of X is different from the shape used to fit the model")
        
        X = X - self.mean_
        return np.dot(X, self.components_.T)

    def fit_transform(self, X, y=None, **kwargs):
        self.fit(X)
        return self.transform(X)

    def inverse_transform(self, X):
        check_is_fitted(self)
        X = np.asarray(X)
        return np.dot(X, self.components_) + self.mean_

    def score_samples(self, X):
        X = self.transform(X)
        return np.sum(X**2, axis=1)

    def score(self, X, y=None):
        # This method is not implemented in this simplified version
        pass

# Helper function to check if the model is fitted
def check_is_fitted(model):
    if not hasattr(model, 'components_'):
        raise ValueError("Model is not fitted")


# Example usage
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
pca = PCA(n_components=2)
X_r = pca.fit_transform(X)
print(X_r.shape)  # Output: (150, 2)

1. 导入依赖

import numpy as np
from scipy.linalg import svd

svd用于执行奇异值分解,我有讲过。

2. PCA 类定义

class PCA:
    def __init__(self, n_components=None, whiten=False, copy=True):
        self.n_components = n_components
        self.whiten = whiten
        self.copy = copy

这是 PCA 类的构造函数,它初始化了几个重要的属性:

  • n_components:要保留的主成分数量。如果设置为 None,则保留所有成分。
  • whiten:是否进行白化处理,即是否将主成分的方差缩放到1。
  • copy:是否在处理数据时复制数据,以避免修改原始数据。

3. 拟合方法

def fit(self, X, y=None):
    X = np.asarray(X)
    if X.ndim == 1:
        X = X[:, np.newaxis]
        
    # Center the data
    self.mean_ = np.mean(X, axis=0)
    X = X - self.mean_

    # Perform SVD
    U, S, V = svd(X, full_matrices=False)
    if self.n_components is None:
        self.n_components_ = V.shape[1]
    else:
        self.n_components_ = min(self.n_components, V.shape[1])

    # Store the components
    self.components_ = V[:self.n_components_]

    # Store the explained variance
    self.explained_variance_ = S[:self.n_components_]**2 / X.shape[0]
        
    return self

fit 方法用于计算数据的PCA变换:

  • 首先,将数据转换为 numpy 数组,并确保数据是二维的。
  • 计算数据的均值,并中心化数据(减去均值)。
  • 执行SVD,得到 US 和 V 三个矩阵。
  • SVD可以看之前的文章24/11/6 算法笔记 SVD-CSDN博客
  • 根据 n_components 的设置,确定保留的主成分数量。
  • 保存主成分(V 矩阵的列)和解释的方差。

主成分有什么用:

  • PCA可以减少数据的维度,同时保留最重要的特征。这有助于去除噪声和冗余信息,使得数据集更易于管理和分析。

4. 转换方法

def transform(self, X):
    check_is_fitted(self)
    X = np.asarray(X)
    if X.shape[1] != self.mean_.shape[0]:
        raise ValueError("Shape of X is different from the shape used to fit the model")
        
    X = X - self.mean_
    return np.dot(X, self.components_.T)

transform 方法用于将新数据投影到主成分上:

  • 确保模型已经被拟合。
  • 将输入数据转换为 numpy 数组,并检查数据的形状是否与拟合时的数据一致。
  • 中心化数据。
  • 将数据与主成分的转置矩阵相乘,得到降维后的数据。

5. 拟合和转换方法

def fit_transform(self, X, y=None, **kwargs):
    self.fit(X)
    return self.transform(X)

fit_transform 方法结合了 fittransform 方法,先拟合模型,然后将数据投影到主成分上。

6. 逆变换方法

def inverse_transform(self, X):
    check_is_fitted(self)
    X = np.asarray(X)
    return np.dot(X, self.components_) + self.mean_

7.样本得分函数

def score_samples(self, X):
    X = self.transform(X)
    return np.sum(X**2, axis=1)

8.辅助函数

def check_is_fitted(model):
    if not hasattr(model, 'components_'):
        raise ValueError("Model is not fitted")

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2-142【软件无线电原理与应用作业】基于matlab的圆形阵列的波束形成进行仿真

【软件无线电原理与应用作业】基于matlab的圆形阵列的波束形成进行仿真,具有14页文档。假设发射信号载频为1GHz,圆形阵列半径为0.8米,在圆周上均匀布置30个阵元。1.画出指向0度的方向图。2.如果目标在0度,有一不相干的干扰信号在3…

<项目代码>YOLOv8 苹果腐烂识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…

python练习相关代码

一元二次方程的求根公式为&#xff1a; import mathdef quadratic(a, b, c):discriminant b**2 - 4*a*cif discriminant < 0:return Noneelif discriminant 0:return [-b / (2*a)]else:root1 (-b math.sqrt(discriminant)) / (2*a)root2 (-b - math.sqrt(discriminant)…

2024软件测试面试热点问题

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 大厂面试热点问题 1、测试人员需要何时参加需求分析&#xff1f; 如果条件循序 原则上来说 是越早介入需求分析越好 因为测试人员对需求理解越深刻 对测试工…

windows、linux安装jmeter及设置中文显示

系列文章目录 1.windows、linux安装jmeter及设置中文显示 2.jmeter常用配置元件介绍总结之安装插件 3.jmeter常用配置元件介绍总结之取样器 windows、linux安装jmeter及设置中文显示 前言一、jdk安装1.windows安装jdk1.1.复制环境变量快捷跳转 2.linux安装jdk 二、下载安装jmet…

各种数据库介绍

1. 关系型数据库&#xff08;RDBMS&#xff09; MySQL • 特点&#xff1a;开源、免费&#xff0c;社区版功能强大且稳定。支持大量的并发连接&#xff0c;常用于Web应用。 • 适用场景&#xff1a;中小型网站、博客、电商等。 PostgreSQL • 特点&#xff1a;功能丰富&#xf…

【linux】查看不同网络命名空间的端口

在部署harbor时&#xff0c;内部用的是数据库postgresql&#xff0c;端口默认是: 5432&#xff0c;一开始以为这个数据库docker容器是在本命名空间中&#xff0c;一直用ss -lnt查询系统的端口&#xff0c;找不到5432端口。但是harbor要能正常使用&#xff0c;所有怀疑harbor的容…

使用ffmpeg和mediamtx模拟多通道rtsp相机

首先下载ffmpeg&#xff0c;在windows系统上直接下载可执行文件&#xff0c;并配置环境变量即可在命令行当中调用执行。 下载地址&#xff1a; https://ffmpeg.org/再在github上下载mediamtx搭建rtsp服务器&#xff0c;使用ffmpeg将码流推流到rtsp服务器。 下载地址&#xff1…

大数据分库分表方案

分库分表介绍 分库分表应用场景 分库分表介绍 大数据分库分表是一种数据库架构技术&#xff0c;旨在应对大数据量场景下的数据库性能瓶颈。以下是对大数据分库分表的详细解释&#xff1a; 一、定义与背景 定义&#xff1a; 分库&#xff1a;将一个大型数据库按照一定的规则…

关于word 页眉页脚的一些小问题

去掉页眉底纹&#xff1a; 对文档的段落边框和底纹进行设置&#xff0c;也是页眉横线怎么删除的一种解决方式&#xff0c;具体操作如下&#xff1a; 选中页眉中的横线文本&#xff1b; 点击【开始】选项卡&#xff0c;在【段落】组中点击【边框】按钮的下拉箭头&#xff1b; …

爬虫-------字体反爬

目录 一、了解什么是字体加密 二. 定位字体位置 三. python处理字体 1. 工具库 2. 字体读取 3. 处理字体 案例1:起点 案例2:字符偏移: 5请求数据 - 发现偏移量 5.4 多套字体替换 套用模板 版本1 版本2 四.项目实战 1. 采集目标 2. 逆向结果 一、了解什么是…

Fortran安装(vscode+gcc+Python)

编写时间&#xff1a; 2024年11月7日 环境配置&#xff1a; gcc VScode Python 条件&#xff1a; Windows 10 x64 VMware虚拟机 前言 这是我出的第2个关于Fortran安装的教程&#xff0c;由于上一个方法&#xff08;你可以在本专栏里找到&#xff09;对储存空间的要求比较…

外包干了2年,快要废了。。。

先说一下自己的情况&#xff0c;普通本科毕业&#xff0c;在外包干了2年多的功能测试&#xff0c;这几年因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境真的会…

丹摩征文活动|详解 DAMODEL(丹摩智算)平台:为 AI 开发者量身打造的智算云服务

本文 什么是 DAMODEL&#xff08;丹摩智算&#xff09;&#xff1f;DAMODEL 的平台特性快速上手 DAMODEL 平台GPU 实例概览创建 GPU 云实例 储存选项技术支持与社区服务结语 在人工智能领域的飞速发展中&#xff0c;计算资源与平台的选择变得尤为重要。为了帮助 AI 开发者解决高…

canal1.1.7使用canal-adapter进行mysql同步数据

重要的事情说前面&#xff0c;canal1.1.8需要jdk11以上&#xff0c;大家自行选择&#xff0c;我这由于项目原因只能使用1.1.7兼容版的 文章参考地址&#xff1a; canal 使用详解_canal使用-CSDN博客 使用canal.deployer-1.1.7和canal.adapter-1.1.7实现mysql数据同步_mysql更…

Docker安装XXL-JOB分布式调度任务

一、持久化 1、下载 xxl-job 源码,找到持久化脚本 2、创建 xxl-job 数据库,将上述文件中的脚本在本库执行即可 create database xxl_job charset utf8mb4 collate utf8mb4_general_ci; 二、安装 1、下载 xxl-job 镜像 docker pull xuxueli/xxl-job-admin:2.4.1 2、创建挂…

线性表之链表详解

欢迎来到我的&#xff1a;世界 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 前言线性表的概述链表的概述 内容链表的结构链表节点的定义 链表的基本功能单向链表的初始化链表的插入操作头插操作尾插操作 链表的删除操作头…

高校数字化校园中数据交换和共享平台的设计与实现(源码+定制+开发)校园数据整合平台、高校信息交换系统、校园数据整合平台、数字校园信息交换平台、校园数据集成管理

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

【Linux驱动开发】timer库下的jiffies时间戳和延时驱动编写

【Linux驱动开发】timer库下的jiffies时间戳和延时驱动编写 gitee地址&#xff1a; https://gitee.com/Mike_Zhou_Admin/Linux_Driver_Timestamp_Driver/更新以gitee为准 文章目录 timer库时间戳函数延时函数驱动代码应用测试附录&#xff1a;嵌入式Linux驱动开发基本步骤开发…

python安装了numpy却用不了且报错的解决方案和numpy的简单应用于图像处理

1.报错情况如下&#xff1a;Error importing numpy: 解决方法&#xff1a;降低python和numpy的版本&#xff0c;我一开始下载安装的都是最新版的python和numpy&#xff0c;后来降低了版本后就不报错且可正常使用了&#xff0c;这里给出我使用的版本作为参考&#xff08;记得卸…