目录
数据降维会丢失一些信息(好比压缩图像带来的效果一样),所以,它虽然能够加速训练,但是也会轻微降低系统性能。
我们简要说一下降维的两种主要方法:投影和流形学习。投影:高维空间的所有训练实例实际上受一个低得多的低维子空间所影响,将训练实例投影到该子空间就是投影。但许多情况下,子空间可能是弯曲的或转动的,就引入了流形学习。流形假设(流形假说)认为大多数现实世界的高维度数据集存在一个低维度的流形来重新表示。我们可以把瑞士卷看做一个二维流形的例子。更概括的说,d维流形就是n维空间的一部分(d<n),局部类似于一个d维超平面。
主成分分析(PCA)是迄今最流行的降维算法。它能识别出最接近数据的超平面,然后将数据投影该平面。同时该超平面也保留了数据最大差异性。
常规模块的导入以及图像可视化的设置:
# Common imports
import numpy as np
import os
# to make this notebook's output stable across runs
np.random.seed(42)
# To plot pretty figures
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)
1 主成分
主成分分析(PCA)可以在训练集中识别出哪条轴(一维超平面)对差异性的贡献度最高。即下图中由实线表示的轴。同时它也找出了第二条轴,它对剩余差异性的贡献度最高,与第一条轴垂直。
定义第i条轴的单位向量就叫作第i个主成分。上图中,第一个主成分是c1,第二个主成分是c2。前两个主成分是平面里正交的箭头所示,第三个主成分则垂直于平面。
那么我们该怎么找到训练集的主成分呢?我们有一种标准矩阵分解技术,叫作奇异值分解(SVD)。它可以将训练集矩阵X分解成三个矩阵的点积 ,其中 正包含我们想要的所有主成分,公式如下:
下面的代码使用NumPy的svd()函数来获取训练集中所有主成分,并提取前两个:
#3D数据集
np.random.seed(4)
m = 60
w1, w2 = 0.1, 0.3
noise = 0.1
angles = np.random.rand(m) * 3 * np.pi / 2 - 0.5
X = np.empty((m, 3))
X[:, 0] = np.cos(angles) + np.sin(angles)/2 + noise * np.random.randn(m) / 2
X[:, 1] = np.sin(angles) * 0.7 + noise * np.random.randn(m) / 2
X[:, 2] = X[:, 0] * w1 + X[:, 1] * w2 + noise * np.random.randn(m)
#获取主成分
X_centered = X - X.mean(axis=0)
U, s, Vt = np.linalg.svd(X_centered)
c1 = Vt.T[:, 0]
c2 = Vt.T[:, 1]
2 低维度投影
一旦确定了所有主成分,就可以将数据集投影到由前d个主成分定义的超平面上,从而将数据集的维度降低到d维,这个超平面的选择,能确保投影保留尽可能多的差异性。
要将训练集投影到超平面上,简单地计算训练集矩阵X和矩阵 的点积即可, 是包含前d个主成分的矩阵(即由矩阵 的前d列组成的矩阵),如下式:
下面的代码将训练集投影到由前两个主成分定义的平面上:
W2 = Vt.T[:, :2]
X2D = X_centered.dot(W2)
Scikit-Learn的PCA类使用SVD分解来实现主成分,下面代码应用PCA将数据集的维度降到二维(它会自动处理数据集中) :
from sklearn.decomposition import PCA
pca = PCA(n_components = 2)
X2D = pca.fit_transform(X)
我们可以通过变量components_来访问主成分:
pca.components_
运行结果如下:
array([[-0.93636116, -0.29854881, -0.18465208],
[ 0.34027485, -0.90119108, -0.2684542 ]])
第一个主成分等于 pca.components_.T[:,0] 。
pca.components_.T[:,0]
运行结果如下:
array([-0.93636116, -0.29854881, -0.18465208])
3 方差解释率
方差解释率可以通过变量 explained_variance_ratio_ 获得。它表示每个主成分轴对整个数据集的方差贡献度。我们看一下(3D数据集)前两个主成分的方差解释率:
pca.explained_variance_ratio_
运行结果如下:
array([0.84248607, 0.14631839])