对pca降维后的手写体数字图片数据分类_机器学习:数据的准备和探索——特征提取和降维...

af0fc3998159506f05d2575a753bdf05.png

在数据的预处理阶段,特征提取和数据降维是提升模型表示能力的一种重要手段。

特征提取主要是从数据中找到有用的特征,用于提升模型的表示能力,而数据降维主要是在不减少模型准确率的情况下减少数据的特征数量。

比如,我们要搭建一个预测身高的模型,现有的数据包括身高、性别、年龄、饭量以及是否喜欢运动,这么多的变量如何确定模型呢?

这就要用到数据降维。简单说就是把性别、年龄、饭量、是否喜欢运动组成的四维变量转换为一维,再寻找与身高之间的关系就方便多了。

那四维变量如何变为一维呢?

从原理上来说,将不同变量按照不同权重转化到一维空间,再将各个变量叠加就组成一个新的一维变量。

从方法上来说,下面将主要介绍的3种方法——主成分分析、核主成分分析和ISomap流行学习都能实现数据降维。

其中,主成分分析(PCA)和核主成分分析(KPCA)将应用于人脸数据集特征提取,ISomap流形学习将应用在手写数字数据集上。

一、主成分分析(PCA)

主成分分析是一种分析、简化数据集、提取主要成分的技术。

在实际生活中,特征之间可能存在一定的相关性,比如上文中的年龄和饭量,这种情况下就存在重叠的信息。

主成分分析则可以通过少数的特征来保留原始数据集中的大部分信息,从而减少数据维度。

具体原理可以参考文章:

主成分分析(PCA)原理详解_李春春的专栏-CSDN博客_主成分分析​blog.csdn.net
000c67709a26aaa81e1149b1fa742feb.png

当然,主成分分析也有缺点,其分析效果主要依赖于给定的数据集,所以数据集的准确性对分析结果影响很大。

下面我们将以AR人脸数据集(没有数据集的小伙伴可以私信我或在评论区留言)为例,使用PCA技术找到数据集中的特征脸数据。

AR人脸数据集有100类人脸,其中男、女各50类,每类数据有26幅图像,每幅图像大小为165*120。第一步要做的就是载入相关方法和数据:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = "retina"
from matplotlib.font_manager import FontProperties
fonts = FontProperties(fname="C:WindowsFontsSimHei.ttf", size=14)
from sklearn.decomposition import PCA
import cv2
from sklearn.preprocessing import StandardScalerface = []
label = []
for i in ["m","w"]:for m in range(1,51):for n in range(1,27):path='D:/AR/'+i+"-"+str(m).rjust(3,"0")+"-"+str(n).rjust(2,"0")+'.pgm' #每个人文件位置不同img=cv2.imread(path,cv2.IMREAD_GRAYSCALE)h,w=img.shapeimg_col=img.reshape(h*w)face.append(img_col)face_trans = []
face = np.array(face).T
face.shape

52012118fb3fb04908649045e753552b.png

从数据组成可以看出,该数据集共有2600个人脸图像,每个图像的特征维度为19800维。

上述代码还使用了OpenCV(需要用pip安装)导入图片,函数cv2.imread(filepath,flags)可以读入一副图片,其中filepath为要读入图片的完整路径,flags为读入图片的标志,cv2.IMREAD_COLOR为默认参数,指读入一副彩色图片但忽略alpha通道,cv2.IMREAD_GRAYSCALE指读入灰度图片。

.T”表示将数组反转,如果不进行反转将会得到(2600, 19800)的数组,在做特征提取时将会对单张图片进行降维(也就是对19800进行降维),并不是我们想要的结果。

np.array(face).T也可以用下面的代码替代,结果是一样的:

for x in range(len(face[0])):temp = []for y in range(len(face)):temp.append(face[y][x])face_trans.append(temp)
face = np.array(face_trans)

完成数据载入后就能查看导入的图像了:

height = 165
width = 120
plt.figure(figsize=(10,6))
for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face[:,ii*26].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off")
plt.subplots_adjust(wspace=0.1,hspace=0.1)
plt.show() 

height和width是图片的长和宽,plt.imshow()函数可以实现热图绘制,参数plt.cm.gray表示返回灰度色图,interpolation='nearest'指线性图,一般由RGB组成的图都设置为线性,vmin和vmax参数可以控制非线性缩放。

plt.subplots_adjust()用来控制子图布局,wspace、hspace分别表示子图之间左右、上下的间距。

11b7162d535172757e9ee2119be1c8a4.png

下面对每张图像进行标准化处理:

sc = StandardScaler()
face = sc.fit_transform(face)
face

7c2ed367ab1a34953d4dff6bc689bc3a.png

标准化后对数据集的几张图像进行可视化并查看数据集内容,相比标准化前颜色稍浅

