介绍
在数据科学和机器学习领域,数据降维是一个至关重要的步骤,尤其是在处理具有大量特征的高维数据集时。主成分分析(PCA)作为一种经典的线性降维方法,能够有效地减少数据的维度,同时保留数据集中最重要的信息。本文将从PCA的基本原理出发,探讨其在数据分析中的应用,并提供Python实现的 示例
步骤原理
该部分主要从数学原理方面介绍PCA的基本步骤,内容可能较为枯燥,但对理解这一方法有着一定的帮助。PCA 的核心思想是通过线性变换,将原始数据投影到一组新的正交基向量上。这些基向量被称为主成分,每个主成分代表原始数据在某个方向上的最大方差。 主要包括5个步骤:
- 数据标准化:将数据中心化,使每个特征的均值为 0,标准差为 1。
- 计算协方差矩阵:计算标准化数据的协方差矩阵,以衡量不同特征之间的相关性。
- 特征值分解:对协方差矩阵进行特征值分解,得到特征值和特征向量。
- 选择主成分:根据特征值的大小选择前 k 个特征向量,这些向量对应的特征值最大,代表数据中最多的变异信息。
- 数据投影:将原始数据投影到选择的主成分上,得到降维后的数据。
1.标准化
数据标准化对于了解统计学这方面知识的小伙伴来说已经十分熟悉了,就是对数据的一个归纳操作,消除指标间不同量纲造成的影响。标准化的方法有很多,诸如利用标准差、极值等等。我一般比较喜欢用极值(毕竟计算简单)。
对于正向指标:
Y
i
j
=
x
i
j
−
m
i
n
(
x
i
)
m
a
x
(
x
i
−
m
i
n
(
x
i
)
)
Y_{ij}=\frac{x_{ij}-min(x_{i})}{max(x_{i}-min(x_{i}))}
Yij=max(xi−min(xi))xij−min(xi)
对于负向指标:
Y
i
j
=
m
a
x
(
x
i
)
x
i
j
m
a
x
(
x
i
−
m
i
n
(
x
i
)
)
Y_{ij}=\frac{max(x_{i})x_{ij}}{max(x_{i}-min(x_{i}))}
Yij=max(xi−min(xi))max(xi)xij
最后便得到一个数值全部在0~1的数据矩阵Y,每一列代表一个指标,每一行代表一组观测值。
2.计算协方差矩阵
协方差矩阵是PCA的核心部分,表现出了指标两两间的关系。
对于特征i和特征j,协方差
σ
i
j
=
1
n
−
1
∑
k
=
1
n
(
x
k
i
−
x
ˉ
i
)
(
x
k
j
−
x
ˉ
j
)
\sigma_{ij}=\frac{1}{n-1}\sum_{k=1}^{n}(x_{ki}-\bar{x}_{i})(x_{kj}-\bar{x}_{j})
σij=n−11∑k=1n(xki−xˉi)(xkj−xˉj)
对每两个指标都按照这个公式重复计算,最终得到一个协方差矩阵。很明显对于
σ
i
i
\sigma_{ii}
σii这样位置的协方差 实际就是该指标的方差。
3.特征值特征向量求解
当然,这里是特征值计算步骤的描述,公式部分使用LaTeX源码,不包含渲染后的公式:
- 确定特征方程:首先,我们构建特征方程,它是通过将矩阵
A
A
A与特征向量
v
\mathbf{v}
v相乘,然后减去特征值
λ
\lambda
λ 乘以单位矩阵
I
I
I 与
v
\mathbf{v}
v 的乘积得到的。这个方程可以表示为:
A v − λ I v = 0 A\mathbf{v} - \lambda I \mathbf{v} = 0 Av−λIv=0 - 简化特征方程:将上述方程重写为:
( A − λ I ) v = 0 (A - \lambda I)\mathbf{v} = 0 (A−λI)v=0
由于 v \mathbf{v} v 不是零向量,我们可以得出:
det ( A − λ I ) = 0 \det(A - \lambda I) = 0 det(A−λI)=0 - 求解特征值:求解上述特征多项式方程,找到所有可能的 λ \lambda λ值。这些值就是矩阵 A A A的特征值。
- 求解特征向量:对于每个求得的特征值 λ \lambda λ,将其代入 ( A − λ I ) v = 0 (A - \lambda I)\mathbf{v} = 0 (A−λI)v=0 并求解 v \mathbf{v} v,得到对应的特征向量。
4.主成分选择
主成分选择是主成分分析(PCA)中的一个关键步骤,它涉及到根据特征值的大小来决定哪些主成分应该被保留。以下是主成分选择的步骤,其中公式部分使用LaTeX源码:
-
排序特征值:在计算得到特征值后,将特征值按照从大到小的顺序进行排序。对应的特征向量也应该相应地排序。
Λ sorted = [ λ π ( 1 ) 0 ⋯ 0 0 λ π ( 2 ) ⋯ 0 ⋮ ⋮ ⋱ ⋮ 0 0 ⋯ λ π ( n ) ] \Lambda_{\text{sorted}} = \begin{bmatrix} \lambda_{\pi(1)} & 0 & \cdots & 0 \\ 0 & \lambda_{\pi(2)} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \lambda_{\pi(n)} \end{bmatrix} Λsorted= λπ(1)0⋮00λπ(2)⋮0⋯⋯⋱⋯00⋮λπ(n) -
解释方差:计算每个特征值占总方差的百分比,这可以通过以下公式来实现:
方差解释比例 = λ i ∑ j = 1 n λ j × 100 % \text{方差解释比例} = \frac{\lambda_i}{\sum_{j=1}^{n} \lambda_j} \times 100\% 方差解释比例=∑j=1nλjλi×100%
其中, λ i \lambda_i λi是第 i i i个特征值, n n n是特征值的总数。
-
选择主成分:根据方差解释比例,选择前 k k k 个主成分,这些主成分通常解释了大部分的方差。选择 k k k的标准可以是:
- 达到一定的方差解释阈值,例如95%(在实际中一般达到85%就可以了)。
- 根据特征值的“解释力”排序,选择前几个特征值对应的特征向量。
-
构造新的空间:使用选择的主成分的特征向量构造一个新的矩阵 W W W,这个矩阵的每一列是一个主成分的特征向量。
-
转换数据:将原始数据投影到新的空间中,通过以下公式进行转换:
X new = W T X \mathbf{X}_{\text{new}} = W^T \mathbf{X} Xnew=WTX
其中, X \mathbf{X} X是原始数据矩阵, W T W^T WT是特征向量矩阵的转置, X new \mathbf{X}_{\text{new}} Xnew是转换后的数据矩阵。
通过这些步骤,PCA能够将原始数据集转换到一个新的坐标系中,这个新坐标系的轴(即主成分)是按照数据方差的大小排列的,从而实现了数据的降维。降维后的数据集保留了原始数据集中最重要的信息,同时减少了数据的复杂性。
PS:需要注意的是,最终选取的主成分并不是直接从原始指标中选择几个。它的本质是原始指标线性组合出的几个包含总体大部分信息的新的指标。
5.主成分得分
最后一步便是是计算主成分得分,实际上这就是上面的转换数据部分:
- 解释主成分得分:对于转化后的新矩阵,每个得分 x new , i \mathbf{x}_{\text{new},i} xnew,i表示原始数据点在第 i i i个主成分方向上的投影距离。
- 应用主成分得分:主成分得分可以用于后续的分析,比如有时会结合指标权重计算每个目标的综合得分,以用作评价模型。
这个过程是PCA的核心,它允许我们在降低数据复杂性的同时,保留了数据集中的主要信息。主成分得分提供了一种有效的方式来探索和分析数据的内在结构。
实例分析
下面是一个通过python实现的具体案例分析(案例只是供大家练习和深入理解算法,并无实际意义)。
指标名称 | 符号表示 |
---|---|
销售额 | x 1 x_1 x1 |
利润率 | x 2 x_2 x2 |
客户满意度 | x 3 x_3 x3 |
市场份额 | x 4 x_4 x4 |
广告支出 | x 5 x_5 x5 |
员工数量 | x 6 x_6 x6 |
研发投入 | x 7 x_7 x7 |
产品质量评分 | x 8 x_8 x8 |
员工满意度 | x 9 x_9 x9 |
如上一共有9个指标,观测的目标一共有7个,具体数值如下:
观测值 | 指标1 | 指标2 | 指标3 | 指标4 | 指标5 | 指标6 | 指标7 | 指标8 | 指标9 |
---|---|---|---|---|---|---|---|---|---|
观测1 | 120 | 8.5 | 7.5 | 15 | 25 | 50 | 15 | 85 | 8.5 |
观测2 | 150 | 9.0 | 8.0 | 14 | 30 | 55 | 20 | 88 | 9.0 |
观测3 | 130 | 8.0 | 8.5 | 16 | 20 | 60 | 18 | 90 | 8.8 |
观测4 | 160 | 9.5 | 9.0 | 12 | 35 | 65 | 22 | 92 | 9.2 |
观测5 | 180 | 7.0 | 7.0 | 18 | 40 | 70 | 25 | 86 | 7.5 |
观测6 | 200 | 8.0 | 9.0 | 10 | 50 | 80 | 30 | 95 | 9.5 |
观测7 | 170 | 7.5 | 8.5 | 13 | 45 | 75 | 28 | 91 | 8.0 |
代码示例
import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# 观测数据
data = np.array([
[120, 8.5, 7.5, 15, 25, 50, 15, 85, 8.5],
[150, 9.0, 8.0, 14, 30, 55, 20, 88, 9.0],
[130, 8.0, 8.5, 16, 20, 60, 18, 90, 8.8],
[160, 9.5, 9.0, 12, 35, 65, 22, 92, 9.2],
[180, 7.0, 7.0, 18, 40, 70, 25, 86, 7.5],
[200, 8.0, 9.0, 10, 50, 80, 30, 95, 9.5],
[170, 7.5, 8.5, 13, 45, 75, 28, 91, 8.0]
], dtype=np.float64)
# 数据标准化
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
# 执行PCA
pca = PCA()
pca.fit(data_scaled)
# 主成分得分矩阵
scores = pca.transform(data_scaled)
# 方差分析表
explained_variance = pca.explained_variance_ratio_
total_variance = sum(explained_variance)
cumulative_explained_variance = np.cumsum(explained_variance)
# 打印结果
print("主成分得分矩阵 (前两个主成分):")
print(scores[:, :2])
print("\n方差解释比例:")
for i, var in enumerate(explained_variance, 1):
print(f"主成分{i}: {var:.2%}")
print("\n累积方差解释比例:")
for i, cum_var in enumerate(cumulative_explained_variance, 1):
print(f"主成分{i}: {cum_var:.2%}")
# 选择主成分
# 例如,选择累积方差解释比例达到95%的主成分数量
k = np.searchsorted(cumulative_explained_variance, 0.95) + 1
print(f"\n选择的累积方差解释比例达到95%的主成分数量: {k}")
补充:在进行主成分分析前,一般先要对指标间的相关性进行检验,若相关性较低则选择的数据可能不适合用主成分分析进行研究。
常用的方法主要是KMO和Bartlett球形度检验:
KMO的值在0~1之间,越接近于1表示越适合用主成分分析。
- KMO值大于0.9:非常适合PCA。
- KMO值在0.8到0.9之间:适合PCA。
- KMO值在0.7到0.8之间:中等程度适合PCA。
- KMO值在0.6到0.7之间:勉强适合PCA。
- KMO值小于0.6:不适合PCA。
Bartlett检验假设:
- 零假设(H0):相关矩阵与单位矩阵没有显著差异,即变量之间不相关。
- 备择假设(H1):相关矩阵与单位矩阵有显著差异,即变量之间存在相关性。