机器学习--主成分分析 PCA

特征维度约减

     特征约减的目的是将高维特征向量映射到低维子空间中。比如:
给定n个样本(每个样本维度为p维){x1,....xn} 通过特征变换/投影矩阵实现特征空间的压缩:

高维数据

为何要维度约减?

  1. 数据压缩和存储:高维数据通常需要占用更大的存储空间。通过维度约减,可以将数据压缩为较低维度的表示形式,减少存储需求。

  2. 降低计算复杂度:在高维空间中进行计算通常更加复杂和耗时。通过维度约减,可以将计算转移到低维空间中进行,从而降低计算复杂度和提高计算效率。

  3. 特征选择和提取:维度约减可以帮助我们识别和选择最重要的特征,去除冗余和噪声。这有助于提高模型的泛化能力和性能,并减少过拟合的风险。

  4. 可视化和解释:将高维数据映射到二维或三维空间,可以更容易地进行可视化和解释。我们可以观察数据在低维空间中的分布、结构和聚类情况,发现数据中的潜在模式和规律。

  5. 数据处理和挖掘:在高维空间中,数据点之间的距离和相似度更难确定。通过维度约减,可以使得数据点之间的距离和相似度更加明确和可靠,从而更好地进行数据处理和挖掘任务。

常规维度约减方法 

  1. 监督学习:监督学习是指在有标注数据的前提下,通过构建模型来预测新的未知数据的标签或数值。监督学习需要使用一些已经标记好了标签的数据作为训练集,在模型训练过程中,计算模型预测值和实际值之间的误差,并不断调整模型参数使其错误率最小化。常见的监督学习算法包括决策树、支持向量机、神经网络等。

  2. 无监督学习:无监督学习是指在没有标注数据的情况下,尝试发现数据中的潜在模式和结构。无监督学习不需要已知的标签信息,而是将数据分成几个组或类,以便在后续的处理中可以更好地理解和处理数据。常见的无监督学习算法包括聚类、降维、异常检测等。

  3. 半监督学习:半监督学习是介于监督学习和无监督学习之间的学习方式。半监督学习旨在同时利用有标注和无标注数据来训练模型,以提高模型的性能。半监督学习算法通常利用少量的已标注数据来指导模型训练,同时结合大量未标注数据的信息进行模型优化。半监督学习经常用于在数据集标注成本较高、而未标注数据却很容易获取时。

主成分分析(PCA)

       主成分分析 (PCA) 基本思路:
1. 通过协方差分析,建立高维空间到低维空间的线性映射/矩阵
2.保留尽可能多的样本信息
3.压缩后的数据对分类、聚类尽量不产生影响,甚至有所提升
主成分 (PCs):将原始高维向量通过投影矩阵,投射到低维空间中的向量

代数定义

给定 n 个样本(每个样本维度为 p 维)
          
定义 z 1j 为样本 x j 在第一主成分 / 主方向 a 1 上的投影
其中:a1=(a11,a21...ap1)
xj=(x1j,x2j...xpj)
我们的目标是找到 a 1 , 使 z 1 的方差最大

PCA算法流程

  1. 数据预处理:对原始数据进行标准化处理,使得数据各维度具有相同的重要性。

  2. 计算协方差矩阵:计算数据的协方差矩阵,该矩阵反映了数据之间的线性相关性。协方差矩阵的对角线元素为各个特征的方差,非对角线元素为特征之间的协方差。

  3. 计算特征值和特征向量:对协方差矩阵进行特征值分解,得到特征值和特征向量。其中,特征向量表示的是数据在新的坐标系下的主要方向,而特征值则代表了数据在该方向上的方差大小。

  4. 排序和选择主成分:将特征值从大到小排序,选择前k个特征值对应的特征向量作为新的坐标系的主要方向。

  5. 构造新的特征空间:将原始数据投影到新的坐标系中,得到降维后的数据集。

第一步: 分别求 x y 的平均值。 然后对于所有的样本,都减去 对应的均值。这里x 的均值是1.81, y 的均值是 1.91
第二步 :求协方差矩阵。由于 样本只有两个维度,可根据协方差矩阵计算公式求得。
第三步 :分解求协方差的特征值和特征向量
第四步 :将特征值按照从大到小的顺序排序,选择其中最大的k 个。这里特征值只有两个,我们选择最大的那个,这里是1.28402771 。对应的特征向量是(-0.677873399, -0.735178656)T
第五步 :将样本点投影到选取的特征向量上。

代码实现

下面使用svm和pca实现,对人脸图片进行PCA降维,并用SVM进行分类。


