2020机器学习PCA 降维实践
2020-02-05 本文已影响0人
zidea
machine_learning.jpg
wechat.jpeg
实例1 我们从一个简单数据集(鸢尾花数据集)开始,这里我就不过多介绍这个数据集了,通过鸢尾花的以下 4 特征
- Sepal.Length(花萼长度)
- Sepal.Width(花萼宽度)
- Petal.Length(花瓣长度)
- Petal.Width(花瓣宽度)
来分类为 3 个类别
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 的参数,
- n_components PCA降维后的特征维度数目,如果没有指定
-
svd_solver
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
我们看看图片,现在我们数据只有 维度数据,我们需要将这些数据恢复到 图片, 维度图片并不是原始数据。我们只是恢复图片的尺寸,数据与原始数据不同。
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