sklearn学习 5.降维算法PCA和SVD

一.概述

**1.从什么叫“维度”说开来 **
对于数组和Series来说,维度就是功能shape返回的结果,shape中返回了几个数字,就是几维。索引以外的数 据,不分行列的叫一维(此时shape返回唯一的维度上的数据个数),有行列之分叫二维(shape返回行x列),也 称为表。一张表多二维,复数的表构成了更高的维度。当一个数组中存在2张3行4列的表时,shape返回的是(更 高维,行,列)。当数组中存在2组2张3行4列的表时,数据就是4维,shape返回(2,2,3,4)。
sklearn学习 5.降维算法PCA和SVD_第1张图片
数组中的每一张表,都可以是一个特征矩阵或一个DataFrame,这些结构永远只有一张表,所以一定有行列,其中 行是样本,列是特征。针对每一张表,维度指的是样本的数量或特征的数量,一般无特别说明,指的都是特征的数 量。除了索引之外,一个特征是一维,两个特征是二维,n个特征是n维。
在这里插入图片描述
对图像来说,维度就是图像中特征向量的数量。特征向量可以理解为是坐标轴,一个特征向量定义一条直线,是一 维,两个相互垂直的特征向量定义一个平面,即一个直角坐标系,就是二维,三个相互垂直的特征向量定义一个空 间,即一个立体直角坐标系,就是三维。三个以上的特征向量相互垂直,定义人眼无法看见,也无法想象的高维空间。
sklearn学习 5.降维算法PCA和SVD_第2张图片
降维算法中的”降维“,指的是降低特征矩阵中特征的数量。上周的课中我们说过,降维的目的是为了让算法运算更 快,效果更好,但其实还有另一种需求:数据可视化。从上面的图我们其实可以看得出,图像和特征矩阵的维度是 可以相互对应的,即一个特征对应一个特征向量,对应一条坐标轴。所以,三维及以下的特征矩阵,是可以被可视 化的,这可以帮助我们很快地理解数据的分布,而三维以上特征矩阵的则不能被可视化,数据的性质也就比较难理解。
**2.sklearn中的降维算法 **
sklearn中降维算法都被包括在模块decomposition中,这个模块本质是一个矩阵分解模块。在过去的十年中,如 果要讨论算法进步的先锋,矩阵分解可以说是独树一帜。矩阵分解可以用在降维,深度学习,聚类分析,数据预处 理,低纬度特征学习,推荐系统,大数据分析等领域。在2006年,Netflix曾经举办了一个奖金为100万美元的推荐 系统算法比赛,后的获奖者就使用了矩阵分解中的明星:奇异值分解SVD
sklearn学习 5.降维算法PCA和SVD_第3张图片
SVD和主成分分析PCA都属于矩阵分解算法中的入门算法,都是通过分解特征矩阵来进行降维

二.PCA与SVD

在降维过程中,我们会减少特征的数量,这意味着删除数据,数据量变少则表示模型可以获取的信息会变少,模型 的表现可能会因此受影响。同时,在高维数据中,必然有一些特征是不带有有效的信息的(比如噪音),或者有一 些特征带有的信息和其他一些特征是重复的(比如一些特征可能会线性相关)。我们希望能够找出一种办法来帮助 我们衡量特征上所带的信息量,让我们在降维的过程中,能够即减少特征的数量,又保留大部分有效信息——将那 些带有重复信息的特征合并,并删除那些带无效信息的特征等等——逐渐创造出能够代表原特征矩阵大部分信息 的,特征更少的,新特征矩阵
特征工程课中,我们提到过一种重要的特征选择方法:方差过滤。如果一个特征的方差很小,则意味着这个 特征上很可能有大量取值都相同(比如90%都是1,只有10%是0,甚至100%是1),那这一个特征的取值对样本而 言就没有区分度,这种特征就不带有有效信息。从方差的这种应用就可以推断出,如果一个特征的方差很大,则说 明这个特征上带有大量的信息。因此,在降维中,PCA使用的信息量衡量指标,就是样本方差,又称可解释性方 差,方差越大,特征所带的信息量越多。
在这里插入图片描述
Var代表一个特征的方差,n代表样本量,xi代表一个特征中的每个样本取值,xhat代表这一列样本的均值。

1.降维究竟是怎样实现

class sklearn.decomposition.PCA (n_components=None, copy=True, whiten=False, svd_solver=’auto’, tol=0.0, iterated_power=’auto’, random_state=None) 