# 导入相关模块
from __future__ import print_function
from time import time
import logging
import cv2
import matplotlib.pyplot as plt
from numpy import *
import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.metrics import ConfusionMatrixDisplay
from sklearn.decomposition import PCA
from sklearn.svm import SVC
import zipfile
import os
from sklearn.utils.fixes import loguniform
from sklearn.model_selection import RandomizedSearchCV

数据预处理

# 解压数据集,请学习zipfile的用法
import zipfile
extracting = zipfile.ZipFile('./data/data76601/crop_images.zip')
extracting.extractall('./data/crop_images')# 画图函数
def plot_gallery(images, titles, h, w, n_row=4, n_col=4):  # n_row=4, n_col=4表示一行有几张图,一列有几张图"""Helper function to plot a gallery of portraits"""plt.figure(figsize=(2.1 * n_col, 2.8 * n_row))  # 确定了图片的尺寸plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, wspace=.75, hspace=.35)for i in range(n_row * n_col):plt.subplot(n_row, n_col, i + 1)  # n_row行,n_col列,位置是第i+1个,从1开始 # cmap: 颜色图谱(colormap), 默认绘制为RGB(A)颜色空间plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)  # 画图plt.title(titles[i], size=12)plt.xticks(())plt.yticks(())#获得数据集中的七个人名和数字组成的字典+得到所有照片的地址
def get_name(file_dir):"""用来得到数据集中的七个人名和数字组成的字典+得到所有照片的二维列表地址:param file_dir:新数据的名字:return:返回一个字典+一个二维列表"""all_dirs = []all_path = []count = 0for root, dirs, files in os.walk(file_dir):  # 分别从文件地址中,读出根地址、子目录、文件名all_dirs.append(dirs)  # 子目录就是这个人的名字,所以要存下来temp = []if count == 0:count += 1continuefor file in files:temp.append(os.path.join(root, file))  # 这里每次循环存的就是一个人70张照片地址count += 1all_path.append(temp)  # 得到7*70的照片地址,二维的all_dirs = all_dirs[0]  # 得到一维的人脸照片名number = [i for i in range(7)]name_dict = dict(zip(number, all_dirs))  # 得到人名字典return name_dict, all_path  # 返回的分别是名字字典7、二维7*70图片地址# 获取名字字典+所有图片的二维地址
name_dict = {}
all_path = []
file_new_path = r'./data/crop_images'
name_dict, all_path = get_name(file_new_path)
print(name_dict)
print(np.shape(all_path))# 读取数据
all_data_set = []
all_data_label = []
def get_Image():for i in range(7):for j in range(50):images_path = all_path[i][j]img = cv2.imread(images_path)img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 改为灰度图,颜色空间转换函数h, w = img_gray.shapeimg_col = img_gray.reshape(h * w)all_data_set.append(img_col)  # 存图片all_data_label.append(i)  # label#返回图片大小return h, w
#获得图片大小
h, w = get_Image()#整理数据
# 将列表改成数组
X = array(all_data_set)
y = array(all_data_label)n_samples, n_features = X.shape
n_classes = len(unique(y))target_names = []
for i in range(7):names = name_dict[i]target_names.append(names)  # 用图片文件名中的人名print("n_samples: %d" % n_samples)  # 图片总量
print("n_features: %d" % n_features) # 每张图片内按尺寸定的数量,行列尺寸相乘
print("n_classes: %d" % n_classes)  # 标签总量

数据集划分

# 划分数据
#要求:1、3/4用于训练,1/4用于测试;2、random_state设为1,随机种子保证得到相同随机数,保证每次运行结果一致。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)

PCA提取特征(降维)


# 这个部分是提取特征脸的过程,本来想分开,但是为了保持整体性我又把他们放在一起了,我会尽量做注释n_components = 95  # 定义取的特征脸数量,经过测试:95准确率相对高
print("Extracting the top %d eigenfaces from %d faces" % (n_components, X_train.shape[0]))
t0 = time()
# 选择一种svd方式,whiten是一种数据预处理方式,会损失一些数据信息,但可获得更好的预测结果
pca = PCA(n_components=n_components, svd_solver='full', whiten=True).fit(X_train)  # 经过测试,full最好
print("done in %0.3fs" % (time() - t0))eigenfaces = pca.components_.reshape((n_components, h, w))  # 特征脸print("Projecting the input data on the eigenfaces orthonormal basis")t0 = time()
X_train_pca = pca.transform(X_train)  # 得到训练集投影系数
X_test_pca = pca.transform(X_test)  # 得到测试集投影系数
# 接下来我们就会使用投影系数来进行训练
print("done in %0.3fs" % (time() - t0))# 最后我们得到了特征脸,画个图看看把
# plot the gallery of the most significative eigenfaces画出最有意义的面孔
eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])]
plot_gallery(eigenfaces, eigenface_titles, h, w)plt.show()

