欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PCA原理解析及应用指南(pyspqrk版)

程序员文章站 2022-04-18 20:58:23
...

PCA原理解析及应用指南(pyspqrk版)

之前虽然也用过PCA方法来降维,但只注重代码,没有注重原理,趁这次研究唐老师论文《企业特征和中国股市》的机会,深入研究下这个经典降维方法的前世今生。

一、协方差矩阵是什么

要理解PCA,需要理解的第一个概念就是:协方差

协方差可以从方差来理解,方差考察的是每个样本的值与所有样本均值的相关性,而协方差既是站在不同维度上,考察两个不同维度样本的相关性。

比如对于x,y,z三个特征,其协方差矩阵为:

 cov(x,x)  cov(x,y)  cov(x,z)

 cov(y,x)  cov(y,y)  cov(y,z)

 cov(z,x)  cov(z,y)  cov(z,z)

从这个矩阵可以看出,协方差矩阵的每个元素考察的都是对应的两个维度数值之间的相关性,并且,协方差矩阵是对称的。

PCA法的主要逻辑

首先,一句话总结PCA想做的事:既是想从现有所有特征中,提炼出其中公共的成分,生成了一个新的特征,这个特征可以最大程度还原原来特征;

比如当只有两个特征x,y时,将特征x作为x轴,特征y作为y轴,可以得到以下点集:

PCA原理解析及应用指南(pyspqrk版)

 

PCA法相当于是从(x,y)的点集中找到这样一条直线:

这条直线要满足所有点到直线的垂直距离之和最小(还原误差尽量小),且投影点在直线上的分布足够广(方差尽量大,既是点离中心的距离尽量广,这样就可以尽量照顾所有特征),如下图既是要找的最优直线:

PCA原理解析及应用指南(pyspqrk版)

 

关于这句话的几点补充:

1)、投影点分布越广,这条轴线的方差就越大(既是最大信噪比)

2)、最终这条直线可以被确定为w1x+w2y,既是一个新特征了

3)、最终x,y两个特征,就被降维到这个新特征w1x+w2y

三、PCA与矩阵特征向量

如上面所言,要找的这条直线是方差尽量大的方向,这句话也可以理解为是找到特征值大的特征向量的方向。所以PCA法的具体处理流程既是下面的步骤:

1、设样本数据为n*m矩阵,设为矩阵A,首先计算出样本的协方差矩阵(m*m)

2、然后求出用k个特征向量表示的矩阵B(m*k),k小于等于m,求方阵特征向量的方法很简单,求非方阵的特征向量,需要用SVD(奇异值分解)法,参考文章是:https://blog.csdn.net/qq_34662278/article/details/85221254

3、最后用原始样本 A * B得到PCA结果矩阵C(n*k)

四、PCA法实例验证

1、输入样本:

[(Vectors.sparse(5, [(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]),)]

2、处理程序

from pyspark.ml.feature import PCA
from pyspark.ml.linalg import Vectors
from pyspark import SparkContext
from pyspark.sql import HiveContext
sc = SparkContext.getOrCreate()
spark = HiveContext(sc)
data = [(Vectors.sparse(5, [(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]),)]
# 原始数据是一个 3*5 的矩阵,设这个矩阵为A
df = spark.createDataFrame(data, ["features"])
pca = PCA(k=1, inputCol="features", outputCol="pcaFeatures")
# 这里的k表示原来矩阵的协方差矩阵的特征向量的个数,因为原来矩阵只有五个维度,所以这个k值要小于等于5
# 已经试过k=6会报错
# 当k=2时,会生成一个5*的特征向量组成的矩阵B
# 然后原来的矩阵A和协方差矩阵的特征向量矩阵相乘 A*B,得到一个新的输出C:3*k
# C既是A的主成分,也即是C可以用来表示A,而且还把A降维了
model = pca.fit(df)
result = model.transform(df).select("pcaFeatures")
result.show(truncate=False)

PCA方法的几个参数:

k:既是表示k个特征向量,也是最终输出的维度

InputCol:输入样本名称

OutputCol:输出样本名称

3、最终输出

pcaFeatures

1.6485728230883807

-4.645104331781534

-6.428880535676489

可以看到最终的输出只有一个维度,这都是k值的作用,也即是原来的五个维度的特征,现在用一个新的维度表示即可。