sklearn学习 5.降维算法PCA和SVD_第4张图片
我们现在有一组简单的数据,有特征x1和x2,三个样本数据的坐标点分别为(1,1),(2,2),(3,3)。我们可以让x1和 x2分别作为两个特征向量,很轻松地用一个二维平面来描述这组数据。这组数据现在每个特征的均值都为2,方差 则等于:
在这里插入图片描述
每个特征的数据一模一样,因此方差也都为1,数据的方差总和是2。
现在我们的目标是:只用一个特征向量来描述这组数据,即将二维数据降为一维数据,并且尽可能地保留信息量, 即让数据的总方差尽量靠近2。于是,我们将原本的直角坐标系逆时针旋转45°,形成了新的特征向量x1和x2组 成的新平面,在这个新平面中,三个样本数据的坐标点可以表示为 ( 2 , 0 ) , ( 2 2 , 0 ) , ( 3 2 , 0 ) (\sqrt{2},0),(2\sqrt{2},0),(3\sqrt{2},0) (2 ,0)(22 ,0)(32 ,0)。可 以注意到,x2上的数值此时都变成了0,因此x2明显不带有任何有效信息了(此时x2的方差也为0了)。此时, x2特征上的数据均值是 2 2 2\sqrt{2} 22 ,而方差则可表示成:
在这里插入图片描述
x1*上的数据均值为0,方差也为0。

此时,我们根据信息含量的排序,取信息含量大的一个特征,因为我们想要的是一维数据。所以我们可以将x2* 删除,同时也删除图中的x2特征向量,剩下的x1就代表了曾经需要两个特征来代表的三个样本点。通过旋转原 有特征向量组成的坐标轴来找到新特征向量和新坐标平面,我们将三个样本点的信息压缩到了一条直线上,实现了 二维变一维,并且尽量保留原始数据的信息。一个成功的降维,就实现了。
sklearn学习 5.降维算法PCA和SVD_第5张图片
在这个降维过程中,有几个重要的步骤
sklearn学习 5.降维算法PCA和SVD_第6张图片
在步骤3当中,我们用来找出n个新特征向量,让数据能够被压缩到少数特征上并且总信息量不损失太多的技术就是 矩阵分解。PCA和SVD是两种不同的降维算法,但他们都遵从上面的过程来实现降维,只是两种算法中矩阵分解的 方法不同,信息量的衡量指标不同罢了。PCA使用方差作为信息量的衡量指标,并且特征值分解来找出空间V。降 维时,它会通过一系列数学的神秘操作(比如说,产生协方差矩阵 1 n X X T \frac{1}{n}XX^{T} n1XXT)将特征矩阵X分解为以下 三个矩阵,其中 Q Q Q Q − 1 Q^{-1} Q1是辅助的矩阵,Σ是一个对角矩阵(即除了对角线上有值,其他位置都是0的矩 阵),其对角线上的元素就是方差。降维完成之后,PCA找到的每个新特征向量就叫做“主成分”,而被丢弃的特征 向量被认为信息量很少,这些信息很可能就是噪音。
在这里插入图片描述
而SVD使用奇异值分解来找出空间V,其中Σ也是一个对角矩阵,不过它对角线上的元素是奇异值,这也是SVD中用 来衡量特征上的信息量的指标。U和V^{T}分别是左奇异矩阵和右奇异矩阵,也都是辅助矩阵。
在这里插入图片描述
在数学原理中,无论是PCA和SVD都需要遍历所有的特征和样本来计算信息量指标。并且在矩阵分解的过程之中, 会产生比原来的特征矩阵更大的矩阵,比如原数据的结构是(m,n),在矩阵分解中为了找出佳新特征空间V,可能 需要产生(n,n),(m,m)大小的矩阵,还需要产生协方差矩阵去计算更多的信息。而现在无论是Python还是R,或者 其他的任何语言,在大型矩阵运算上都不是特别擅长,无论代码如何简化,我们不可避免地要等待计算机去完成这 个非常庞大的数学计算过程。因此,降维算法的计算量很大,运行比较缓慢,但无论如何,它们的功能无可替代, 它们依然是机器学习领域的宠儿。

思考:降维和特征选择都是特征工程技术,它们有什么不同?

特征工程中有三种方式:特征提取,特征创造和特征选择。仔细观察上面的降维例子和上周我们讲解过的特征 选择,你发现有什么不同了吗?

特征选择是从已存在的特征中选取携带信息多的,选完之后的特征依然具有可解释性,我们依然知道这个特 征在原数据的哪个位置,代表着原数据上的什么含义。

而降维算法,是将已存在的特征进行压缩,降维完毕后的特征不是原本的特征矩阵中的任何一个特征,而是通 过某些方式组合起来的新特征。通常来说,在新的特征矩阵生成之前,我们无法知晓降维算法们都建立了怎样 的新特征向量,新特征矩阵生成之后也不具有可读性,我们无法判断新特征矩阵的特征是从原数据中的什么特 征组合而来,新特征虽然带有原始数据的信息,却已经不是原数据上代表着的含义了。降维算法因此是特征创 造(feature creation,或feature construction)的一种。

