主成分分析(PCA):探索数据的核心

文章目录

  • 前言
  • 1. 什么是 PCA ?
  • 2. PCA 的原理
    • 2.1 协方差和方差
    • 2.2 核心思想
    • 2.3 步骤
  • 3. PCA 的应用场景
  • 4. PCA 的优缺点
  • 5. 示例:人脸识别
    • 5.1 完整代码
    • 5.2 运行结果
  • 结语


前言

当今社会,数据无处不在。从社交媒体到金融交易,从医疗诊断到市场分析,数据的规模不断增长,这些数据往往具有高维度和复杂性,使得我们难以直观地理解其内在结构。而如何从海量的数据中提取出有用的信息和模式成为了一个巨大的挑战。这就是主成分分析(Principal Component Analysis,PCA)发挥作用的地方,它作为一种强大的降维技术,可以帮助我们发现数据背后的规律和奥秘。



1. 什么是 PCA ?

主成分分析(Principal Component Analysis,PCA)是一种统计学方法,旨在通过线性变换将原始数据转化为一组新的变量,这些新变量称为主成分。每个主成分都是原始数据的线性组合,且彼此之间相互独立。主成分按照方差的大小排列,前几个主成分包含了数据中大部分的信息。

在机器学习和数据科学领域,主成分分析是一种经典且常用的降维技术。通过将原始数据转换为一组新的无关变量,我们可以摒弃其中的噪声和冗余,提取出数据的主要特征。与其他降维技术相比,主成分分析不仅可以降低数据维度,还能保留尽可能多的信息。

2. PCA 的原理

为了理解主成分分析的原理,首先需要了解协方差和方差的概念。协方差描述了两个变量之间的线性关系程度,方差则衡量单个变量的离散程度。主成分分析基于这些概念,通过寻找投影轴使得数据方差最大化,实现降维的目标。

2.1 协方差和方差

协方差描述了两个变量之间的线性关系程度。对于两个变量 x x x y y y ,它们的协方差可以通过以下公式计算:

cov ( x , y ) = 1 n − 1 ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) \text{cov}(\mathbf{x}, \mathbf{y}) = \frac{1}{n-1} \sum_{i=1}^{n} (x_i - \bar{x})(y_i - \bar{y}) cov(x,y)=n11i=1n(xixˉ)(yiyˉ)

其中, n n n 表示样本的数量, x i x_i xi y i y_i yi 分别表示变量 x x x y y y 的取值, x ˉ \bar{x} xˉ y ˉ \bar{y} yˉ 表示变量 x x x y y y 的均值。协方差的值可以为正、负或零,分别表示正相关、负相关和无关。

方差衡量单个变量的离散程度,可以通过以下公式计算:

Var ( x ) = 1 n − 1 ∑ i = 1 n ( x i − x ˉ ) 2 \text{Var}(\mathbf{x}) = \frac{1}{n-1} \sum_{i=1}^{n} (x_i - \bar{x})^2 Var(x)=n11i=1n(xixˉ)2

其中, x i x_i xi 表示变量 x x x 的取值, x ˉ \bar{x} xˉ 表示变量 x x x 的均值。

2.2 核心思想

PCA 的核心思想是通过线性变换将原始数据投影到一个新的坐标系中,该坐标系的特点是使得投影后的数据在各个维度上的方差最大化。通过选择最大方差的特征向量,我们可以得到一个保留了数据主要信息的低维表示。

2.3 步骤

具体来说,PCA 的步骤如下:

  1. 标准化数据:对原始数据进行均值中心化和标准差归一化,保证每个特征具有零均值和单位方差,以避免不同尺度的特征对主成分分析的影响。

  2. 计算协方差矩阵:根据标准化后的数据计算协方差矩阵,该矩阵描述了各个特征之间的相关性。

  3. 特征值分解:对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。

    特征向量描述了数据在新的坐标系中的方向,而特征值表示了以该特征向量作为基的重要性。

  4. 选择主成分:按照特征值的大小,选择前k个特征向量作为主成分,其中k是我们希望降低后的维度数目。

    在选择主成分时,我们通常会选择特征值较大的特征向量。这是因为特征值越大,说明对应的特征向量所表示的主成分包含的信息越多。通过选择适当数量的主成分,我们可以将数据从原始的高维空间投影到低维的空间中,以实现数据降维的目的。

  5. 投影数据:将标准化后的数据投影到选择的主成分上,得到降维后的数据表示。