SVM分类器

 这个部分就是进行训练了,采用的是SVM,最终得到不错的SVM分类器print("Fitting the classifier to the training set")  # 将分类器拟合到训练集
t0 = time()
'''C为惩罚因子,越大模型对训练数据拟合程度越高,gama是高斯核参数'''
param_grid = {'C': [5e2, 1e3, 5e3, 1e4, 5e4, 1e5],'gamma': [0.0001, 0.0005, 0.001, 0.002, 0.0009, 0.005, 0.01, 0.1], }# 我在这里要选取一系列可能是最优的超参数C和gamma,然后在下面中找到最优的
# 分类器是SVC组成的这个高斯核(RBF)+balanced防止过拟合
clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)  # 超参数自动搜索模块,按你的要求,在你给定的超参数范围内选一个最合适的
# 表示调整各类别权重,权重与该类中样本数成反比,防止模型过于拟合某个样本数量过大的类clf = clf.fit(X_train_pca, y_train)
print("done in %0.3fs" % (time() - t0))
print("Best estimator found by grid search:")  # 用网格搜索找到最佳估计量
print(clf.best_estimator_)  # 让我们看一下都有哪些分类器弄好了的超参数

用训练好的SVM分类器预测

# 下面用训练好的分类器进行预测print("Predicting people's names on the test set")  # 在测试集中预测人们的名字
t0 = time()
y_pred = clf.predict(X_test_pca)  # 进行预测
#y_pred = clf.predict(X_test)  # 进行预测print("done in %0.3fs" % (time() - t0))print(classification_report(y_test, y_pred, target_names=target_names))  # 查准率/查全率/F1值/测试样本数
#print(confusion_matrix(y_test, y_pred, labels=range(n_classes)))# plot the result of the prediction on a portion of the test set
# 在测试集的一部分上绘制预测结果def title(y_pred, y_test, target_names, i):pred_name = target_names[y_pred[i] - 1]true_name = target_names[y_test[i] - 1]return ' predicted: %s\n true:      %s' % (pred_name, true_name)# 画图展示
prediction_titles = [title(y_pred, y_test, target_names, i) for i in range(y_pred.shape[0])]
plot_gallery(X_test, prediction_titles, h, w)plt.show()

总结

主成分分析(Principal Component Analysis,PCA)是一种常用的降维方法和数据分析技术。它可以将高维数据映射到低维空间,并保留最重要的特征信息。

PCA的核心思想是通过线性变换将原始数据映射到新的坐标系下,使得在新的坐标系中,数据的方差最大化。具体步骤如下:

  1. 标准化数据:将原始数据进行标准化处理,使得所有特征具有相同的尺度,避免某些特征对结果的影响过大。

  2. 计算协方差矩阵:计算标准化后的数据的协方差矩阵。协方差矩阵描述了数据之间的相关性。

  3. 计算特征值和特征向量:对协方差矩阵进行特征值分解,得到特征值和对应的特征向量。特征值表示了新坐标系下的方差,特征向量则定义了新坐标系的方向。

  4. 选择主成分:根据特征值的大小,选择最大的K个特征值对应的特征向量作为主成分。

  5. 数据映射:将原始数据投影到选择的主成分上,得到降维后的数据。

PCA的应用包括数据降维、数据可视化、特征提取等。通过降低数据的维度,PCA可以减少计算复杂度、消除冗余信息、去除噪声、提高模型性能等。同时,PCA还可以帮助我们理解数据之间的关系和结构,发现数据中的潜在模式和规律。

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

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

相关文章

No Magic—复杂机电产品系统架构开发套件

产品概述 CATIA Magic,原名MagicDraw,俗称No Magic,被达索收购后融入3DExperience产品协同研发管理平台中,形成更具协同体验的系统工程解决方案。该软件提供对SysML/UML/UAF语言的完整支持,提供独有的MagicGrid方法论&…

易点易动固定资产管理系统集成企业微信,帮助企业全生命周期管理固定资产

在现代企业中,固定资产管理是一项至关重要的任务。固定资产的高效管理可以提高企业的运营效率、降低成本,并确保资产的安全和稳定。然而,传统的固定资产管理方法往往复杂繁琐,容易出现信息不准确、流程不畅和数据不一致的问题。为…

设计模式:简单工厂模式

这里写目录标题 工厂模式简介核心角色:实现 工厂模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 工厂模式提供了一种将对象的实例化过程封…

d3dcompiler_43.dll丢失怎么修复?怎么解决

在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是“找不到d3dcompiler_43.dll文件”。那么,d3dcompiler_43.dll是什么文件?它的作用是什么?如果缺失了该如何修复呢?本文将详细介绍d3dcompiler_…