height = 165
width = 120
plt.figure(figsize=(10,6))
for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face[:,ii*26].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off")
plt.subplots_adjust(wspace=0.1,hspace=0.1)
plt.show()

AR人脸图像如图所示:

4c3a88a46a610edf22cacb40f0341431.png

接下来使用主成分分析法找到数据集中的100张特征脸数据并计算数据集解释方差百分比:

pca = PCA(n_components=100,svd_solver="randomized",whiten=True)
face_pca = pca.fit_transform(face)
np.sum(pca.explained_variance_ratio_)

PCA函数中的n_components参数指需要保持的主成分个数,svd_solver指定求解时使用的算法,whiten表示是否对数据集进行白化处理。

运行后可以看到如下结果:

72f02827f09a4ae45fb863194f16dfd8.png

可以发现得到的100张特征人脸数据达到了93.73%的解释方差,保留了数据集中的大部分信息。

再次查看降维后的特征脸图像:

height = 165
width = 120
plt.figure(figsize=(10,6))
for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face_pca[:,ii].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off")
plt.subplots_adjust(wspace=0.1,hspace=0.1)
plt.show()

PCA得到的特征脸如图所示:

ccbd36b4aefa203a50891177b1b57752.png

可以看出,大部分特征脸都是带有眼镜的,说明原始数据中含有大量的带有眼镜的人脸数据。

二、核主成分分析(KPCA)

PCA是一种线性的数据降维技术,而核主成分分析(KPCA)则可以得到数据的非线性表示。

简单理解就是,KPCA是PCA的升级版,通过只保留前面的主要特征来达到对数据进行降维的目的。

具体原理可以参考文章:

解释一下核主成分分析(Kernel Principal Component Analysis, KPCA)的公式推导过程~​blog.csdn.net
bdf7ad0d52fb11ac83403a76069d64da.png

核主成分分析的“核”,事实上是加入了核函数,用核函数替代原始数据让分析更加准确。

下面使用KernelPCA函数对AR数据集提取特征脸数据:

from sklearn.decomposition import KernelPCA
kpca = KernelPCA(n_components=100,kernel="rbf")
face_kpca = kpca.fit_transform(face)height = 165
width = 120
plt.figure(figsize=(10,6))
for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face_kpca[:,ii].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off")
plt.subplots_adjust(wspace=0.1,hspace=0.1)
plt.show()

注意:KernelPCA函数对内存要求较高,很可能出现MemoryError,建议运行内存在8G及以上。

KernelPCA函数中的n_components参数与PCA相同,表示需要保持的主成分个数。

Kernel表示核方法,可以为“linear”“poly”“rbf”“sigmoid”“cosine”“precomputed”。

KernelPCA得到的特征脸如图所示:

f51208da2548ffbfbfd54139a6e8b47b.png

与PCA得到的特征脸相比,核主成分分析的轮廓更加鲜明

从上面的示例可以看出,无论是PCA还是KPCA都是通过对数据样本量进行降维得到特征脸,降维还可以作用于数据的特征维度。

如果再对降维后的数据进行数据可视化,能够更方便地分析数据之间的结构和关系。

下面使用核主成分分析对人脸数据集进行特征提取,然后可视化,并分析原始图像之间的关系:

faceT = face.T
kpca_f = KernelPCA(n_components=100,kernel="rbf")
kpca_f.fit(faceT)
face_kpcaf = kpca_f.transform(faceT)
face_kpcaf.shape

反转后将19800维降维​:

2860b2ae561fe6c69c88e49b19f943bf.png

图片可视化​:

from matplotlib import offsetbox
plt.figure(figsize=(16,12))
ax = plt.subplot(111)
x = face_kpcaf[:,0]
y = face_kpcaf[:,1]
images = []
for i in range(len(x)):x0,y0 = x[i],y[i]img = np.reshape(faceT[i,:],(165,120))image = offsetbox.OffsetImage(img,zoom=0.4)ab = offsetbox.AnnotationBbox(image,(x0,y0),xycoords='data',frameon=False)images.append(ax.add_artist(ab))
ax.update_datalim(np.column_stack([x,y]))
ax.autoscale()
plt.xlabel("KernelPCA主成分1",FontProperties=fonts)
plt.ylabel("KernelPCA主成分2",FontProperties=fonts)
plt.show()

代码中使用offsetbox包绘制图片,offsetbox.OffsetImage()为获取图片方法,参数zoom表示缩放比例,offsetbox.AnnotationBbox()为设定图片坐标方法,参数frameon表示是否加外框。

KPCA下的空间结构如图所示:

e125b586efdcece87c44785a39176e59.png

上面的程序中,相应坐标的位置就是核主成分的前两个主成分,分别为X轴和Y轴,然后将2600张图片绘制到图像上。