3. PCA 的应用场景

PCA 在各个领域都有广泛的应用。以下是一些常见的应用场景:

  • 数据压缩:对于大规模数据集,PCA 可以大幅度减小数据的维度,从而节省存储空间和计算成本。
  • 数据可视化:通过将高维数据投影到二维或三维空间中,我们可以更好地理解数据集的结构和分布。
  • 特征选择和提取:PCA 能够从原始数据中发现潜在的重要特征,帮助我们理解数据背后的信息。通过选取最重要的主成分,PCA 可以减少模型复杂度和数据存储需求,同时仍能保持较高的分类或回归性能。
  • 去除噪声:如果数据包含了噪声或冗余信息,PCA 可以通过去除其中的低方差分量来消除不相关的噪声和冗余数据,以提高数据质量。
  • 图像处理:使用 PCA 可以对图像进行降噪、压缩和特征提取,对于图像识别、人脸识别等任务具有重要意义。
  • 探索性数据分析:PCA 可以帮助发现数据集中存在的模式和结构,从而帮助决策和洞察。
  • 机器学习:通过降低数据的维度,PCA可以减少模型的复杂性,并提高训练速度和模型的泛化能力。

4. PCA 的优缺点

PCA 作为一种降维技术具有以下优点:

  • 可以简化数据集,降低数据维度,减少冗余和噪声,节省存储和计算的开销。
  • 可以帮助我们理解数据之间的关联性、模式和趋势。
  • 能够保持数据之间的最大差异性,提取主要特征,消除不相关的特征,发现数据中的关键信息。
  • 可以用于数据的可视化,方便数据的分析和理解。

然而,PCA 也存在一些限制和不足:

  • 在应用 PCA 之前,数据需要进行标准化处理,使得不同特征具有相同的权重。
  • 依赖于线性假设,可能无法捕捉非线性关系,对于非线性数据可能效果不佳。
  • 不保证可解释性,可能难以直接解释降维后的每个主成分的意义。
  • 对异常值敏感,在面临异常值时可能会对数据中的异常点过度拟合。
  • 降维过程中可能丢失一些信息,使得某些细节无法完全还原。

因此,在应用 PCA 时,需要根据具体问题的需求和数据的特点来进行权衡和选择。

5. 示例:人脸识别

人脸识别是 PCA 应用的一个典型例子。通过将人脸图像转换为主成分,我们可以捕捉到人脸的主要特征,从而实现人脸识别的任务。

以下是 PCA 实现人脸识别的Python代码:

  1. 导入所需的库:
import numpy as np
import os
import cv2
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split

在这里,我们导入了numpy用于数组操作,os用于文件路径操作,cv2用于读取和调整图像,sklearn库中的PCA用于主成分分析,KNeighborsClassifier用于K最近邻分类器,train_test_split用于划分训练集和测试集。

  1. 选择数据集并读取数据:
dataset_folder = 'Face'
selected_dataset = 'ORL_Faces'

X = []  # 存储人脸图像数据
y = []  # 存储对应的标签

images_folder = os.path.join(dataset_folder, selected_dataset)
for root, dirs, files in os.walk(images_folder):
    for file in files:
        if file.endswith('.pgm') or file.endswith('.jpg'):
            img_path = os.path.join(root, file)
            label = os.path.basename(os.path.dirname(img_path))
            face_img = cv2.imread(img_path, 0)
            face_img = cv2.resize(face_img, (100, 100))
            X.append(face_img.flatten())
            y.append(label)

在这里,我们首先指定数据集所在的文件夹(dataset_folder),然后选择一个数据集(selected_dataset)。我们遍历数据集文件夹中的每个人脸图像,读取图像并将其存储在x列表中,同时将对应的标签存储在y列表中。

  1. 将数据转换为numpy数组,并划分训练集和测试集:
