PCA 适用场景和流程说明。

PCA 是一种通过分解特征矩阵来降维的方法。主要适用的应用场景如下:

  • 非监督式类型的数据集。它是一种非监督式的降维方法,因此适用于不带有标签的数据集;而对于带有标签的数据集则可以采用 LDA;
  • 根据方差自主控制特征数量。最大的主成分的数量≤特征的数量,这意味着,PCA也可以输出数量完全相同的特征,具体取决于选择特征中解释的方差比例;
  • 数据量较大的数据集。数据量大包括数据记录多和数据维度多两种情况,PCA 对大型数据集的处理效率较高。

PCA 的实现流程

  1. 按照数据集的 n 维特征矩阵,输入原数据,结构维(m,n),找出原本 n 个特征向量构成的 n 维空间 V;
  2. 决定降维后的特征数量 k;
  3. 通过找一组相互正交的坐标轴,找出 n 个新的特征向量,以及他们构成的新 n 维空间 V;
  4. 找出原始数据在新特征空间 V 中的 n 个新特征向量上对应的值,即“将数据映射到新空间中”;
  5. 选取前 k 个信息量最大的特征,删掉没有被选中的特征,成功将 n 维空间降为 k 维。

流程中的关键是需要决定降维的特征数量 k,以及找到一组相互正交的坐标轴。这里涉及的数理知识有部分细节我还不太清楚。数理推导建议可以看这部分如何理解主元分析(PCA)?

从方差过滤中知道,如果一个特征的方差很小,则意味着这个 特征上很可能有大量取值都相同(比如90%都是1,只有10%是0,甚至100%是1),那这一个特征的取值对样本来说就没有区分度,这种特征就不带有有效信息。也就是说方差越大,特征上带有的信息量越大。因此,在降维中,PCA 使用的信息量衡量指标,就是样本方差。计算公式为:
image.png
Var表示一个特征的方差,n 代表样本量,代表一个特征中的每个样本取值,代表这一列样本的均值。

PCA Python使用

1
2
# pca参数
class sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None)

主要说下 n_components 参数。这个参数可以指定 PCA 降维后期望的特征维度数目。常规来说,要想先看看数据的散点图分布,可以 n_components=2,之前《使用 PCA 降维可视化,了解数据特征分布》有演示。

这里有 2 种方式,第 1 种是指定主成分的方差和所占的最小比例阈值,让 PCA 类根据样本特征方差来决定降维到的维度数,此时n_components 是一个(0,1]之间的数;并且让参数svd_solver ==’full’。比如说,如果我们希望保留 97% 的信息量,就可以输入n_components = 0.97,PCA会自动选出能够让保留的信息量超过97%的特征数量。第 2 种就是文章开始说的方差衡量指标pca_line.explained_variance_ratio_ ,用来查看降维后每个新特征向量所占信息量占原始数据总信息量的百分比。又叫做可解释方差贡献率。

代码演示:

1
2
3
4
5
#导入相关库
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
plt.rcParams['font.family'] = ['Arial Unicode MS']
1
2
3
4
5
#获取skearn库鸢尾花数据集,鸢尾花四维数组
iris = load_iris()
y = iris.target
X = iris.data
X[0:5]
1
2
3
4
5
array([[5.1, 3.5, 1.4, 0.2],
[4.9, 3. , 1.4, 0.2],
[4.7, 3.2, 1.3, 0.2],
[4.6, 3.1, 1.5, 0.2],
[5. , 3.6, 1.4, 0.2]])
1
2
3
4
5
#调用PCA
pca = PCA(n_components=2)
pca = pca.fit(X)
X_dr = pca.transform(X)
X_dr[0:5]
1
2
3
4
5
array([[-2.68412563,  0.31939725],
[-2.71414169, -0.17700123],
[-2.88899057, -0.14494943],
[-2.74534286, -0.31829898],
[-2.72871654, 0.32675451]])
1
2
3
4
5
6
7
8
9
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("降维后特征数量")
plt.ylabel("可解释方差贡献率")
plt.show()

output_3_0.png

累积可解释方差贡献率曲线是一条以降维后保留的特征个数为横坐标,降维后新特征矩阵捕捉到的可解释方差贡献 率为纵坐标的曲线。图中表示 4 个特征是 100%,2 个特征大概在 98%。

1
2
3
4
5
# 保留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_
1
array([0.92461872, 0.05306648])