目录
一.引言
二.PCA 理论
1.主成分分析定义
2.数学基础
A.数据归一化
B.协方差矩阵计算
C.计算协方差矩阵的特征向量和特征值,以识别主成分
D.构造特征向量矩阵
E.沿着主成分轴重新计算数据
三.PCA 实战
1.数据准备
2.PCA 初始化
3.数据降维
四.总结
一.引言
主成分分析 (Principal Component Analysis PCA) 是指将多个变量通过线性变化以选出少数重要变量的一种多元统计方法,又称主分量分析。在实际应用场合下,为了全面分析问题,往往提出很多与此有关的变量, 而不同变量在不同程度上反映这个场合的某些信息。主成分分析是设法将原来众多具有一定相关性的指标重新组合成一组新的互相无关的综合指标来代替,从而实现降维的目的。
二.PCA 理论
1.主成分分析定义
使用统计方法研究多变量课题时,随着变量个数的增多课题的复杂性也随之增加。一些场景下我们希望变量个数尽可能的少且损失的关键信息也越少。在很多情况下,变量之间是有一定相关性的,有时也称共线性,即二者在提供信息时存在一定重叠。主成分分析是对于原先提出的所有变量,将重复或者共线性抢的变量删除,建立尽可能少的变量且互不相关,而且这些新变量能够尽可能保持原有的信息。
2.数学基础
假设有一个二维数据集 (x1,x2,x3...,xn),要求将其从二维降维一维数据。
最直观的方法就是绕着数据旋转,看从哪个视角看过去能够保留更多地点,且以这条线为主,数据分散程度越大,方差越大,那么这个角度或者方向就是后续主成分分析的主方向。实际过程中,由于数据多为高维所以这里只适用一些易于观察的低维数据用于直观理解,下面看一下 PCA 的主要流程:
A.数据归一化
这一步骤的目的是使连续初始变量的范围标准化,使每个变量对分析的贡献相等。
更具体地说,PCA 主成分分析之前进行标准化至关重要的原因是 PCA 对初始变量的方差非常敏感。也就是说,如果初始变量的范围之间存在较大差异,则范围较大的变量将主导范围较小的变量(例如,范围在0和100之间的变量将支配范围在0到1之间的变量),这将导致偏差结果。因此,将数据转换为可比较的尺度可以防止这个问题。
数学实现上,我们可以通过减去均值并除以标准差实现归一化。
一旦标准化完成,所有变量将转换为相同的比例。
B.协方差矩阵计算
这一步骤的目的是了解输入数据集的变量是如何相对于彼此的平均值变化的,或者换句话说,看看它们之间是否存在任何关系。因为有时,变量高度相关,从而包含冗余信息。因此,为了识别这些相关性,我们计算协方差矩阵。这也可以看做是对数据共线性的分析。
协方差矩阵是一个 p×p 对称矩阵 (其中p是维数),以与所有可能的初始变量对相关的协方差作为条目。例如,对于具有 3 个变量 x、y 和 z 的三维数据集,协方差矩阵为3×3矩阵,如下所示:
由于变量与其自身的协方差是其方差 Cov(a,a) = Var(a),且 Cov(a,b) = Cov(b,a),因此协方差矩阵的对角线不变,且上三角部分和下三角部分相同。
如果 Cov(x,y) 为正,则代表两个变量的变化方向相同,反之如果 Cov(x,y) 为负,则二者呈现此消彼长之势,通过协方差矩阵我们可以获得所有变量之间关于相关性的矩阵。
C.计算协方差矩阵的特征向量和特征值,以识别主成分
特征向量和特征值是线性代数概念,我们需要根据协方差矩阵来计算,以确定数据的主要成分。在解释这些概念之前,让我们先了解一下我们所说的主成分是什么意思。
主成分是由初始变量的线性组合或混合构成的新变量。这些组合是以这样的方式进行的,即新变量(即主成分)是不相关的,并且初始变量内的大部分信息被压缩或压缩到第一成分中。所以,这个想法是10维数据给你10个主要成分,但PCA试图将最大可能的信息放在第一个成分中,然后将最大剩余信息放在第二个成分中。通过特征值的大小,我们可以从大到小排列获取不同方向特征的重要性,通过对应的特征向量组合,我们即可获得原始信息的近似。
PCA 将特征重要性从高到低排列,我们可以根据自己的精度要求或者应用场景需求判断获取最重要的 K 维特征。这里需要认识到的一件重要事情是,主成分不太可解释,也没有任何实际意义,因为它们被构造为初始变量的线性组合。
从几何学上讲,主成分代表了解释最大方差的数据方向,也就是说,代表了数据中大部分信息的线。这里,方差和信息之间的关系是,一条线承载的方差越大,沿线数据点的离散度就越大,而沿线的离散度越大,信息就越多。简单地说,只需将主分量视为提供最佳角度来查看和评估数据的新轴,以便观察结果之间的差异更加明显。
假设我们的数据集是2维的,具有2个变量x,y,协方差矩阵的特征向量和特征值如上:
按降序排列特征值,我们得到 λ1>λ2,这意味着对应于第一个主分量(PC1)的特征向量是v1,对应于第二个分量(PC2)的特征矢量是v2。在获得主成分后,我们可以计算每个成分所占的方差(信息)百分比,我们将每个成分的特征值除以特征值之和。如果我们将此应用于上述示例,我们发现 PC1 和 PC2 分别携带 96% 和 4% 的数据方差:
可以看到以 λ1 为主成分即可保留二维数据的大部分信息,当然这是基于方差而言,并不具备一定的真实意义与可解释性。
D.构造特征向量矩阵
正如我们在上一步中所看到的,计算特征向量并按其特征值降序排序,可以让我们按照重要性的顺序找到主成分。在这一步中,我们要做的是,选择是保留所有这些分量,还是丢弃那些意义较小的分量(低特征值),并用剩下的分量形成一个向量矩阵,我们称之为特征向量。
因此,特征向量只是一个矩阵,它将我们决定保留的分量的特征向量作为列。这使得它成为降维的第一步,因为如果我们选择在n中只保留p个特征向量(分量),那么最终的数据集将只有p个维度。
还是刚才的例子,我们选择保留主成分 λ1,因此特征向量为 λ1 对应的特征向量:
当然,选择那些特征值对应的特征向量由用户决定,如果我只想获取几个最不相关的变量来描述我的数据,那么就无需去掉后面那些不重要的成分。
E.沿着主成分轴重新计算数据
在前面的步骤中,除了标准化之外,您不需要对数据进行任何更改,只需选择主要成分并形成特征向量,但输入数据集始终保持原始轴(即,初始变量)。
在这一步骤(这是最后一步)中,目标是使用使用协方差矩阵的特征向量形成的特征向量,将数据从原始轴重新定向到由主分量表示的轴(因此称为主分量分析)。这可以通过特征向量的转置乘以原始数据得到。
假设原始矩阵维度为 MxN,主成分分析后选择前 K 个特征向量,对应特征矩阵 KxN,则降维后的数据 MxN · NxK[转置] = MxK。
参考: A Step-by-Step Explanation of Principal Component Analysis (PCA)
三.PCA 实战
1.数据准备
val spark = SparkSession
.builder //创建spark会话
.master("local") //设置本地模式
.appName("PCAExample") //设置名称
.getOrCreate() //创建会话变量
// 加载向量
val data = Array(
Vectors.sparse(5, Seq((1, 1.0), (3, 7.0))),
Vectors.dense(2.0, 0.0, 3.0, 4.0, 5.0),
Vectors.dense(4.0, 0.0, 0.0, 6.0, 7.0)
)
val df = spark.createDataFrame(data.map(Tuple1.apply)).toDF("features")
原始特征维度为 3x5,通过 sparkSession 转换为 DF 并添加到 features 列。
2.PCA 初始化
//提取主成分,设置主成分个数
val pca = new PCA()
.setInputCol("features")
.setOutputCol("pcaFeatures")
.setK(3)
.fit(df)
设置输入输出列,其中 K=3 代表最终保留重要性前3个特征。
3.数据降维
//打印结果
val result = pca.transform(df).select("pcaFeatures")
result.show(false)
println("特征矩阵")
println(pca.pc)
println("解释性方差")
println(pca.explainedVariance)
spark.stop()
原始矩阵 3x5 的5维度数据,降维后得到 3x3 的3维度数据:
其中特征向量矩阵为与解释性方差如下,维度 5x3:
可以看到前三个特征值累加达到了 99%+,能够描述大部分数据信息。
四.总结
SVD 和 PCA 是目前 Spark ML 库里常见的数据降维方法。他们为大数据的数据位数过多、噪声过多提供了相应的解决方法,提高了大数据算法的运行效率。根据算法特性可知二者均为无监督降维。此外,降维的方法还有很多,包括非线性降维、监督和半监督降维,大家可以基于实际场景选择最佳的降维方式。