X = np.array(X)
y = np.array(y)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

在这一步中,我们将图像数据和标签转换为numpy数组,并使用train_test_split函数将数据集划分为训练集和测试集,其中 20% 的数据作为测试集。

  1. 使用 PCA 降维:
n_components = 100
pca = PCA(n_components=n_components, whiten=True)
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.transform(X_test)

在这一步中,我们使用 PCA 进行降维。我们选择了 100 个主成分(n_components = 100),并通过fit_transform方法对训练集数据进行降维操作,然后使用transform方法对测试集数据进行降维。

  1. 使用 K最近邻分类器 进行人脸识别:
n_neighbors = 3
knn = KNeighborsClassifier(n_neighbors=n_neighbors)
knn.fit(X_train_pca, y_train)
y_pred = knn.predict(X_test_pca)

在这一步中,我们使用K最近邻分类器进行人脸识别。我们选择了3个邻居(n_neighbors = 3),并使用fit方法对降维后的训练数据进行分类器训练,然后使用predict方法对降维后的测试数据进行预测。

  1. 计算分类准确率:
accuracy = np.mean(y_pred == y_test) * 100
print(f"人脸识别准确率:{accuracy}%")

在这一步中,我们计算出人脸识别的准确率。我们比较预测结果(y_pred) 和 实际标签(y_test),计算预测值等于实际值的比例,并将其乘以 100 得到准确率。

  1. 可视化人脸识别结果:
random_index = np.random.randint(0, len(y_test))
test_img = X_test[random_index].reshape((100, 100))
predicted_label = y_pred[random_index]
true_label = y_test[random_index]

plt.subplot(1, 2, 1)
plt.imshow(test_img, cmap='gray')
plt.title('原始图像')
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(test_img, cmap='gray')
plt.title(f'预测: {predicted_label}\n实际: {true_label}')
plt.axis('off')

plt.tight_layout()
plt.show()

在这一步中,我们随机选择一个测试图像进行可视化。我们首先获取原始图像(test_img),然后获取预测标签(predicted_label)和实际标签(true_label)。然后,我们使用subplot函数将原始图像和预测结果以子图的形式显示出来,并用标题显示预测标签。

5.1 完整代码

import numpy as np
import os
import cv2
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
import matplotlib

matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为中文可显示的字体

dataset_folder = 'Face'  # 数据集所在的文件夹
selected_dataset = 'ORL_Faces'  # 选择ORL_Faces数据集

# 读取数据集
# 首先创建一个空的图像列表和对应的标签列表
X = []  # 存储人脸图像数据
y = []  # 存储对应的标签

# 遍历数据集文件夹中的每个人脸图像
images_folder = os.path.join(dataset_folder, selected_dataset)  # 数据集文件夹的路径
for root, dirs, files in os.walk(images_folder):
    for file in files:
        if file.endswith('.pgm') or file.endswith('.jpg'):
            img_path = os.path.join(root, file)
            label = os.path.basename(os.path.dirname(img_path))
            face_img = cv2.imread(img_path, 0)  # 以灰度图像格式读取人脸图像
            face_img = cv2.resize(face_img, (100, 100))  # 将人脸图像调整为统一大小,以便进行PCA
            X.append(face_img.flatten())  # 将人脸图像展平成一维数组并添加到列表中
            y.append(label)  # 添加对应的标签

# 将图像数据和标签转换为numpy数组
X = np.array(X)
y = np.array(y)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 主成分分析(PCA)降维
n_components = 100  # 设置PCA选择的主成分数量
pca = PCA(n_components=n_components, whiten=True)  # 初始化PCA模型
X_train_pca = pca.fit_transform(X_train)  # 对训练数据进行PCA降维
X_test_pca = pca.transform(X_test)  # 对测试数据进行PCA降维

# 使用K最近邻分类器进行人脸识别
n_neighbors = 3  # 设置K最近邻的邻居数量
knn = KNeighborsClassifier(n_neighbors=n_neighbors)  # 初始化K最近邻分类器
knn.fit(X_train_pca, y_train)  # 对降维后的训练数据进行分类器训练
y_pred = knn.predict(X_test_pca)  # 对降维后的测试数据进行分类器预测

