目录
降维是通过单幅图像数据的高维化,对单幅图像转化为高维空间中的数据集合进行的一种操作。机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x->y,其中x是原始数据点的表达,目前最多使用向量表达形式。 y是数据点映射后的低维向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。
本项目将依托于MNIST数据集,手把手实现图像数据集降维。
MNIST数据集来自美国国家标准与技术研究所,是入门级的计算机视觉数据集。它是由6万张训练图片和1万张测试图片构成的,这些图片是手写的从0到9的数字,50%采集美国中学生,50%来自人口普查局(the Census Bureau)的工作人员。这些数字图片进行过预处理和格式化,均为黑白色构成,做了大小调整(28×28像素)并居中处理。MNIST数据集效果如下图所示:
1、获取数据集
在本案例中,选择直接从sklearn.datasets
模块中通过load_digits
导入手写数字图片数据集,该数据集是UCI datasets的Optical Recognition of Handwritten Digits Data Set中的测试集,并且只是MNIST的很小的子集,一共有1797张分辨率为8××8的手写数字图片。同时,该图片有从0到9共十类数字。
先导入load_digits
模块及本案例所需的相关的包,实现代码如下所示:
-
from time import time # 用于计算运行时间
-
import matplotlib.pyplot as plt
-
import numpy as np
-
from matplotlib import offsetbox # 定义图形box的格式
-
from sklearn import (manifold, datasets, decomposition, ensemble,
-
discriminant_analysis, random_projection)
load_digits
中有n_class
参数,可以指定选择提取多少类的图片(从数字0开始),缺省值为10
;还有一个return_X_y
参数(sklearn 0.18版本的新参数),若该参数值为True
,则返回图片数据data
和标签target
,默认为False
。return_X_y
为False
的情况下,将会返回一个Bunch
对象,该对象是一个类似字典的对象,其中包括了数据data
、images
和数据集的完整描述信息DESCR
。
下面就这两种读取方式分别展示:
方法一:返回Bunch对象,实现代码如下所示:
-
digits = datasets.load_digits(n_class=6)
-
print(digits)
-
# 获取bunch中的data,target
-
print(digits.data)
-
print(digits.target)
输出结果如下所示:
-
[[ 0. 0. 5. ..., 0. 0. 0.]
-
[ 0. 0. 0. ..., 10. 0. 0.]
-
[ 0. 0. 0. ..., 16. 9. 0.]
-
...,
-
[ 0. 0. 0. ..., 9. 0. 0.]
-
[ 0. 0. 0. ..., 4. 0. 0.]
-
[ 0. 0. 6. ..., 6. 0. 0.]]
-
[0 1 2 ..., 4 4 0]
方法二:只返回data和target,实现代码如下所示:
-
data = datasets.load_digits(n_class=6)
-
print(data)
输出结果如下所示:
-
{'images': array([[[ 0., 0., 5., ..., 1., 0., 0.],
-
[ 0., 0., 13., ..., 15., 5., 0.],
-
[ 0., 3., 15., ..., 11., 8., 0.],
-
...,
-
[ 0., 4., 11., ..., 12., 7., 0.],
-
[ 0., 2., 14., ..., 12., 0., 0.],
-
[ 0., 0., 6., ..., 0., 0., 0.]],
-
[[ 0., 0., 0., ..., 5., 0., 0.],
-
[ 0., 0., 0., ..., 9., 0., 0.],
-
[ 0., 0., 3., ..., 6., 0., 0.],
-
...,
-
[ 0., 0., 1., ..., 6., 0., 0.],
-
[ 0., 0., 1., ..., 6., 0., 0.],
-
[ 0., 0., 0., ..., 10., 0., 0.]],
-
[[ 0., 0., 0., ..., 12., 0., 0.],
-
[ 0., 0., 3., ..., 14., 0., 0.],
-
[ 0., 0., 8., ..., 16., 0., 0.],
-
...,
-
[ 0., 9., 16., ..., 0., 0., 0.],
-
[ 0., 3., 13., ..., 11., 5., 0.],
-
[ 0., 0., 0., ..., 16., 9., 0.]],
-
...,
-
[[ 0., 0., 0., ..., 6., 0., 0.],
-
[ 0., 0., 0., ..., 2., 0., 0.],
-
[ 0., 0., 8., ..., 1., 2., 0.],
-
...,
-
[ 0., 12., 16., ..., 16., 1., 0.],
-
[ 0., 1., 7., ..., 13., 0., 0.],
-
[ 0., 0., 0., ..., 9., 0., 0.]],
-
[[ 0., 0., 0., ..., 4., 0., 0.],
-
[ 0., 0., 4., ..., 0., 0., 0.],
-
[ 0., 0., 12., ..., 4., 3., 0.],
-
...,
-
[ 0., 12., 16., ..., 13., 0., 0.],
-
[ 0., 0., 4., ..., 8., 0., 0.],
-
[ 0., 0., 0., ..., 4., 0., 0.]],
-
[[ 0., 0., 6., ..., 11., 1., 0.],
-
[ 0., 0., 16., ..., 16., 1., 0.],
-
[ 0., 3., 16., ..., 13., 6., 0.],
-
...,
-
[ 0., 5., 16., ..., 16., 5., 0.],
-
[ 0., 1., 15., ..., 16., 1., 0.],
-
[ 0., 0., 6., ..., 6., 0., 0.]]]), 'data': array
-
([[ 0., 0., 5., ..., 0., 0., 0.],
-
[ 0., 0., 0., ..., 10., 0., 0.],
-
[ 0., 0., 0., ..., 16., 9., 0.],
-
...,
-
[ 0., 0., 0., ..., 9., 0., 0.],
-
[ 0., 0., 0., ..., 4., 0., 0.],
-
[ 0., 0., 6., ..., 6., 0., 0.]]), 'target_names':
-
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), 'DESCR': "Optical Recognition
-
of Handwritten Digits Data Set\n===================================================
-
\n\nNotes\n-----\nData Set Characteristics:\n :Number of Instances:
-
5620\n :Number of Attributes: 64\n :Attribute Information:
-
8x8 image of integer pixels in the range 0..16.\n :Missing Attribute Values:
-
None\n :Creator: E. Alpaydin (alpaydin '@' boun.edu.tr)\n :Date: July;
-
1998\n\nThis is a copy of the test set of the UCI ML hand-written digits
-
datasets\nhttp://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+
-
Digits\n\nThe data set contains images of hand-written digits: 10 classes where\neach
-
class refers to a digit.\n\nPreprocessing programs made available by NIST were used
-
to extract\nnormalized bitmaps of handwritten digits from a preprinted form. From
-
a\ntotal of 43 people, 30 contributed to the training set and different 13\nto the
-
test set. 32x32 bitmaps are divided into nonoverlapping blocks of\n4x4 and the
-
number of on pixels are counted in each block. This generates\nan input matrix of
-
8x8 where each element is an integer in the range\n0..16. This reduces dimensionality
-
and gives invariance to small\ndistortions.\n\nFor info on NIST preprocessing routines,
-
see M. D. Garris, J. L. Blue, G.\nT. Candela, D. L. Dimmick, J. Geist, P. J. Grother,
-
S. A. Janet, and C.\nL. Wilson, NIST Form-Based Handprint Recognition System, NISTIR
-
5469,\n1994.\n\nReferences\n----------\n - C. Kaynak (1995) Methods of Combining
-
Multiple Classifiers and Their\n Applications to Handwritten Digit Recognition,
-
MSc Thesis, Institute of\n Graduate Studies in Science and Engineering, Bogazici
-
University.\n - E. Alpaydin, C. Kaynak (1998) Cascading Classifiers, Kybernetika.\n
-
- Ken Tang and Ponnuthurai N. Suganthan and Xi Yao and A. Kai Qin.\n Linear
-
dimensionalityreduction using relevance weighted LDA. School of\n Electrical
-
and Electronic Engineering Nanyang Technological University.\n 2005.\n - Claudio
-
Gentile. A New Approximate Maximal Margin Classification\n Algorithm. NIPS.
-
2000.\n", 'target': array([0, 1, 2, ..., 4, 4, 0])}
本案例只提取从数字0到数字5的图片进行降维,我们挑选图片数据集中的前六个照片进行展示,实现代码如下所示:
-
# plt.gray()
-
fig, axes = plt.subplots(nrows=1, ncols=6, figsize=(8, 8))
-
for i,ax in zip(range(6),axes.flatten()):
-
ax.imshow(digits.images[i], cmap=plt.cm.gray_r)
-
plt.show()
效果如下所示:
为了能够方便的展示手写数字图片,使用返回Bunch
对象的导入方式,实现代码如下所示:
-
digits = datasets.load_digits(n_class=6)
-
X = digits.data
-
y = digits.target
-
n_samples, n_features = X.shape
-
n_neighbors = 30
2、数据集可视化
将数据集部分数据图片可视化显示,实现代码如下所示:
-
n_img_per_row = 30 # 每行显示30个图片
-
# 整个图形占 300*300,由于一张图片为8*8,所以每张图片周围包了一层白框,防止图片之间互相影响
-
img = np.zeros((10 * n_img_per_row, 10 * n_img_per_row))
-
for i in range(n_img_per_row):
-
ix = 10 * i + 1
-
for j in range(n_img_per_row):
-
iy = 10 * j + 1
-
img[ix:ix + 8, iy:iy + 8] = X[i * n_img_per_row + j].reshape((8, 8))
-
plt.figure(figsize=(6,6))
-
plt.imshow(img, cmap=plt.cm.binary)
-
plt.xticks([])
-
plt.yticks([])
-
plt.title('A selection from the 64-dimensional digits dataset')
效果如下所示:
3、降维及可视化
图片数据是一种高维数据(从几十到上百万的维度),如果把每个图片看成是高维空间的点,要把这些点在高维空间展示出来是极其困难的,所以我们需要将这些数据进行降维,在二维或者三维空间中看出整个数据集的内嵌结构。
本案例要展示的降维方法及所在sklearn的模块如下表所示:
调用以上方法进行降维的流程都是类似的:
- 首先根据具体方法创建实例:
实例名 = sklearn模块.调用的方法(一些参数的设置)
- 然后对数据进行转换:
转换后的数据变量名 = 实例名.fit_transform(X)
,在某些方法如LDA降维中还需要提供标签y
- 最后将转换后的数据进行可视化:输入转换后的数据以及标题,画出二维空间的图。
为了绘图方便并统一画图的风格,首先定义plot_embedding
函数用于画出低维嵌入的图形。
配色方案如下所示:
。。。。。。。。。。。。。。。。。
版权原因,完整文章,请参考如下: