首页 > 编程语言 >降维算法 0基础小白也能懂(附代码)

降维算法 0基础小白也能懂(附代码)

时间:2024-09-13 11:35:31浏览次数:8  
标签:matrix 特征向量 协方差 矩阵 小白 降维 算法 PCA

降维算法 0基础小白也能懂(附代码)

原文链接

啥是降维算法

在互联网大数据场景下,我们经常需要面对高维数据,在对这些数据做分析和可视化的时候,我们通常会面对「高维」这个障碍。在数据挖掘和建模的过程中,高维数据也同样带来大的计算量,占据更多的资源,而且许多变量之间可能存在相关性,从而增加了分析与建模的复杂性。

我们希望找到一种方法,在对数据完成降维「压缩」的同时,尽量减少信息损失。由于各变量之间存在一定的相关关系,因此可以考虑将关系紧密的变量变成尽可能少的新变量,使这些新变量是两两不相关的,那么就可以用较少的综合指标分别代表存在于各个变量中的各类信息。机器学习中的降维算法就是这样的一类算法。

主成分分析(Principal Components Analysis,简称PCA)是最重要的数据降维方法之一。在数据压缩消除冗余和数据噪音消除等领域都有广泛的应用。本篇我们来展开讲解一下这个算法。

PCA与最大可分性

对于\(X= \left[ \begin{matrix} x_1 \\ x_2 \\ \vdots\\ x_n \\ \end{matrix} \right] ,X\in R^n\),我们希望\(X\)从\(n\)维降到\(n^{'}\)维,同时希望信息损失最少。比如,从\(n=2\)维降到\(n^{'}=1\)维

上图为一个典型的例子,假如我们要对一系列人的样本进行数据降维(每个样本包含「身高」「体重」两个维度)。右图我们既可以降维到第一主成分轴,也可以降维到第二主成分轴。

哪个主成分轴更优呢?从直观感觉上,我们会认为「第一主成分轴」优于「第二主成分轴」,因为它比较大程度保留了数据之间的区分性(保留大部分信息)。

对PCA算法而言,我们希望找到小于原数据维度的若干个投影坐标方向,把数据投影在这些方向,获得压缩的信息表示。下面我们就一步一步来推导一下 PCA 算法原理。

基变换

其实就是线性代数里面的矩阵相乘

方差

在本文的开始部分,我们提到了,降维的目的是希望压缩数据但信息损失最少,也就是说,我们希望投影后的数据尽可能分散开。在数学上,这种分散程度我们用「方差」来表达,方差越大,数据越分散。

设第一个特征为\(a\),第二个特征为\(b\),则某个样本可以写作\(x_i=\left[ \begin{matrix} a \\ b \\ \end{matrix} \right]\)

协方差

协方差(Covariance)在概率和统计学中用于衡量两个变量的总体误差。比如对于二维随机变量 \(x_i=\left[ \begin{matrix} a \\ b \\ \end{matrix} \right]\),特征a,b除了自身的数学期望和方差,还需要讨论a,b之间互相关系的数学特征。

协方差 \(Cov=\frac{1}{m}\sum_{i=1}^ma_ib_i\)

当 \(Cov=0\)时,变量a,b完全独立,这也是我们希望达到的优化目标。方差是协方差的一种特殊情况,即当两个变量是相同的情况 。

协方差矩阵

对于\(n\)维随机变量,\(x_i=\left[ \begin{matrix} x_1 \\ x_2 \\ \vdots \\ x_n\\ \end{matrix} \right] ,C =\left[ \begin{matrix} Var(x_1) & Cov(x_1,x_2) & \cdots & Cov(x_1,x_n) \\ Cov(x_2,x_1) & Var(x_2) & \cdots & Cov(x_1,x_n) \\ \vdots & \vdots & \ddots & \vdots \\ Cov(x_n,x_1) & Cov(x_n,x_2) & \cdots & Var(x_n) \\ \end{matrix} \right] \)
我们可以看到,协方差矩阵是 n 行 n 列的对称矩阵,主对角线上是方差,而协对角线上是协方差。

那如果有 m 个样本的话,\(X=\left[ \begin{matrix} a_1 & a_2 &\cdots & a_m \\ b_1 & b_2 & \cdots & b_m \\ \end{matrix} \right]\)。对\(X\)做一些变换,用 \(X\) 乘以 \(X\) 的转置,并乘上系数 \(1/m\):