# 计算分类准确率
accuracy = np.mean(y_pred == y_test) * 100
print(f"人脸识别准确率:{accuracy}%")

# 可视化人脸识别结果
# 随机选择一个测试样本进行可视化
random_index = np.random.randint(0, len(y_test))  # 随机选择一个索引
test_img = X_test[random_index].reshape((100, 100))  # 获取对应的图像
predicted_label = y_pred[random_index]  # 预测的标签
true_label = y_test[random_index]  # 实际的标签

# 显示原始图像
plt.subplot(1, 2, 1)
plt.imshow(test_img, cmap='gray')
plt.title('原始图像')
plt.axis('off')

# 显示预测结果
plt.subplot(1, 2, 2)
plt.imshow(test_img, cmap='gray')
plt.title(f'预测: {predicted_label}\n实际: {true_label}')
plt.axis('off')

plt.tight_layout()
plt.show()

5.2 运行结果

在这里插入图片描述



结语

在本篇博客中,我们探讨了 PCA 的概念、原理、应用以及其优缺点。PCA 作为一种简化数据和发现隐藏信息的利器,对于数据分析和特征提取具有重要意义。希望读者通过本文的学习,能够深入理解 PCA,并将其应用于实际问题中。然而,在应用 PCA 时,我们需要考虑数据的特点和具体问题的需求选择合适的主成分数量,并对结果进行解释和验证。

希望这篇博客对您有所帮助!如果您对主成分分析有更多的兴趣,建议进一步学习和探索相关的算法和应用。如果您有任何问题或疑惑,欢迎在下方留言讨论。感谢阅读!

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

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

相关文章

SpringBoot解决跨域的5种方式

本文来说下SpringBoot中实现跨域的5种方式。 文章目录 什么是跨域java解决CORS跨域请求的方式 返回新的CorsFilter(全局跨域)重写WebMvcConfigurer(全局跨域)使用注解 (局部跨域)手动设置响应头(局部跨域)使用自定义filter实现跨域 本文小结 什么是跨域 跨域:指的…

在FC中手工创建虚拟机模板

1、Linux去除个性化信息 (1)编辑网卡配置文件,只保留以下内容(以RHEL 7为例) (2)清除主机密钥信息(开机会自动生成) (3)清除Machine ID&#xff…

Java智慧工地管理平台系统源码带APP端源码

智慧工地将“互联网”的理念和技术引入建筑工地,从施工现场源头抓起,最大程度地收集人员、安全、环境、材料等关键业务数据,依托物联网、互联网,建立云端大数据管理平台,形成“端云大数据”的业务体系和新的管理模式&a…

JAVA反序列化之URLDNS链分析

简单介绍下urldns链 在此之前最好有如下知识,请自行bing or google学习。 什么是序列化 反序列化 ?特点! java对象反射调用? hashmap在java中是一种怎样的数据类型? dns解析记录有那…

Phind-CodeLlama-34B-v2 + Excel + Python 超强组合玩转数据分析

Phind-CodeLlama-34B-v2 Excel Python 超强组合玩转数据分析 0. 背景1. 使用 Phind-CodeLlama-34B-v2 pandas 实现数据导入和导出1.1 使用 Phind-CodeLlama-34B-v2 pandas 导入 Excel 文件中的数据1.2 使用 Phind-CodeLlama-34B-v2 pandas 读取部分Excel文件数据 2. 使用 …

Origin 2021软件安装包下载及安装教程

Origin 2021下载链接:https://docs.qq.com/doc/DUnJNb3p4VWJtUUhP 1.选中下载的压缩包,然后鼠标右键选择解压到"Origin 2021"文件夹 2.双击打开“Setup”文件夹 3.选中“Setup.exe”鼠标右键点击“以管理员身份运行” 4.点击“下一步" 5…

C ++类

