关于PCA的一份介绍

news2024/9/25 9:28:55

在这篇文章中,我将介绍机器学习中的一种无监督学习算法——PCA,因为它主要有两种用途,即降维与特征提取,所以我将将围绕这两种用途来介绍它,包括基本概念,应用与代码实践。

一、 PCA

1.1 概念

PCA(principal component analysis)中文名叫主成分分析,是一种旋转数据集的方法,也是一种广泛使用的统计方法,用于探索数据内部的结构,尤其是当变量间存在相关性的时候。它在旋转数据集后,通常是根据新特征对数据的重要性来选择它的一个子集。

1.2 PCA步骤

PCA整体有五个步骤,分别是:1.标准化数据,2.计算协方差矩阵,3.计算特征值与特征向量,4.排序并选择主成分,5.数据投影。详细些说,PCA因为对于量纲敏感,所以需要统一数据的量纲,进行标准化处理,而使之有相同的尺度;而计算协方差则是因为PCA是为了寻找数据的最大方差方向,而协方差则正好反应了特征间的相关性;而特征值的计算是因为特征值的大小反映了该特征方向上方差的大小;在选择主成分时,会按照特征值从大到小排序,选取前k个特征向量作为主成分,这k个特征向量构成一个新的基,用于投影原始数据;最后就是将原始数据投影到刚才得到的那个新的基上。

1.3 PCA的优缺点

优点:PCA可以降低程序的复杂度,并为数据提供一种可视化的方法,而且也可以在一定程度上减少噪声,因为PCA倾向于保留最重要的信息。

缺点:PCA假设数据的主要信息可以通过方差来得到,但会存在信息存在于低方差方向的现象,而且PCA是种线性的方法,如果数据中存在非线性的结构,那么PCA可能就无法很好捕捉这些结构。

二、降维

1.1 概念

降维(Dimensionality Reduction)是数据科学和机器学习中一个重要的概念和技术,它的目的是通过减少数据的特征数量来简化数据集,同时尽可能保留数据的关键信息。降维技术广泛应用于数据预处理阶段,以提高后续分析或建模的效率和效果。

1.2 降维的方法

关于降维的方法,主要分为两种,一种是线性方法,一种是非线性方法。其中,关于线性方法常见的有三种,分别是:主成分分析(PCA)、线性判别法(LDA)、因子分析(FA);而非线性分析主要有四种,分别为:t-分布邻域嵌入(t-SNE)、多维尺度分析(MDS)、局部线性嵌入(LLE)、自组织映射(SOM)。

具体关于这七中降维方法我会在之后单独再写一篇关于降维的文章来介绍,所以在此不会多言。

1.3 降维的应用

降维可以应用在各个方面,比如如下的这个数据可视化上,此外,在NLP、生物基因等方面也有着不同的应用。

1.4 python代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score

# 数据加载及预处理
digits = load_digits()
X = digits.data
y = digits.target
scaler = StandardScaler()
X_scaler = scaler.fit_transform(X)

# 降维
pca = PCA(n_components=50)
X_pca = pca.fit_transform(X_scaler)

# 数据划分
X_train, X_test, y_train, y_test = train_test_split(X_pca,y,random_state=42)

# mlp实例化
mlp = MLPClassifier(hidden_layer_sizes=(100,), max_iter=1000)
mlp.fit(X_train,y_train)

# 预测
y_pre = mlp.predict(X_test)
accuracy = accuracy_score(y_test, y_pre)
print("The accuracy score is: {}".format(accuracy))

# 可视化
pca_vis = PCA(n_components=2)
X_vis = pca_vis.fit_transform(X_scaler)
plt.figure(figsize=(8, 6))
for digit in range(10):
    plt.scatter(X_vis[y == digit, 0], X_vis[y == digit, 1], label=f"Digit {digit}", alpha=0.7)
plt.xlabel("First Principal Component")
plt.ylabel("Second Principal Component")
plt.legend()
plt.title("PCA of Digits Dataset")
plt.grid(True)

# 热图绘制
plt.matshow(pca_vis.components_, cmap='viridis')
plt.xticks([0,1],["First component", "Second component"])
plt.colorbar()
plt.xticks(range(len(digits.feature_names)),
           digits.feature_names,rotation=60,ha='left')
plt.xlabel("Feature")
plt.ylabel("principal components")
plt.show()

在这个代码中,是对于一个手写数字用多层感知机来进行识别,期间分别对于这个手写数字的数据集进行了两次的pca降维操作,但它们的目的不同,在第一次中,降维是为了让数据集更适于mlp去训练,这样做可以减少代码的计算复杂度、去除噪声并提高性能;第二次降维则是为了数据的可视化,它将数据从原有的维数降到二维,以此来让其能够展示在平面图表上,并有助于查看这些数据的分布情况。

关于代码的输出如下:

我们需要知道,每次进行运算得到的结构其实都有可能不相同,但极为近似,就像我上一次的结果就是0.98,而之所以这样是因为神经网络的权重随机初始化的,而且在训练过程中关于正则化等技术都有可能导致结果的不一样。

然后是这个代码给出的图像:

 三、 特征提取

1.1 概念

