机器学习与计算机视觉深度学习OpenCv

2020机器学习PCA 降维实践

2020-02-05  本文已影响0人  zidea
machine_learning.jpg

实例1 我们从一个简单数据集(鸢尾花数据集)开始,这里我就不过多介绍这个数据集了,通过鸢尾花的以下 4 特征

from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

iris = load_iris()

查看数据集

加载完数据集,我们可以通过打印简单了解一下数据集的样子

print(iris.data.shape)
print(iris.feature_names)
print(iris.target_names)
(150, 4)
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
['setosa' 'versicolor' 'virginica']

定义 PCA

这里创建 PCA 然后我们降维为 2 维度,原先数据集为 4 个维度数据

pca = PCA(2)
print(pca)
PCA(copy=True, iterated_power='auto', n_components=2, random_state=None,
  svd_solver='auto', tol=0.0, whiten=False)

我觉得有必要解释一下 sklearn 的 PCA 的参数,

X, y = iris.data, iris.target
X_proj = pca.fit_transform(X)

plt.scatter(X_proj[:,0], X_proj[:,1],c=y) 
plt.show()
output_8_0.png

我们可以借助 PCA 和 SVM 进行人脸识别,这里使用 sklearn 提供的面部 Olivetti 数据集。通过 PCA 对图片进行压缩

from sklearn.datasets import fetch_olivetti_faces
oliv=fetch_olivetti_faces()
print(oliv.keys())
downloading Olivetti faces from https://ndownloader.figshare.com/files/5976027 to /Users/jangwoo/scikit_learn_data
dict_keys(['data', 'images', 'target', 'DESCR'])
print(oliv.data.shape)
#400 张图片 图片大小为 64 x 64 (4096) pixels 
(400, 4096)
fig = plt.figure(figsize=(6,6))
for i in range(64):
    ax = fig.add_subplot(8, 8, i+1, xticks=[], yticks=[]) 
    ax.imshow(oliv.images[i], cmap=plt.cm.bone, interpolation='nearest') 
plt.show()
output_12_0.png

X,y=oliv.data, oliv.target
pca_oliv = PCA(64)
X_proj = pca_oliv.fit_transform(X)
print(pca_oliv)
PCA(copy=True, iterated_power='auto', n_components=64, random_state=None,
  svd_solver='auto', tol=0.0, whiten=False)
print(np.cumsum(pca_oliv.explained_variance_ratio_))
[0.2381271  0.37806675 0.4577528  0.50773615 0.5438346  0.57540405
 0.5996724  0.62003636 0.6396175  0.6563387  0.6722909  0.6866607
 0.69912815 0.7105995  0.72122824 0.73100543 0.74019605 0.7483518
 0.75589055 0.7633604  0.77034616 0.7764924  0.7823317  0.7880289
 0.7934908  0.79880935 0.8039475  0.8089059  0.8134825  0.81789434
 0.8219143  0.82575613 0.82937557 0.8327207  0.8359242  0.839084
 0.84213424 0.8451201  0.8479405  0.85067976 0.85327536 0.8558125
 0.85825586 0.8606506  0.86295485 0.8652151  0.86743444 0.86963314
 0.8717143  0.87375385 0.8756971  0.8775972  0.8794373  0.8812151
 0.8829779  0.8846808  0.8863216  0.887924   0.8895061  0.8910453
 0.8925585  0.8940452  0.89550924 0.89692205]

64x64像素的图像压缩为8x8像素的图像仍然保留了89.7%的方差

fig = plt.figure(figsize=(8,8))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
for i in range(10):
    ax = fig.add_subplot(5, 5, i+1, xticks=[], yticks=[])
    ax.imshow(np.reshape(pca_oliv.components_[i,:], (64,64)), cmap=plt.cm.bone, interpolation='nearest')
plt.show()
output_17_0.png

我们看看图片,现在我们数据只有 8 \times 8 维度数据,我们需要将这些数据恢复到 64 \times 64 图片,64 \times 64 维度图片并不是原始数据。我们只是恢复图片的尺寸,数据与原始数据不同。

X_inv_proj = pca_oliv.inverse_transform(X_proj)
X_proj_img = np.reshape(X_inv_proj,(400,64,64))
fig = plt.figure(figsize=(6,6))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
for i in range(64):
    ax = fig.add_subplot(8, 8, i+1, xticks=[], yticks=[])
    ax.imshow(X_proj_img[i], cmap=plt.cm.bone, interpolation='nearest')
output_19_0.png

经过降维后,我们来展示一下图片,虽然在细节上有些缺失,但是这些图片效果还算不错。这个说明我们高维特征图像其实只占据一部分特征。

(待续)
最后希望大家关注我们微信公众号


wechat.jpeg
上一篇下一篇

猜你喜欢

热点阅读