可以想见,PCA一般不适用于探索特征和标签之间的关系的模型(如线性回归),因为无法解释的新特征和标 签之间的关系不具有意义。在线性回归模型中,我们使用特征选择。
**2.重要参数n_components **
n_components是我们降维后需要的维度,即降维后需要保留的特征数量,降维流程中第二步里需要确认的k值, 一般输入[0, min(X.shape)]范围中的整数。一说到K,大家可能都会想到,类似于KNN中的K和随机森林中的 n_estimators,这是一个需要我们人为去确认的超参数,并且我们设定的数字会影响到模型的表现。如果留下的特 征太多,就达不到降维的效果,如果留下的特征太少,那新特征向量可能无法容纳原始数据集中的大部分信息,因 此,n_components既不能太大也不能太小。那怎么办呢?
可以先从我们的降维目标说起:如果我们希望可视化一组数据来观察数据分布,我们往往将数据降到三维以下,很 多时候是二维,即n_components的取值为2。
** 迷你案例:高维数据的可视化 **
调用库和模块

import matplotlib.pyplot as plt from sklearn.datasets import load_iris from sklearn.decomposition import PCA

提取数据集

iris = load_iris() y = iris.target X = iris.data #作为数组,X是几维? X.shape #作为数据表或特征矩阵,X是几维? import pandas as pd pd.DataFrame(X)

建模

#调用PCA pca = PCA(n_components=2)           #实例化 
pca = pca.fit(X)                    #拟合模型 
X_dr = pca.transform(X)             #获取新矩阵
 
X_dr #也可以fit_transform一步到位 #X_dr = PCA(2).fit_transform(X

可视化

#要将三种鸢尾花的数据分布显示在二维平面坐标系中,对应的两个坐标(两个特征向量)应该是三种鸢尾花降维后的 x1和x2,怎样才能取出三种鸢尾花下不同的x1和x2呢?
 
X_dr[y == 0, 0] #这里是布尔索引,看出来了么?
 
#要展示三中分类的分布,需要对三种鸢尾花分别绘图 #可以写成三行代码,也可以写成for循环 
""" plt.figure() 
plt.scatter(X_dr[y==0, 0], X_dr[y==0, 1], c="red", label=iris.target_names[0]) 
plt.scatter(X_dr[y==1, 0], X_dr[y==1, 1], c="black", label=iris.target_names[1]) 
plt.scatter(X_dr[y==2, 0], X_dr[y==2, 1], c="orange", label=iris.target_names[2]) 
plt.legend() 
plt.title('PCA of IRIS dataset') 
plt.show() """
 
colors = ['red', 'black', 'orange'] 
iris.target_names
 
plt.figure() 
for i in [0, 1, 2]:    
    plt.scatter(X_dr[y == i, 0]
                    ,X_dr[y == i, 1]
                    ,alpha=.7
                    ,c=colors[i]                
                    ,label=iris.target_names[i]               ) plt.legend() 
plt.title('PCA of IRIS dataset') 
plt.show()

鸢尾花的分布被展现在我们眼前了,明显这是一个分簇的分布,并且每个簇之间的分布相对比较明显,也许 versicolor和virginia这两种花之间会有一些分类错误,但setosa肯定不会被分错。这样的数据很容易分类,可以遇 见,KNN,随机森林,神经网络,朴素贝叶斯,Adaboost这些分类器在鸢尾花数据集上,未调整的时候都可以有 95%上下的准确率

探索降维后的数据

#属性explained_variance,查看降维后每个新特征向量上所带的信息量大小(可解释性方差的大小) 
pca.explained_variance_
 
#属性explained_variance_ratio,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比 #又叫做可解释方差贡献率 
pca.explained_variance_ratio_ 
#大部分信息都被有效地集中在了第一个特征上
 
pca.explained_variance_ratio_.sum()

选择最好的n_components:累积可解释方差贡献率曲线

当参数components中不填写任何值,则默认返回min(X.shape)个特征,一般来说,样本量都会大于特征数目,所 以什么都不填就相当于转换了新特征空间,但没有减少特征的个数。一般来说,不会使用这种输入方式。但我们却 可以使用这种输入方式来画出累计可解释方差贡献率曲线,以此选择好的n_components的整数取值。
累积可解释方差贡献率曲线是一条以降维后保留的特征个数为横坐标,降维后新特征矩阵捕捉到的可解释方差贡献 率为纵坐标的曲线,能够帮助我们决定n_components好的取值。