特征提取(Feature Extraction)是数据科学和机器学习中的一个重要环节,它涉及从原始数据中提取有用的特征或信息,以供后续的分析或建模使用。特征提取的目标是在保留数据的关键信息的同时,减少数据的复杂性和维度,从而提高模型的性能和解释性。

1.2 特征提取的方法

关于特征提取,可以根据其是否依赖标签而将方法分为两种:有监督特征提取和无监督特征提取。关于有监督特征提取的常见方法有:线性判别分析(LDA)、特征选择、特征构造、决策树特征重要性。关于无监督特征提取有:主成分分析(PCA)、非负举证分解(NMF)、自编码器、t-分布邻域嵌入(t-SNE)、多维尺度分析。

1.3 特征提取的应用

关于特征提取,它可以用于多个方面,下面的这个人脸识别就是基于PCA的一个特征提取应用,此外,图像分类、基因表达数据分析、股票市场分析等都会应用到它。

1.4 python代码

如下这个代码是关于人脸识别的,它会将判别是同一个人的所有图像一起显示出来。本来关于人脸照片的数据集可以在sklearn上直接获取,通过这个导包的方式:

from sklearn.datasets import fetch_lfw_people

但在实践中发现会出现网络连接上的报错,像这样:raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 403: Forbidden

那么,为了解决这个问题,我便在kaggle上找到了一个人脸识别的数据集,其url在这里:

face-recog-dataset (kaggle.com)

 那么,具体的代码如下:

from sklearn.metrics import classification_report
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
import os
import glob
from PIL import Image
import matplotlib.pyplot as plt
import warnings

# 指定图像文件夹的路径
all_path = r"C:\Users\20349\Desktop\ArtificialIntelligence\ML\kaggle\人脸识别数据集"

# 获取所有jpg图像的路径列表
image_path = glob.glob(os.path.join(all_path, '*.jpg'))

# 设定一个统一的大小
target_size = (128, 128)

# 指定颜色模式
convert_mode = 'RGB'

# 读取并处理所有图像
image_size = []
labels = []  # 假设你已经有了对应的标签列表

for idx, path in enumerate(image_path):
    img = Image.open(path).convert(convert_mode).resize(target_size)
    image_size.append(np.array(img))
    labels.append(idx)  # 这里假设每个图像对应一个唯一的标签

# 将图像列表转换为NumPy数组
image_array = np.array(image_size)

# 数据预处理:归一化
image_array = image_array.astype('float32') / 255.0

# 将图像数组展平为一维向量
flattened_images = image_array.reshape(image_array.shape[0], -1)

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

# PCA特征提取
pca = PCA(n_components=150)
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.transform(X_test)

# KNN分类器
clf = KNeighborsClassifier(n_neighbors=3)
clf.fit(X_train_pca, y_train)

# 预测
y_pred = clf.predict(X_test_pca)

# 打印分类报告
with warnings.catch_warnings():
    warnings.filterwarnings("ignore", category=UserWarning)
    print(classification_report(y_test, y_pred, zero_division=1))

