一·核心部分
1解决的问题:应对高维数据带来的计算量大、冗余信息多、易出现过拟合等问题,在减少数据维度的同时尽可能保留原始数据的关键信息。
2核心思想:从高维数据中提取少数几个主成分,这些主成分是原始特征的线性组合,能最大程度保留数据方差(信息)且相互正交(无关联),以此实现降维。
3关键概念:包括主成分(原始特征的线性组合,用于替代高维特征)、方差(衡量数据信息多少的指标,主成分需最大化方差)、正交性(主成分之间互不相关,避免信息重复)。
二·原理加推导
数学概念
(1)内积:
A与B的内积:A⋅B=∣A∣∣B∣cos(α)
sqrt就是根号
- 假设向量B的模等于1,即(|B| = 1),此时A到B的投影变成了:(A · B = |A| cos(α))
(2)
对于多维的
基变换的含义:
- 两个矩阵相乘的意义是将右边矩阵中的每一列列向量变换到左边矩阵中每一行行向量为基所表示的空间中去。
- 抽象地说,一个矩阵可以表示一种线性变换。
卷积
黄色填充和卷积核两个矩阵相乘,空间发生了变换,
如何降维
在求积y1 y2求最大方差
如何求最大方差
问题变为:
寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大。(对于二维变一维来说)
方案:找到方差次大
讨论:就是关于方差次大与方差最大的关系是怎样的|答案:线性无关(两条线是垂直的关系)如果是交叉不是90垂直就是线性有关
协方差:
表征两个字段之间的相关性。
当协方差为 0 时,表示两个字段完全独立。
目标:
利用协方差为 0,选择另一组基,这组基的方向一定与第一组基正交。
推广:
将一组 N 维向量降为 K 维(K 大于 0,小于 N),其目标是选择 K 个单位(模为 1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为 0,而字段的方差则尽可能大(在正交的约束下,取最大的 K 个方差)
终极目标:
找到一组合的基。
注:降维是指降维的x的特征值
协方差矩阵:
假设我们有 a,b 两个字段,组成矩阵:X
用 X 乘以其转置,并乘以 1/m:
对角线是方差,反对角线是协方差
推广:
对于更高维度的数据,上述结论依然成立。
找到一组合适的基。
方差:
协方差:
目标:
除主对角线上的元素外,都为 0,并且方差从大到小排列。也就是协方差是0
终极目标:
找到一组合适的基。
协方差矩阵对角化:
寻找一个矩阵 P,满足是一个对角矩阵,并且对角元素按从大到小依次排列,那么 P 的前 K 行就是要寻找的基,用 P 的前 K 行组成的矩阵乘以 X 就使得 X 从 N 维降到了 K 维并满足上述优化条件。
原始数据: X —> 协方差矩阵: C
一组基按行组成的矩阵: P
基变换后的数据: Y—> 协方差矩阵: D
隐含信息: Y = PX
PCA 中的数学
协方差矩阵 C 对角化:
实对称矩阵特性:
终极目标:
找到一组合适的基。
实对称矩阵:矩阵转置等于其本身
对角化:除主对角线之外其余元素均为 0
实对称矩阵必可对角化
PCA 中的数学
终极目标找到:
P 是协方差矩阵 C 的特征向量单位化后按行排列出的矩阵,其中每一行都是 C 的一个特征向量。
1. 执行第一步与第二步:
a b c d e
2. 计算协方差矩阵:
3. 计算协方差矩阵的特征值与特征向量:
4. 矩阵P
对角化验证:
5. 降维
优点:
1. 计算方法简单,容易实现。
2. 可以减少指标筛选的工作量。
3. 消除变量间的多重共线性。
4. 在一定程度上能减少噪声数据。
缺点:
1. 特征必须是连续型变量。
2. 无法解释降维后的数据是什么。
3. 贡献率小的成分有可能更重要。
三·参数
sklearn.decomposition.PCA PCA(n_components=None, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None)[source]
n_components:这个参数可以帮我们指定希望 PCA 降维后的特征维度数目。简单来说:指定整数,表示要降维到的目标,【比如 10 维的数据,指定 n_components=5,表示将 10 维数据降维到 5 维】如果为小数,表示累计方差百分比。0.9
copy:类型:bool,True 或者 False,缺省时默认为 True。 意义:表示是否在运行算法时,将原始训练数据复制一份。若为 True,则运行 PCA 算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为 False,则运行 PCA 算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。 【按默认为 True】
whiten:判断是否进行白化。所谓白化,就是对降维后的数据的每个特征进行归一化,让方差都为 1.对于 PCA 降维本身来说,一般不需要白化。如果你 PCA 降维后有后续的数据处理动作,可以考虑白化。默认值是 False,即不进行白化。
svd_solver:即指定奇异值分解 SVD 的方法,由于特征分解是奇异值分解 SVD 的一个特例,一般的 PCA 库都是基于 SVD 实现的。有 4 个可以选择的值:{ 'auto', 'full', 'arpack', 'randomized' }。randomized 一般适用于数据量大,数据维度多同时主成分数目比例又较低的 PCA 降维,它使用了一些加快 SVD 的随机算法。full 则是传统意义上的 SVD,使用了 scipy 库对应的实现。arpack 和 randomized 的适用场景类似,区别是 randomized 使用的是 scikit-learn 自己的 SVD 实现,而 arpack 直接使用了 scipy 库的 sparse SVD 实现。默认是 auto,即
PCA 类会自己去在前面讲到的三种算法里面去权衡,选择一个合适的 SVD 算法来降维。一般来说,使用默认值就够了。【按默认设置即可】
Attributes 属性:
components_:array, shape (n_components, n_features) 指表示主成分系数矩阵
explained_variance_:降维后的各主成分的方差值。方差值越大,则说明越是重要的主成分。
explained_variance_ratio_:降维后的各主成分的方差值占总方差值的比例,这个比例越大,则越是重要的主成分。【一般看比例即可 >90%】
3、PCA 对象的方法
- fit (X,y=None)
fit () 可以说是 scikit-learn 中通用的方法,每个需要训练的算法都会有 fit () 方法,它其实就是算法中的 “训练” 这一步骤。因为 PCA 是无监督学习算法,此处 y 自然等于 None。
fit (X),表示用数据 X 来训练 PCA 模型。
函数返回值:调用 fit 方法的对象本身。比如 pca.fit (X),表示用 X 对 pca 这个对象进行训练。
代码
from sklearn.decomposition import PCA
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report# 数据读取(CSV格式)
data = pd.read_csv("creditcard.csv")# 数据划分(特征X和标签y)
X = data.iloc[:, :-1]
y = data.iloc[:, -1]# ---------------------- PCA降维处理 ----------------------
# 实例化PCA对象(保留90%的方差)
pca = PCA(n_components=0.90)
pca.fit(X) # 训练PCA模型# 输出PCA相关信息
print("=== PCA降维信息 ===")
print(f"保留的主成分数量: {pca.n_components_}")
print(f"解释的方差占比总和: {sum(pca.explained_variance_ratio_):.4f}")
print("各主成分解释的方差占比:", pca.explained_variance_ratio_)# 对数据进行降维转换
new_x = pca.transform(X)# 划分降维后的训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(new_x, y, test_size=0.2, random_state=0
)# 训练逻辑回归模型(手动设置class_weight处理类别不平衡)
classifier_pca = LogisticRegression(max_iter=1000,class_weight='balanced' # 自动调整类别权重,提升少数类召回率
)
classifier_pca.fit(x_train, y_train)# 预测
train_pred_pca = classifier_pca.predict(x_train)
test_pred_pca = classifier_pca.predict(x_test)# 输出分类报告(包含召回率等指标)
print("\n=== PCA降维后 - 训练集分类报告 ===")
print(classification_report(y_train, train_pred_pca)) # 训练集表现print("=== PCA降维后 - 测试集分类报告 ===")
print(classification_report(y_test, test_pred_pca)) # 测试集表现# ---------------------- 不使用PCA降维 ----------------------
# 直接划分原始数据
x_train_no_pca, x_test_no_pca, y_train_no_pca, y_test_no_pca = train_test_split(X, y, test_size=0.2, random_state=0
)# 训练逻辑回归模型(不降维,同样设置class_weight)
classifier_no_pca = LogisticRegression(max_iter=1000,class_weight='balanced'
)
classifier_no_pca.fit(x_train_no_pca, y_train_no_pca)# 预测
train_pred_no_pca = classifier_no_pca.predict(x_train_no_pca)
test_pred_no_pca = classifier_no_pca.predict(x_test_no_pca)# 输出分类报告
print("\n=== 不使用PCA - 训练集分类报告 ===")
print(classification_report(y_train_no_pca, train_pred_no_pca))print("=== 不使用PCA - 测试集分类报告 ===")
print(classification_report(y_test_no_pca, test_pred_no_pca))
1. 导入所需库
python
运行
from sklearn.decomposition import PCA # 导入PCA降维工具
import pandas as pd # 数据处理库
from sklearn.model_selection import train_test_split # 数据拆分工具
from sklearn.linear_model import LogisticRegression # 逻辑回归模型
from sklearn.metrics import classification_report # 分类评估报告工具
2. 数据读取与划分
python
运行
# 读取CSV格式的信用卡数据
data = pd.read_csv("creditcard.csv")# 划分特征X和标签y(假设最后一列是目标变量,即是否欺诈)
X = data.iloc[:, :-1] # 取所有行,除最后一列外的所有列作为特征
y = data.iloc[:, -1] # 取所有行的最后一列作为标签
3. PCA 降维处理部分
python
运行
# 实例化PCA对象,设置保留90%的方差(即降维后保留原数据90%的信息)
pca = PCA(n_components=0.90)
pca.fit(X) # 用原始特征数据训练PCA模型,学习主成分# 输出PCA降维的相关信息
print("=== PCA降维信息 ===")
print(f"保留的主成分数量: {pca.n_components_}") # 实际保留的主成分个数
print(f"解释的方差占比总和: {sum(pca.explained_variance_ratio_):.4f}") # 总方差保留比例
print("各主成分解释的方差占比:", pca.explained_variance_ratio_) # 每个主成分的方差占比# 对原始特征数据进行降维转换,得到新的低维特征
new_x = pca.transform(X)
4. 降维后的数据建模与评估
python
运行
# 将降维后的数据集拆分为训练集(80%)和测试集(20%),固定随机种子保证结果可复现
x_train, x_test, y_train, y_test = train_test_split(new_x, y, test_size=0.2, random_state=0
)# 初始化逻辑回归模型,设置最大迭代次数为1000(确保收敛)
# class_weight='balanced'用于处理类别不平衡问题(信用卡欺诈数据中欺诈样本通常很少)
classifier_pca = LogisticRegression(max_iter=1000,class_weight='balanced'
)
classifier_pca.fit(x_train, y_train) # 用降维后的训练集训练模型# 分别对训练集和测试集进行预测
train_pred_pca = classifier_pca.predict(x_train)
test_pred_pca = classifier_pca.predict(x_test)# 输出分类报告,包含精确率、召回率、F1分数等指标,评估模型表现
print("\n=== PCA降维后 - 训练集分类报告 ===")
print(classification_report(y_train, train_pred_pca))
print("=== PCA降维后 - 测试集分类报告 ===")
print(classification_report(y_test, test_pred_pca))
5. 不使用 PCA 降维的对比实验
python
运行
# 直接对原始特征数据进行拆分,参数与前面保持一致,确保对比公平
x_train_no_pca, x_test_no_pca, y_train_no_pca, y_test_no_pca = train_test_split(X, y, test_size=0.2, random_state=0
)# 初始化另一个逻辑回归模型,参数与降维实验保持一致
classifier_no_pca = LogisticRegression(max_iter=1000,class_weight='balanced'
)
classifier_no_pca.fit(x_train_no_pca, y_train_no_pca) # 用原始特征训练模型# 分别对训练集和测试集进行预测
train_pred_no_pca = classifier_no_pca.predict(x_train_no_pca)
test_pred_no_pca = classifier_no_pca.predict(x_test_no_pca)# 输出分类报告,与降维后的结果进行对比
print("\n=== 不使用PCA - 训练集分类报告 ===")
print(classification_report(y_train_no_pca, train_pred_no_pca))
print("=== 不使用PCA - 测试集分类报告 ===")
print(classification_report(y_test_no_pca, test_pred_no_pca))
代码的主要目的
通过对比使用 PCA 降维和不使用 PCA 降维两种情况下,逻辑回归模型的分类效果,来验证 PCA 降维是否能在减少特征维度(简化模型、提高运算效率)的同时,保持较好的模型性能。
在信用卡欺诈检测这类场景中,PCA 的价值通常体现在:
- 减少特征数量,加快模型训练和预测速度
- 去除噪声和冗余信息,可能提升模型泛化能力
- 缓解维度灾难问题
通过观察两个分类报告的各项指标(尤其是测试集的召回率,在欺诈检测中很重要),可以判断 PCA 降维是否达到了预期效果。