import numpy as np 
pca_line = PCA().fit(X) plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_)) plt.xticks([1,2,3,4]) #这是为了限制坐标轴显示为整数 
plt.xlabel("number of components after dimension reduction") plt.ylabel("cumulative explained variance") 
plt.show()

最大似然估计自选超参数

除了输入整数,n_components还有哪些选择呢?之前我们提到过,矩阵分解的理论发展在业界独树一帜,勤奋智 慧的数学大神Minka, T.P.在麻省理工学院媒体实验室做研究时找出了让PCA用大似然估计(maximum likelihood estimation)自选超参数的方法,输入“mle”作为n_components的参数输入,就可以调用这种方法

pca_mle = PCA(n_components="mle") 
pca_mle = pca_mle.fit(X) 
X_mle = pca_mle.transform(X)
 
X_mle #可以发现,mle为我们自动选择了3个特征
 
pca_mle.explained_variance_ratio_.sum() 
#得到了比设定2个特征时更高的信息含量,对于鸢尾花这个很小的数据集来说,3个特征对应这么高的信息含量,并不 需要去纠结于只保留2个特征,毕竟三个特征也可以可视化

** 最大似然估计自选超参数 **
除了输入整数,n_components还有哪些选择呢?之前我们提到过,矩阵分解的理论发展在业界独树一帜,勤奋智 慧的数学大神Minka, T.P.在麻省理工学院媒体实验室做研究时找出了让PCA用大似然估计(maximum likelihood estimation)自选超参数的方法,输入“mle”作为n_components的参数输入,就可以调用这种方法

pca_mle = PCA(n_components="mle") 
pca_mle = pca_mle.fit(X) 
X_mle = pca_mle.transform(X)
 
X_mle #可以发现,mle为我们自动选择了3个特征
 
pca_mle.explained_variance_ratio_.sum() #得到了比设定2个特征时更高的信息含量,对于鸢尾花这个很小的数据集来说,3个特征对应这么高的信息含量,并不 需要去纠结于只保留2个特征,毕竟三个特征也可以可视化

按信息量占比选超参数
输入[0,1]之间的浮点数,并且让参数svd_solver ==‘full’,表示希望降维后的总解释性方差占比大于n_components 指定的百分比,即是说,希望保留百分之多少的信息量。比如说,如果我们希望保留97%的信息量,就可以输入 n_components = 0.97,PCA会自动选出能够让保留的信息量超过97%的特征数量。

pca_f = PCA(n_components=0.97,svd_solver="full") 
pca_f = pca_f.fit(X) 
X_f = pca_f.transform(X)
 
pca_f.explained_variance_ratio_ 

**3. 重要参数svd_solver **
PCA中的SVD哪里来?

svd_solver是奇异值分解器的意思,为什么PCA算法下面会有有关奇异值分解的参 数?不是两种算法么?我们之前曾经提到过,PCA和SVD涉及了大量的矩阵计算,两者都是运算量很大的模型,但 其实,SVD有一种惊人的数学性质,即是它可以跳过数学神秘的宇宙,不计算协方差矩阵,直接找出一个新特征向 量组成的n维空间,而这个n维空间就是奇异值分解后的右矩阵 V T V^{T} VT(所以一开始在讲解降维过程时,我们说”生 成新特征向量组成的空间V",并非巧合,而是特指奇异值分解中的矩阵 V T V^{T} VT)。
sklearn学习 5.降维算法PCA和SVD_第7张图片
k就是n_components,是我们降维后希望得到的维度。若X为(m,n)的特征矩阵,V^{T}就是结构为(n,n)的矩阵,取 这个矩阵的前k行(进行切片),即将V转换为结构为(k,n)的矩阵。而V_{(k,n)}与原特征矩阵X相乘,即可得到降维 后的特征矩阵X_dr。这是说,奇异值分解可以不计算协方差矩阵等等结构复杂计算冗长的矩阵,就直接求出新特征 空间和降维后的特征矩阵。

简而言之,SVD在矩阵分解中的过程比PCA简单快速,虽然两个算法都走一样的分解流程,但SVD可以作弊耍赖。 但是遗憾的是,SVD的信息量衡量指标比较复杂,要理解”奇异值“远不如理解”方差“来得容易,因此,sklearn将降 维流程拆成了两部分:一部分是计算特征空间V,由奇异值分解完成,另一部分是映射数据和求解新特征矩阵,由 主成分分析完成,实现了用SVD的性质减少计算量,却让信息量的评估指标是方差,具体流程如下图:
sklearn学习 5.降维算法PCA和SVD_第8张图片

你可能感兴趣的:(机器学习,可视化)