RK3568驱动指南|第九篇 设备模型-第102章 platform总线注册流程实例分析实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

C# halcon 工业产品尺寸测量

产品检测 这段代码是一个基于HalconDotNet的Windows窗体应用程序,主要用于图像处理和测量。以下是对代码的一些总结: 1. **图像显示与加载:** - 使用HalconDotNet库进行图像处理。 - 通过OpenFileDialog实现图像文件的选择和加载。 …

纯css实现三等分饼图

实现原理,先绘制一个圆,然后把圆分成两份,在绘制一个菱形,最下面的角是120,这样就可以实现三等分啦 关键代码是一个css很少见的属性clip-path clip-path: polygon(24rem 36rem, 48rem 18rem, 24rem 0, 0 18rem); &…

使用Python做个可视化的“剪刀石头布”小游戏

目录 一、引言 二、环境准备与基础知识 三、游戏界面制作 四、游戏逻辑实现 五、代码示例 六、游戏测试与优化 七、扩展与改进 八、总结 一、引言 “剪刀石头布”是一种古老的手势游戏,它简单易懂,趣味性强,适合各个年龄段的人参与。…

Reids在Win下无法远程访问

1.将redis在windows上启动主要做了以下配置 1.1.在redis.windows.conf中修改一下 原:bind 127.0.0.1 改:# bind 127.0.0.1 bind 0.0.0.0 原:protected-mode yes 改:protected-mode no去掉了127.0.0.1,加入0.0.0.0后&…

CC++刷题练习

蓝桥杯[错误的票据] 题目: 某涉密单位下发了某种票据,并要在年终全部收回每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某…

基于ssm+vue搭建的新闻网站论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

百度Apollo:激光雷达检测技术深度解析

🎬 鸽芷咕:个人主页 🔥 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 粉丝福利活动 ✅参与方式:通过连接报名观看课程,即可免费获取精美周边 ⛳️活动链接&#xf…

【Docker】docker部署conda并激活环境

原文作者:我辈李想 版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、新建dockerfile文件二、使用build创建镜像1.报错:Your shell has not been properly configured to use conda activate.…

快速学习SpringBoot

SpringBoot springboot传统方式构建spring应用程序使用springboot子项目构建起步依赖自动配置其它特性 SpringBoot项目部署Spring项目部署属性配置方式命令行参数方式配置环境变量方式外部配置文件方式 多环境开发-Pofiles多环境开发分组 springboot 传统方式构建spring应用程…

【数据结构】数组实现队列(详细版)

目录 队列的定义 普通顺序队列的劣势——与链队列相比 顺序队列实现方法: 一、动态增长队列 1、初始化队列 2、元素入队 3、判断队列是否为空 4、元素出队 5、获取队首元素 6、获取队尾元素 7、获取队列元素个数 8、销毁队列 总结: 动态增长队列…

whistle+SwitchyOmega前端api代理调试

1、whistle介绍 whistle官网whistle githubwhistle主要用于查看、修改HTTP、HTTPS、Websocket的请求、响应,也可以作为HTTP代理服务器,功能很强大 2、安装教程 官方安装文档 // 全局安装whistle npm install -g whistle// 安装whistle的inspect插件&a…

2024.1.3 关于 Redis 渐进式遍历 和 数据库管理命令

目录 引言 渐进式遍历 SCAN 命令 数据库管理命令 切换数据库 获取数据库 key 个数 删除数据库所有 key 同步删除 SYNC 异步删除 ASYNC 阅读下述文章之前建议点击下方链接熟悉 keys 命令的用法和特点 Redis 全局通用命令 ​​​渐进式遍历 keys * 命令一次性将 Redi…

安全狗入选“2023年福建省信息技术应用创新解决方案”名单

近日,福建省数字福建建设领导小组办公室公布了2023年福建省信息技术应用创新解决方案入选项目评选结果。 作为国内云原生安全领导厂商,安全狗凭借综合且具备突出创新水平的方案入选。 厦门服云信息科技有限公司(品牌名:安全狗&…

栈和队列oj题——232. 用栈实现队列

. 个人主页:晓风飞 专栏:LeetCode刷题|数据结构|Linux|C语言 路漫漫其修远兮,吾将上下而求索 文章目录 题目要求:实现 MyStack 类:注意:示例:解释:提示: 解题核心概念数据…

LeetCode刷题---矩阵置零

解题思路: 本题要求原地置换元素 对矩阵进行第一轮遍历,使用第一行第一列来充当该行该列是否要置换为0的标记位,如果第一行或第一列本身就含有零元素,我们使用colZero和rowZero变量来对其标记。如果第i行第j列的那个元素为0&#…