\(\frac{1}{m}XX^T=\frac{1}{m} \left[ \begin{matrix} a_1 & a_2 &\cdots & a_m \\ b_1 & b_2 & \cdots & b_m \\ \end{matrix} \right]\left[ \begin{matrix} a_1 & b_1 \\ a_2 & b_2 \\ \vdots & \vdots \\ a_n & b_n \end{matrix} \right] ==\left[ \begin{matrix} \frac{1}{m}\sum_{i=1}^ma_i^2 & \frac{1}{m}\sum_{i=1}^ma_ib_i \\ \frac{1}{m}\sum_{i=1}^ma_ib_i & \frac{1}{m}\sum_{i=1}^mb_i^2 \\ \end{matrix} \right] \)
这正是协方差矩阵!

协方差矩阵对角化

再回到我们的场景和目标:

  • 现在我们有 m 个样本数据,每个样本有 n 个特征,那么设这些原始数据为 X,X 为 n 行 m 列的矩阵。

  • 想要找到一个基 P ,使 \(Y_{r\times m}=P_{r\times n}X_{n\times m}\),其中 \(r<n\),达到降维的目的

设 \(X\) 的协方差矩阵为 \(C\),\(Y\) 的协方差矩阵为 \(D\),且\(Y=PX\) 。

我们的目标变为:对原始数据X做PCA后,得到的 Y 的协方差矩阵 D 的各个方向方差最大(数据的方差表示了数据在该方向上的分散程度,也可以看作是数据中蕴含的信息量。通过选择方差最大的方向,我们能够保留尽可能多的原始数据中的信息。),协方差为 0。

那么 C 与 D 是什么关系呢?

\(D=\frac{1}{m}YY^T=\frac{1}{m}(PX)(PX^T)=\frac{1}{m}PXX^TP^T=PCP^T\)

到这里就可以了,可以发现\(D\)和\(C\)是通过\(P\)相联系的,同时呢,我们希望它是对角矩阵。这是因为对角矩阵意味着各个维度之间的协方差为 0,也就是说,新的主成分是相互独立的。这正是 PCA 的目标:找到这样一个变换,使得在新坐标系下,各个方向上数据的方差最大且相互独立。

之前我们说过,协方差矩阵\(C\)是一个是对称矩阵,实对称矩阵具有一些非常有用的性质:

正交特性:实对称矩阵的不同特征值对应的特征向量必然正交。
特征向量的线性无关性:对于具有相同特征值的特征向量,存在多个线性无关的特征向量,并且这些特征向量可以正交化。

由上面两条可知,一个\(n\)行\(n\)列的实对称矩阵一定可以找到\(n\)个单位正交特征向量,设这\(n\)个特征向量为\(e_1,e_2,...,e_n\),我们将其按列组成矩阵:\(E=[e_1 e_2 ... e_n]\)

则对协方差矩阵\(C\)有如下结论:
\(E^TCE=\)\(\Lambda = \begin{pmatrix} \lambda_1 & 0 & 0 & \dots & 0 \\ 0 & \lambda_2 & 0 & \dots & 0 \\ 0 & 0 & \lambda_3 & \dots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \dots & \lambda_n \end{pmatrix}\),其对角元素为各特征向量对应的特征值(可能有重复)。

这里也就是\(E^T=P\),这样\(D\)就对角了。

PCA算法思路整理

代码实现

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs


# 定义PCA算法
def PCA(X, num_components):
    # 数据中心化
    X_meaned = X - np.mean(X, axis=0)

    # 计算协方差矩阵
    covariance_matrix = np.cov(X_meaned, rowvar=False)

    # 计算协方差矩阵的特征值和特征向量
    eigen_values, eigen_vectors = np.linalg.eigh(covariance_matrix)

    # 按照特征值从大到小排序
    sorted_index = np.argsort(eigen_values)[::-1]
    sorted_eigenvalue = eigen_values[sorted_index]
    sorted_eigenvectors = eigen_vectors[:, sorted_index]

    # 选择前num_components个特征向量
    eigenvector_subset = sorted_eigenvectors[:, 0:num_components]

    # 将数据投影到这些特征向量上
    X_reduced = np.dot(X_meaned, eigenvector_subset)

    return X_reduced


# 生成几个聚类的三维数据集
X, _ = make_blobs(n_samples=300, centers=3, n_features=3, cluster_std=1.0, random_state=42)

# 使用PCA将三维数据降维到二维
X_reduced = PCA(X, 2)

# 绘制三维原始数据和二维降维数据
fig = plt.figure(figsize=(12, 6))