从图上可以发现,原始数据图像在核主成分空间中的分布特点是:在X轴从左到右分布,依次为戴墨镜图像、干净的人脸图像、戴围巾图像

在Y轴从上到下分布,也是呈区域性分布。

三、Isomap流形学习

Isomap流形学习是借鉴了拓扑流形概念的一种降维方法,可以用于数据降维。

流形并不是一个“形状”,而是一个“空间”。

其原理可以简单理解为通过近邻的距离来计算高维空间中样本点的距离。

具体原理可以参考文章:

流形学习之等距特征映射(Isomap)_长夜悠悠的博客-CSDN博客​blog.csdn.net
36c9c19cb98a4632ef31f8451ffbd84f.png

下面用手写字体数据集进行演示:

from sklearn.manifold import Isomap
from sklearn.datasets import load_digits
X,Y = load_digits(return_X_y=True)
X = X[0:1000,:]
Y = Y[0:1000]

查看手写字体数据集​:

size = 8
plt.figure(figsize=(10,4))
for ii in np.arange(10):plt.subplot(2,5,ii+1)image = X[ii,:].reshape(size,size)plt.imshow(image,interpolation='nearest')plt.axis("off")
plt.subplots_adjust(wspace=0.1,hspace=0.1)
plt.show()

6d845d0be4668243d719ba538c458fe1.png

从sklearn.datasets库中使用load_digits函数可以导入手写字体数据集,并使用sklearn库中的manifold模块的Isomap函数对手写字体数据集进行降维学习:

n_neighbors = [5,10,15,20]
shape = ["s","p","*","h","+","x","D","o","v",">"]
for n in n_neighbors:isomap = Isomap(n_neighbors=n,n_components=2)im_iso = isomap.fit_transform(X)plt.figure(figsize=(10,7))for ii in range(len(np.unique(Y))):scatter = im_iso[Y==ii,:]plt.scatter(scatter[:,0],scatter[:,1],color=plt.cm.Set1(ii/10.),marker=shape[ii],label=str(ii))plt.legend()plt.title("Isnmap根据"+str(n)+"个近邻得到的降维",FontProperties=fonts)plt.legend()plt.show()

分别根据不同的近邻数目[5,10,15,20]来计算流形降维结果如下:

5164687cfafde0f5a9d7c367c991a486.png

1312e2d21dd9a2f793fb033dc08edf7d.png

c011707c36b6db31e17bc7090964993e.png

8034b6b41876926e95e253bb7f143d60.png

从图中可以看出,近邻数量越多,降维后数据之间就越紧密,就越不能很好地区分数据。

因此,近邻的个数对流形降维得到的结果影响很大,在建立分类模型前需要留意近邻数量对最终结果的影响。

数据提取和降维是数据分析中非常重要的部分,随着大数据到来,数据的海量增加使得高维数据在今后越来越常见,如何提取和降维就显得格外重要。

关于特征提取和降维的内容就这么多,理解起来有一定困难,特别是PCA方法的理解,在今后的学习中也会用到,需要牢牢掌握。

数据预处理到此就结束了,还想增长技能的小伙伴可以再查查相关资料。下一次我们将开始一个新的模块——模型训练和评估

你确定不关注我一波?!

c14b304141718ff1824e5ecbeab376d8.png

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

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

相关文章

程序员应对浏览器同源策略的姿势

同源策略浏览器最基本的安全规范——同源策略(Same-Origin Policy)。所谓同源是指域名、协议、端口相同。不同源的浏览器脚本(javascript、ActionScript、canvas)在没明确授权的情况下,不能读写对方的资源。同源策略规定了浏览器脚本互操作web数据的基本原则&#x…

word List38

word List38 如果存在什么问题,欢迎批评指正!谢谢!

.net core 整洁架构入门

Clean Architecture with .NET Core: Getting Started# 使用.NET Core整洁架构(Clean Architecture):入门Over the past two years, I’ve travelled the world teaching programmers how to build enterprise applications using Clean Architecture wi…

算法---背包问题

算法—背包问题 参考&#xff1a;趣学算法 代码&#xff1a; typedef struct three {float w;float v;float p; }three; #define elemType three int quickSort1(elemType a[], int l, int h) {//快速排序int i l, j h;elemType p1 a[i];while (i < j) {while (i<j…

允许服务与桌面交互_在后全面屏时代 手机需要什么样的人机交互?

在智能手机进入全面屏时代之后&#xff0c;智能手机的屏占比已经越来越高&#xff0c;智能手机上的各种实体按键也已经越来越少&#xff0c;手机屏幕已经在客观上成为了用户进行交互操作的主要部件&#xff0c;而触控也全面取代了按键成为手机交互中最主要的方式。全面屏手机正…

C++实现链式存储线索二叉树

