【数学建模】主成分分析(PCA)详解:从理论到实践的全面指南
【数学建模】主成分分析(PCA)详解:从理论到实践的全面指南
在数据科学和经济学研究中,我们常面临高维数据(如各省市的GDP、消费水平、固定资产投资等指标)的分析难题。高维数据不仅增加了计算复杂度,还可能存在多重共线性和信息冗余。主成分分析(PCA)通过降维技术,将多个相关变量转化为少数几个独立的主成分,保留数据核心信息,简化分析流程。例如,通过PCA可从20个经济指标中提取4个主成分,解释85%以上的原始数据方差,助力决策者快速识别区域经济差异。
主成分分析(PCA)
1.1 概念
PCA(Principal Components Analysis)即主成分分析技术[1],又称主分量分析,旨在利用降维的思想,把多指标转化为少数几个综合指标。在统计学中,主成分分析PCA是一种简化数据集的技术。它是一个线性变换。这个变换把数据变换到一个新的坐标系统中,使得任何数据投影的第一大方差在第一个坐标(称为第一主成分)上,第二大方差在第二个坐标(第二主成分)上,依次类推。主成分分析经常用于减少数据集的维数,同时保持数据集的对方差贡献最大的特征。这是通过保留低阶主成分,忽略高阶主成分做到的。这样低阶成分往往能够保留住数据的最重要方面。但是,这也不是一定的,要视具体应用而定。
1.2 应用场景
- 数据降维:通过正交变换保留高方差主成分,将高维数据映射至低维空间,实现信息高效浓缩,便于可视化,理解数据特征。
- 噪声消除:剔除低方差主成分(通常为尾部成分),过滤噪声与冗余信息,保留数据核心特征。
- 多重共线性消除:当多个特征之间存在较高的相关性时,生成不相关的主成分,解决共线性问题,增强模型鲁棒性。
1.3 使用条件
任何方法都有适用条件,PCA也不例外。
- 异常值考虑:PCA基于数据的方差和协方差来确定主成分的方向。异常值会极大地影响数据的方差和协方差结构,导致主成分方向偏移,无法准确反映数据的真实结构。
- 线性程度检验(二选一即可):
- KMO检验:KMO值需 > 0.6(0.8-0.9为理想范围)。
- Bartlett球形检验:需拒绝原假设(P值<0.05),表明变量间存在显著相关性。
注意事项:PCA适合处理线性结构数据,若数据存在复杂非线性关系,需结合核方法(Kernel PCA)或者考虑使用t-SNE等降维方法。
数学原理
- 1、假设有 n 个样本,m 个指标,则可构成大小为 n × n 的样本矩阵 x:
$$
\mathbf{x} = \begin{bmatrix}
x_{11} & x_{12} & \cdots & x_{1m} \
x_{21} & x_{22} & \cdots & x_{2m} \
\vdots & \vdots & \ddots & \vdots \
x_{n1} & x_{n2} & \cdots & x_{nm}
\end{bmatrix} = (\mathbf{x}_1, \mathbf{x}_2, \cdots, \mathbf{x}_m )
$$
2、对数据进行列标准化后,求协方差矩阵:
标准化
按列计算均值:
$$
\bar{x}j = \frac{1}{n} \sum{i=1}^{n} x_{ij},
$$
标准差:
$$
S_j = \sqrt{\frac{\sum_{i=1}^{n} (x_{ij} - \bar{x}_j)^2}{n-1}}
$$
标准化数据:
$$
X_{ij} = \frac{x_{ij} - \bar{x}_j}{S_j}
$$
公式原始样本矩阵经过标准化变化:
$$
\mathbf{X} = \begin{bmatrix}
X_{11} & X_{12} & \cdots & X_{1n} \
X_{21} & X_{22} & \cdots & X_{2m} \
\vdots & \vdots & \ddots & \vdots \
X_{n1} & X_{n2} & \cdots & X_{nm}
\end{bmatrix} = (\mathbf{X}_1, \mathbf{X}_2, \cdots, \mathbf{X}_m)
$$
- 计算协方差
计算标准化样本的协方差矩阵:
$$
\mathbf{R} = \begin{bmatrix}
r_{11} & r_{12} & \cdots & r_{1m} \
r_{21} & r_{22} & \cdots & r_{2m} \
\vdots & \vdots & \ddots & \vdots \
r_{m1} & r_{m2} & \cdots & r_{mm}
\end{bmatrix}
$$
$$
r_{ij} = \frac{1}{n-1} \sum_{k=1}^{n} (X_{ki} - \bar{X}i)(X{kj} - \bar{X}j) = \frac{1}{n-1} \sum{k=1}^{n} X_{ki} X_{kj}
$$
也可以直接计算:
$$
\mathbf{R} = \frac{\sum_{k=1}^{n} (x_{ki} - \bar{x}i)(x{kj} - \bar{x}j)}{\sqrt{\sum{k=1}^{n} (x_{ki} - \bar{x}i)^2 \sum{k=1}^{n} (x_{kj} - \bar{x}_j)^2}}
$$
3、计算 R 的特征值和特征值向量:
特征值
$$
\lambda_1 \geq \lambda_2 \geq \cdots \geq \lambda_p \geq 0,
$$
R 是半正定矩阵,且
$$
\text{tr}(\mathbf{R}) = \sum_{k=1}^{p} \lambda_k = p
$$
表示矩阵的迹等于其特征值之和,且这个和等于 p。
R是一个半正定矩阵,其特征值不可能为负。
特征向量:
$$
\text{特征向量:} \mathbf{a}1 = \begin{bmatrix}
a{11} \
a_{21} \
\vdots \
a_{p1}
\end{bmatrix}, \mathbf{a}2 = \begin{bmatrix}
a{12} \
a_{22} \
\vdots \
a_{p2}
\end{bmatrix}, \cdots, \mathbf{a}p = \begin{bmatrix}
a{1p} \
a_{2p} \
\vdots \
a_{pp}
\end{bmatrix}
$$
- 4、计算主成分贡献率率以及累计贡献率:
贡献率
$$
\text{贡献率} = \frac{\lambda_i}{\sum_{k=1}^{p} \lambda_k}
$$
累加贡献率
$$
\text{累加贡献率} = \frac{\sum_{k=1}^{i} \lambda_k}{\sum_{k=1}^{p} \lambda_k}, \quad (i = 1, 2, \cdots, p)
$$
注意:相关系数是协方差的标准化形式,用于消除量纲的影响。
- 5、写出主成分:
一般取累计贡献率超过 90% 的特征值所对应的第一、第二、…、第 m(m ≤ p )个主成分。
第 i 个主成分:
$$
\text{第 } i \text{ 个主成分:} F_i = a_{1i} X_1 + a_{2i} X_2 + \cdots + a_{pi} X_p
$$
案例分析
本文以各省市自治区经济发展数据如下图作为案例,分析PCA降维方法的使用。为方便复现结尾提供了数据下载链接。
3.1 结果展示
3.1.1 使用python计算代码过程
检验结果和协方差矩阵展示,运行第一个代码块即可得到结果
主成分分析后的结果展示,运行代码块2后可以得到
3.2 代码展示
3.2.1 使用python计算代码过程代码展示
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
from factor_analyzer.factor_analyzer import calculate_kmo
from sklearn.preprocessing import StandardScaler
# 读取数据
data = pd.read_excel('./data/表1 各省市自治区经济发展数据.xlsx')
data.dropna(inplace=True)
data
# 数据预处理
data = data.drop(['Unnamed: 0'], axis=1)
# 适合性检验(Bartlett && KMO
df_check = data
# Bartlett 球状检验
chi_square_value, p_value = calculate_bartlett_sphericity(df_check)
print("Bartlett=", chi_square_value, p_value)
# KMO检验(>0.6为好,越靠近1越好)
kmo_all, kmo_model = calculate_kmo(df_check)
print("KMO=", kmo_all)
# 主成分分析
#标准化
data = data.apply(lambda x: (x - x.mean()) / x.std(), axis=0)
scaler=StandardScaler()
nor_data=scaler.fit_transform(data)
#相关系数矩阵
nor_data= pd.DataFrame(nor_data)
nor_cor_data=nor_data.corr()
nor_cor_data
#求相关系数矩阵的特征值和特征向量
nor_cor_data=nor_cor_data.values
featValue, featVec= np.linalg.eig(nor_cor_data.T) #求解系数相关矩阵的特征值和特征向量
featValue, featVec
#对特征值进行排序
featValue = sorted(featValue)[::-1]
print('特征值',featValue)
#求特征值的贡献度
print(np.sum(featValue))
gx = featValue/np.sum(featValue)
print('贡献度',gx)
#求特征值的累计贡献度
lg = np.cumsum(gx)
print('累计贡献度',lg)
#选出主成分
#设置阈值
line=0.95
k=[i for i in range(len(lg)) if lg[i]<=line]
k = list(k)
print('选择主成分的索引',k)
#选出主成分对应的特征向量矩阵
selectVec = np.matrix(featVec.T[k]).T
selectVec=selectVec*(-1)
print('选择主成分的特征向量矩阵',selectVec)
#求主成分的得分
finalData = np.dot(nor_data,selectVec)
print('主成分得分',finalData)
3.2.2 使用sklearn库代码简化过程
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# 读取数据
data = pd.read_excel('./data/表1 各省市自治区经济发展数据.xlsx')
data.dropna(inplace=True)
# 数据预处理
data = data.drop(['Unnamed: 0'], axis=1)
# 标准化
scaler = StandardScaler()
nor_data = scaler.fit_transform(data)
# 主成分分析
pca = PCA()
pca.fit(nor_data)
# 输出结果
print("特征值:", pca.explained_variance_)
print("贡献度:", pca.explained_variance_ratio_)
print("累计贡献度:", pca.explained_variance_ratio_.cumsum())
# 选择主成分(假设选择累计贡献度达到 95% 的主成分)
line = 0.95
k = [i for i, cum_var in enumerate(pca.explained_variance_ratio_.cumsum()) if cum_var <= line]
print("选择主成分的索引:", k)
# 获取主成分的特征向量
selectVec = pca.components_[:len(k)]
print("选择主成分的特征向量矩阵:\n", selectVec)
# 计算主成分得分
finalData = pca.transform(nor_data)[:, :len(k)]
print("主成分得分:\n", finalData)
参考链接
[1]pca技术_百度百科;
清风数学建模学习笔记——主成分分析(PCA)原理详解及案例分析_x10为生均教育经费对以上指标数据做主成分分析,并提取主成分-CSDN博客
各省市自治区经济发展数据
本文原文来自CSDN博客