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

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

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

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

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

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

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

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

一、主成分分析(PCA)

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

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

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

具体原理可以参考文章:

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

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

下面我们将以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

从数据组成可以看出,该数据集共有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分别表示子图之间左右、上下的间距。

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

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

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

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人脸图像如图所示:

接下来使用主成分分析法找到数据集中的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表示是否对数据集进行白化处理。

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

可以发现得到的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得到的特征脸如图所示:

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

二、核主成分分析(KPCA)

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

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

具体原理可以参考文章:

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

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

下面使用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得到的特征脸如图所示:

与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维降维​:

图片可视化​:

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下的空间结构如图所示:

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

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

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

三、Isomap流形学习

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

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

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

具体原理可以参考文章:

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

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

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()

从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]来计算流形降维结果如下:

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

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

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

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

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

你确定不关注我一波?!

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

  1. 对pca降维后的手写体数字图片数据分类_【AI白身境】深度学习中的数据可视化...

    今天是新专栏<AI白身境>的第八篇,所谓白身,就是什么都不会,还没有进入角色. 上一节我们已经讲述了如何用爬虫爬取数据,那爬取完数据之后就应该是进行处理了,一个很常用的手段是数据可视化. ...

  2. 对pca降维后的手写体数字图片数据分类_知识干货-机器学习-TSNE数据降维

    1.TSNE的基本概念 2.例1 鸢尾花数据集降维 3.例2 MINISET数据集降维 1.TSNE的基本概念 t-SNE(t-distributed stochastic neighbor embe ...

  3. 对pca降维后的手写体数字图片数据分类_python机器学习API介绍13: 数据降维及主成分分析...

    数据降维概述:数据降维是机器学习领域中重要的内容,所谓的降维就是采用某种映射方法,将高维空间中的数据点映射到低维的空间中.其本质是学习一个映射函数f: x->y.其中x是原始数据点的表述,目前多 ...

  4. 如何从TensorFlow的mnist数据集导出手写体数字图片

    在TensorFlow的官方入门课程中,多次用到mnist数据集. mnist数据集是一个数字手写体图片库,但它的存储格式并非常见的图片格式,所有的图片都集中保存在四个扩展名为idx3-ubyte的二 ...

  5. GAN网络生成手写体数字图片

    Keras真香,以前都是用tensorflow来写神经网络,自从用了keras,发现这个Keras也蛮方便的. 目前感觉keras的优点就是方便搭建基于标准网络组件的神经网络,这里的网络组件包括全连接 ...

  6. Python实现手写体数字图片识别+GUI界面+画板数字识别

    __pycache__文件夹是Python自动生成的,详细了解https://blog.csdn.net/yitiaodashu/article/details/79023987 其他各个文件在之后部 ...

  7. Python+TensorFlow+PyQt实现手写体数字图片识别+GUI界面+画板数字识别

    __pycache__文件夹是Python自动生成的,详细了解https://blog.csdn.net/yitiaodashu/article/details/79023987 其他各个文件在之后部 ...

  8. 手写体数字图像识别图像_手写识别调整笔画大小而不是图像

    手写体数字图像识别图像 A straightforward algorithm to dealing with handwritten symbol recognition problems in M ...

  9. 降维后的高维特征的参数_高维超参数调整简介

    降维后的高维特征的参数 by Thalles Silva 由Thalles Silva 高维超参数调整简介 (An introduction to high-dimensional hyper-par ...

最新文章

  1. poj3007(set的应用)
  2. Wasserstein距离在生成模型中的应用
  3. python扩展库不是用于科学计算的有_有哪些科学计算的开源库
  4. mongoose 入门以及 mongoose 实现数据 的增、删、改、查
  5. spring的bean不能注入的几种原因及分析
  6. java 批量插入clob_SpringBoot系列(16)线程池Executors并发编程之批量查询-插入数据
  7. 《深入理解 Spring Cloud 与微服务构建》第五章 Kubernetes
  8. 基于Go语言实现高并发推荐系统架构设计
  9. Android RecyclerView布局动画
  10. 安装配置管理 之 JRE 安装和配置,以适合JAVA程序运行所具备的环境
  11. flask + websocket实现简单的单聊和群聊
  12. java逆向框架_JOOQ框架学习(1):逆向编译生成代码
  13. 【免积分下载】吴恩达 机器学习笔记PDF版v5.5.pdf
  14. IT负载率与数据中心规模——孙长青
  15. 可视化优化:百度地图内网访问(通过nginx代理)
  16. python怎么绘制饼图_Matplotlib绘制饼图
  17. 常见实用网站集合(行业研究/政策研究/学习/办公/设计/编程)
  18. Retrofit2网络框架的使用
  19. 中兴让我们感受到“缺芯”之痛~活在当下!
  20. 「高可用架构设计」的入门秘籍

热门文章

  1. 栈与队列之用java实现队列
  2. Sql 存储过程加游标结合的使用
  3. gearman mysql编译_gearman初探(一、编译和安装)
  4. 程序员面试必备的20条Python经典面试题
  5. 通过简单的Word Count讲解MapReduce原理以及Java实现
  6. java 继承 子类 实例化_关于Java继承中父类和子类构造函数的问题
  7. abp框架java,【Net】ABP框架学习之正面硬钢
  8. 32位hex转浮点 python_python——int()、hex()、oct()、bin()、float()数值类型转换函数
  9. 传递函数_使用python计算麦克风阵列信号的传递函数
  10. html插入图片和文字,HTML第三课文字图片插入