一颗线索二叉树&#xff1a; 根据下图进行节点的创建&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; typedef char ElemType;typedef struct BiThrNode {ElemType data;int ltag,rtag;struct BiThrNode *lchild,*rchild; }BiThrNode,*Bi…

windows 仍在设置此设备的类配置。 (代码 56)_谷歌发布Flutter Alpha:支持Windows

老孟导读&#xff1a;Windows来了&#xff0c;Mac、Linux、Web还远吗&#xff1f; 本文翻译自https://medium.com/flutter/announcing-flutter-windows-alpha-33982cd0f433 我们的使命是为开发人员提供一个开源&#xff0c;高生产率的框架&#xff0c;以便在任何平台上构建漂亮…

word List39

word List39 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

不同路径 II-dp

题目背景 一个机器人位于一个 n x m 网格的左上角 机器人每次只能向下或者向右移动一步。它试图达到网格的右下角 题目描述 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径&#xff1f; 网格中的障碍物和空位置分别用 1 和 0 来表示。 输入格式 第一行两…

.NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(下)

05 | 依赖注入&#xff1a;良好架构的起点注册完毕之后&#xff0c;想替换某些组件的某些部分时&#xff0c;可以使用 Replace 和 RemoveAllservices.AddSingleton<IOrderService>(new OrderService()); services.Replace(ServiceDescriptor.Singleton<IOrderService,…

python正态分布函数_python3-正态分布

loc 平均值 scale (scale) 标准差 pdf(x, loc0, scale1) 正态分布&#xff08;Normal distribution&#xff09;&#xff0c;也称“常态分布”&#xff0c;又名高斯分布&#xff08;Gaussian distribution&#xff09;&#xff0c;最早由A.棣莫弗在求二项分布的渐近公式中得到。…

word List40

word List40 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

int 范围_Java学习之随机生成5个(范围1——33)不同数字的思考

昨天做了一道福彩双色球的简单程序题&#xff0c;一开始不懂双色球的玩法&#xff0c;楼主我从来不买彩票的&#xff0c;( ╯□╰ )。所以随机生成某个范围的5个数字&#xff08;数字可以重复&#xff09;&#xff0c;那么很简单&#xff0c;一个循环就可以搞定了&#xff0c;但…

高级数据结构---优先队列

高级数据结构—优先队列 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include <stdio.h> #include <stdlib.h> int r[] { -1,1,4,590,4,2,8,7,5,89,67,5,2,1,67,86,54 };//存储要排序的数,第一个元素不存储元素赋值为-1 int length sizeof(r) / size…

[蓝桥杯2017初赛]贪吃蛇长度-模拟(水题)

题目描述 小明在爷爷的私人收藏馆里找到一台老式电脑。居然没有图形界面&#xff0c;只能用控制台编程。 经过小明的一阵摸索&#xff0c;神奇地设计出了控制台上的贪食蛇游戏。 如下图&#xff0c;是游戏时画面截图。 其中&#xff0c;H表示蛇头&#xff0c;T表示蛇尾。#表示…

蓝屏(BSOD)转储设置,看本文就够了!

前言 我们在内核转储&#xff0c;开抓啦&#xff01;这篇文章里介绍了一个关键的系统设置。设置好后可以让系统在蓝屏&#xff08;Blue Screen of Death&#xff0c;简称 BSOD&#xff09;的时候自动保存转储文件。当时只是简单的介绍了设置步骤&#xff0c;本文力求详细的介绍…

算法---字符串顺序平移

算法—字符串顺序平移 原理&#xff1a;矩阵的转置思想 代码&#xff1a; #include <stdio.h> #include <stdlib.h> void swap(char *a,int i, int j) {//交换二个变量的值char temp a[i];a[i] a[j];a[j] temp; } void invert(char *a,int s, int e) {//对称…

delphi中的函数传参如何传枚举参数_Python基础笔记Day05函数

Python函数 function函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段。函数能提高应用的模块性&#xff0c;和代码的重复利用率。Python提供了许多内建函数&#xff0c;比如print()。但你也可以自己创建函数&#xff0c;这被…

[蓝桥杯2018初赛]日志统计-双指针

代码如下&#xff1a; #include <iostream> #include <algorithm> using namespace std; typedef pair<int, int>PII; #define x first #define y second const int N 100010; bool st[N]; int n, d, k; PII a[N]; int cnt[N];int main() {cin >> n …

不要错过这轮疫情的“洗牌”机会

大家好&#xff0c;我是Z哥。今天和大家随便聊聊天。这次的疫情对我们所有人影响都很大&#xff0c;除了让你心怀忐忑的过了个春节之外&#xff0c;呆在家的时间对很多人来说也是格外的长。这样的突发事件&#xff0c;除了能看出不同公司之间应对突发状况的能力差异之外&#x…