定义一个Person类,私有成员int age,string &name,定义一个Stu类,包含私有成员double *score,写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数,完成对Person的运算符重载(算术运算符、条件运算…

每个AI/ML工程师必须了解的人工智能框架和工具

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

【SpringCloud Alibaba笔记】(2)Nacos服务注册与配置中心

Nacos Nacos简介与下载 是什么? 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos(Dynamic Naming and Configuration Service)就是注册中心+配置中心的组合 Nacos Eureka Config Bus 替代Eureka…

vscode配置的C++环境

目录 1、下载并安装VScode 2、下载MinGW 3、配置MinGW 3.1添加环境变量 3.2 Vscode配置 3.3测试 1、下载并安装VScode Visual Studio Code - Code Editing. Redefined 2、下载MinGW 在MinGW官网MinGW-w64 - for 32 and 64 bit Windows - Browse /mingw-w64/mingw-w64-r…

OpenOCD简介和下载安装(Ubuntu)

文章目录 OpenOCD简介OpenOCD软件模块OpenOCD源码下载OpenOCD安装 OpenOCD简介 OpenOCD(Open On-Chip Debugger)开放式片上调试器 OpenOCD官网 https://openocd.org/,进入官网点击 About 可以看到OpenOCD最初的设计是由国外一个叫Dominic Ra…

VC++ ado 实现单表CURD

继续修改前文的资产管理源码; 新建一个数据库sds;把代码中的数据库连接改为连接此库; 新建下图一个表; 把之前的资产类别管理对话框改为下图所示;对话框ID也改为下图; 资产类别管理菜单和ID改为下图; 直接修改资产类别管理对话框类不太方便,新建一个对话框类,没有关联…

FA模板制作流程

1、FA模板制作的流程(完整复制模板制作) 总结: FA完整复制云桌面模板流程: 1、安装一个全新的Windows,挂载并安装tools 2、关闭防火墙、启动administrator本地超管用户 3、挂载FusionAccess_WindowsDesktop_Instal…

【unity学习笔记】捏人+眨眼效果+口型效果

一、vriod捏人 1.在vroidstudio软件中捏人 2.导出模型(.vrm) 二、vrid导入unity的插件 1.在Git上搜索、打开univrm。 2.找到release页面找到合适的插件版本。(VRM-0.116.0_0f6c) 3.将univrm导入到工程中(assets)。 三…

rosdep init/update失败+rosdep 初始化脚本

我等会给你们开源一个python脚本,自动修改:并且把源代码发到博客里面 注意了使用这个脚本的前提是安装sudo apt install python3-rosdep2;否则文件夹就不对了 #rosdep初始化软件无界面 def replacex():addr1addrfiopen(addr1,r)contfi.read()contcont.…

「Verilog学习笔记」乘法与位运算

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 观察乘数的特点: 1111_1011 1_0000_0000 - 1 - 100 timescale 1ns/1nsmodule dajiang13(input [7:0] A,output [15:0] B);//*************code*********…

2024年人工智能领域10大预测

2023年人工智能领域如果只能筛选一个关键词的话,恐怕非“大模型”莫属。大模型的发展在过去一年中,让各行各业发生了天翻地覆的变化,有企业因大模型而新生,有企业因大模型而消亡。企业的变迁跟技术迭代息息相关,而大模…

阶段十-分布式-nginx服务器

一、Nginx简介 Nginx 是高性能的 HTTP 和反向代理的服务器,处理高并发能力是十分强大的,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。tomcat并发数量理论值是500,实际也就300左右。 1.2 正向代理 正向代理代理的是客户…

详解协方差矩阵,相关矩阵,互协方差矩阵(附完整例题分析)【2】

目录 一. 写在前面 二. 相关矩阵(Correlation Matrix) 三. 实战分析 例题1 (1)均值的关系 (2)协方差的关系 (3)小结 例题2 小结 四. 补充 一. 写在前面 有关协方差矩阵和…

2024年山东省中职“网络安全”试题——B-3:Web安全之综合渗透测试

B-3:Web安全之综合渗透测试 服务器场景名称:Server2010(关闭链接) 服务器场景操作系统:"需要环境有问题加q" 使用渗透机场景Kali中的工具扫描服务器,通过扫描服务器得到web端口,登陆…