# 显示部分图像及其预测标签
show = min(10, len(X_test))
fig, axes = plt.subplots(2, (show + 1) // 2, figsize=(15, 8))
axes = axes.ravel()

for i in range(show):
    # 重塑为原始的三维数组 (128, 128, 3)
    img = X_test[i].reshape(target_size[0], target_size[1], 3)
    axes[i].imshow(img)
    axes[i].set_title(f'Predicted: {y_pred[i]}, Actual: {y_test[i]}')
    axes[i].set_xticks([])
    axes[i].set_yticks([])

plt.tight_layout()
plt.show()

最后我们会从众多的.jpg的文件中识别出同一人的图像,而如下则是随机读取的某一段图像:

然后这是预测结果: 

不过我们观察这个结果,会发现有一定的预测错误,这可能是PCA降维不足导致的,那么我们可以考虑增加主成分的数量或是采用其他特征提取方法来改善。

此上

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

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

相关文章

dev containers plugins for vscode构建虚拟开发环境

0. 需求说明 自用笔记本构建一套开发环境,用docker 虚拟插件 dev containers,实现开发环境的构建,我想构建一套LLMs的环境,由于环境配置太多,不想污染本地环境,所以选择隔离技术 1. 环境准备 vscodedocker 2. 步骤…

任意长度并行前缀和 扫描算法 《PMPP》笔记

下面的算法针对于任意长度输入 对于大数据集,首先将输入分为几段,每一段放进共享内存并用一个线程块处理,比如一个线程块使用1024个线程的话,每个块最多能处理2048个元素。 在前面代码中,一个块最后的执行结果保存到了…

桥接模式和NET模式的区别

桥接模式和NET模式的区别 NAT模式: NAT:网络地址转换(模式):借助宿主机来上网,没桥接那么麻烦,只用配置DNS即可。 缺点:扎根于宿主机,不能和局域网内其它真实的主机进行…

用Python实现运筹学——Day 2: 线性规划的基本概念

一、学习内容 线性规划的定义: 线性规划(Linear Programming, LP)是一种用于求解约束条件下线性目标函数最优解的方法。线性规划问题通常涉及最大化或最小化一个线性目标函数,目标函数的变量受一组线性不等式或等式的约束。 目标…

C语言 | Leetcode C语言题解之第435题无重叠区间

题目: 题解: int cmp(int** a, int** b) {return (*a)[1] - (*b)[1]; }int eraseOverlapIntervals(int** intervals, int intervalsSize, int* intervalsColSize) {if (intervalsSize 0) {return 0;}qsort(intervals, intervalsSize, sizeof(int*), cm…

【React】Ant Design 5.x版本drawer抽屉黑边问题

环境 antd: ^5.14.1react: ^18 问题情况 <Drawer open{open} closable{false} mask{false} width{680}getContainer{props.getContainer || undefined}><p>Some contents...</p><p>Some contents...</p><p>Some contents...</p> …

[网络] 网络层--IP协议

目录 一、IP协议 1.1 基本概念 1.2 IP协议报头 1.3 如何将报头和有效载荷分离和分用 1.4 分片与组装 1.5 如何减少分片&#xff1f; 1.6 分片和封装的具体过程 二、网段划分 2.1 再次理解IP地址 2.2 了解DHCP 2.3 网络划分方案 2.4 为什么要进行网络划分 2.5 特殊的…

Java基础——字节流和字符流

字节流和字符流的用法几乎完全一样&#xff0c;区别在于字节流和字符流所操作的数据单元不同&#xff0c;字节流操作的单元是数据单元是8位的字节&#xff0c;字符流操作的是数据单元为16位的字符。 为什么要有字符流&#xff1f; Java中字符是采用Unicode标准&#xff0c;Un…

【Go语言】Go语言结构体全面解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

基于 Canvas 的可缩放拖动网格示例(Vue3以及TypeScript )

文章目录 1. 基本知识2. Vue33. TypeScript 1. 基本知识 基本知识讲解&#xff1a; Canvas API&#xff1a; 一种用于在网页上绘制图形的 HTML 元素&#xff0c;使用 JavaScript 的 Canvas API 来进行绘制 使用 getContext(2d) 方法获取 2D 绘图上下文&#xff0c;允许开发者绘…

MySQL数据库备份详解

文章目录 引言● 数据库备份的重要性 MySQL数据库备份的基础知识● 备份类型1、完全备份2、增量备份3、差异备份 ● 备份工具与方法1、逻辑备份工具——mysqldump2、物理备份工具——Xtrabackup3、第三方解决方案 MySQL数据库备份的实施步骤1、环境准备2、选择合适的备份工具与…

【Linux基础IO】深入解析Linux基础IO缓冲区机制:提升文件操作效率的关键

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;暂无 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux基础IO &#x1f4d2;1. 什么是缓…

14.第二阶段x86游戏实战2-C++语言开发环境搭建-VisualStudio2017

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

基于jsonpath_ng的JSON数据查改增删

jsonpath_ng支持JSON数据的读写操作。 安装 pip install jsonpath-ng测试数据 from jsonpath_ng import parse import jsonjson_data { "store": {"book": [ { "category": "reference","author": "Nigel Rees&qu…

数据集-目标检测系列-鲨鱼检测数据集 shark >> DataBall

数据集-目标检测系列-鲨鱼检测数据集 shark >> DataBall 数据集-目标检测系列-鲨鱼检测数据集 shark 数据量&#xff1a;6k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;百种数据集&#xff0c;持续增加中。 示例&…

【自动驾驶】基于车辆几何模型的横向控制算法 | Stanley 算法详解与编程实现

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

【Python】探索 Elpy:Emacs 中的 Python 开发环境

可以短时间不开心&#xff0c;但别长时间不清醒。 对于使用 Emacs 编辑器的 Python 开发者来说&#xff0c;Elpy 是一个强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它通过整合多个 Emacs Lisp 和 Python 包&#xff0c;提供了一套完整的 Python 编程支持。本文…

丹摩智算平台体验:AI开发从未如此简单

目录 初次接触丹摩智算GPU算力资源表格 轻松创建GPU实例镜像选择 实验过程体验实验中的一些细节 使用后的感受一点小建议总结 最近我一直在学习一些与深度学习相关的知识&#xff0c;准备自己动手做一些模型训练的实验。平时在自己电脑上跑模型总感觉有点吃力&#xff0c;特别是…

复制他人 CSDN 文章到自己的博客

文章目录 0.前言步骤 0.前言 在复制别人文章发布时&#xff0c;记得表明转载哦 步骤 在需要复制的csdn 文章页面&#xff0c;打开浏览器开发者工具&#xff08;F12&#xff09;Ctrl F 查找"article_content"标签头 右键“Copy”->“Copy element”新建一个 tx…

[大语言模型-论文精读] ACL2024-长尾知识在检索增强型大型语言模型中的作用

ACL2024-长尾知识在检索增强型大型语言模型中的作用 On the Role of Long-tail Knowledge in Retrieval Augmented Large Language Models Authors: Dongyang Li, Junbing Yan, Taolin Zhang, Chengyu Wang, Xiaofeng He, Longtao Huang, Hui Xue, Jun Huang 1.概览 问题解决&…