# 三维原始数据
ax1 = fig.add_subplot(121, projection='3d')
ax1.scatter(X[:, 0], X[:, 1], X[:, 2], color='blue', alpha=0.7)
ax1.set_title('Original 3D Clustered Data')
ax1.set_xlabel('X1')
ax1.set_ylabel('X2')
ax1.set_zlabel('X3')

# 二维降维数据
ax2 = fig.add_subplot(122)
ax2.scatter(X_reduced[:, 0], X_reduced[:, 1], color='red', alpha=0.7)
ax2.set_title('2D Clustered Data After PCA')
ax2.set_xlabel('PC1')
ax2.set_ylabel('PC2')

plt.tight_layout()
plt.show()

结果如下

标签:matrix,特征向量,协方差,矩阵,小白,降维,算法,PCA
From: https://www.cnblogs.com/Mephostopheles/p/18409974

相关文章

  • 算法备案的一个流程是什么?
    一、备案系统注册及登录    算法备案填报人员在初次进入互联网信息服务算法备案系统时,需点击首页右下方的“填报人员入口”进行注册登录系统。二、主体信息填报    算法备案填报人员点击主页的“主体信息”,进行主体信息填报。按照备案主体的实际情况准确......
  • 算法思想之概率算法
    概率算法概率算法的基本概念概率算法是一种算法,它利用概率论的原理来解决问题。这种算法通常用于解决复杂的问题,特别是在确定性算法难以求解或者效率较低的情况下。概率算法的一个重要特点是它不总是保证得到正确的结果,而是以一定的概率得到正确的结果。概率算法可以分为两类:蒙......
  • 最全元器件焊接指南,从小白到精通!
    如果你觉得焊接是一件轻松的事,那我可得提醒你,焊接不仅需要技巧,还需要大量的练习。每一块完美的焊点背后都是数不清的尝试和经验积累!焊接贴片元器件的心得最近累积了不少项目(坑)在焊接过程中,本来以为自己焊接技术还不错(bushi),但实际操作中发现自己还有很多需要提高的地方。......
  • 从小白到高手:Windows注册表基础运维全攻略
    哈喽大家好,欢迎来到虚拟化时代君(XNHCYL)。“  大家好,我是虚拟化时代君,一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…(每天更新不间断,福利不见不散)第一章、小叙经常遇到一些Windows疑难杂症,大家都知道可以通过修改注册表的方......
  • 操作系统实验——存储器的分配与回收算法实现
    1.实验内容:Exercise1:本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。Exercise2:采用最先适应法、最佳适应法、最坏适应法分配主存空间。Exercise3:当一个新作业要求装入主存时,必须查空闲区表,从中找出一个......
  • 0910-0911 shell编程与基础算法(leetCode )
    栈的定义栈(Stack),也称为堆栈,它是一种特殊的线性表,只允许在表的一端进行插入和删除操作。允许在表操作的一端称为栈顶(Top),另一端称为栈底(Bottom)。栈顶是动态变化的,它由一个称为栈顶指针(top)的变量指示。当表中没有元素时,称为空栈。栈的插入操作称为入栈或进栈,删除操作称为出栈或......
  • 从0开始的算法(数据结构和算法)基础(十)
    重新开始更新了,回学校处理事情半个月没有更新,大家勿怪啊。分治算法什么是分治的思想分治的字面意思是分而治之,将问题进行分化,从而进行处理,最后将结果进行合并。尽量的将问题分的不可以再分,分到和操作系统里面的原语是一样的,用较为多空间进行多线程的并行,节省时间运行。递......
  • 代码随想录算法训练营,9月12日 | 513.找树左下角的值,112. 路径总和,106.从中序与后序遍
    513.找树左下角的值题目链接:513.找树左下角的值文档讲解︰代码随想录(programmercarl.com)视频讲解︰找树左下角的值日期:2024-09-12想法:1.迭代:用层序遍历,遍历每层时记录下第一个节点的值,到最后一层就是要求的值;2.递归:根据最大的深度来找目标值。Java代码如下://迭代classSolut......
  • datastructure与算法 orderedPair
    /**  Aninterfacethatdescribestheoperationsofasetofobjects.  @authorCharlesHoot,FrankM.Carrano  @version4.0*/publicinterfaceSetInterface<T>{  /**Getsthecurrentnumberofentriesinthisset.    @return Theintegernum......
  • 数据结构与算法chapter-0
    /**Aninterfaceformethodsthatreturntheperimeterandareaofanobject.@[email protected]*/publicinterfaceMeasurable{/**Getstheperimeter.@returnTheperimeter.*/publicdoublegetPerimeter()......