机器学习算法系列专栏:主成分分析(PCA)降维算法(初学者)

(一)主成分分析(PCA)概念

  • 主成分分析算法:通用的降维工具
  • 降维:数据的特征又叫做数据的维度,减少数据的特征即降维
  • 做到最好的降维效果的方法:减少数据维度的同时 ,能较好地代表原始数据

(二)向量的内积

  • 内积:
  • A与B的内积:A·B=|A| |B|cos(α)
    A:(1,3)
    B:(3,2)
    A·B=sqrt(1+3^2)*sqrt(3^2+2^2)*cos(α)
  • 假设向量B的模等于1,即|B|=1,此时A到B的投影变成了:A·B=|A| cos(α)

(三)pca和随机森林的核心区别

  • 目标不同
    • PCA:无监督降维/压缩,只关心“怎样用最少的维度保留最多的信息”
    • 随机森林:有监督学习,目标是“基于特征预测标签”,可用于分类或回归

  • 标签需求
    • PCA:完全不需要标签 y
    • 随机森林:必须有标签 y 才能训练

  • 特征处理方式
    • PCA:线性变换,把原始特征线性组合成新的正交主成分,特征值可正可负,失去原始业务含义
    • 随机森林:非线性、非参数模型,直接在原始特征空间做划分,保留特征的业务含义,还能给出特征重要性

  • 可解释性
    • PCA:主成分是数学构造,难以直接解释
    • 随机森林:每棵树都是“if-else”规则,能输出特征重要性、局部解释(SHAP、LIME)

  • 输出结果
    • PCA:输出降维后的新特征矩阵,维度 ≤ 原维度
    • 随机森林:输出预测标签或概率,同时可附带特征重要性、OOB误差等

  • 算法类型
    • PCA:矩阵分解/线性代数方法
    • 随机森林:集成学习(Bagging + 决策树)

(三)基

基的概念:

基(也称为基底)是描述、刻画向量空间的基本工具

基的举例:

基:(1,0)T与(0,1)T是二维空间的一组基

(1,0)T就是

向量(3,2)由这一组基完全表示:

向量可以成为基的条件:

任何两个线性无关的二维向量都可以成为一组基

(四)基变换

新的一组基:

将(3,2)映射到新的基上:

由于新的基的模是1,所以直接相乘可得结果

内积的定义:

对于多个二维向量:

对于m个维向量,想将其变换为由R个N维向量表示的新空间中:

基变换的含义:

1.两个矩阵相乘的意义是将右边矩阵中的每一列列向量变换到左边矩阵中每一行行向量为基所表示的空间中去
2.抽象地说,一个矩阵可以表示一种线性变换

关键问题和解决方法:

如何选择基才是最优的?
或者说,如何才能有效地保留较多的原始数据信息
方差最大的方向即为最优基
我们希望投影后投影值尽可能分散,而这种分散程度,可以用数学上的方差来表述

(四)方差

方差公式:

PCA(主成分分析)里最核心的“找主方向”的前置操作:

先把所有数据“搬”到原点(减去均值),再找出一条直线,让数据在这条直线上的分布最“散”(方差最大),这条直线就是 PCA 要找的“主方向”

步骤 1:把每个维度减去该维度的均值
目的:把数据中心化,使数据中心位于原点 (0,0),这样后面算协方差、方差时就不用额外带一个“均值”项,公式更简洁,几何上就是“把坐标系平移到数据中心”

步骤 2:在中心化后的数据上,寻找一个一维基(即一条过原点的直线),使得把所有数据投影到这条直线上后,投影值的方差最大
目的:这条方向就是 第一主成分;方差最大意味着保留了数据在二维平面上最显著的“变化趋势”,从而用一条线就能最好地代表原来二维数据的分布(寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大(对于二维变一维来说))

常见关于方差的问题:

在三维→二维→一维的逐次 PCA 过程中,第二次降维时,“继续沿着方差第二大的方向”行不行?

答案:不行,因为第二主方向必须与第一主方向垂直(线性无关),否则两者几乎重合,信息冗余,无法再多保留原始信息

总结:第一次 PCA 已经抓走了“方差最大”的方向;再降到一维时,如果只继续沿着“方差第二大”的方向,这条方向几乎跟第一次平行(线性相关),几乎带不来新信息,因此必须选一个与第一主成分垂直(线性无关)的方向,才能保留更多原始信息

(五)协方差

协方差的公式:

表征两个字段之间的相关性
当协方差为0时,表示两个字段完全独立

协方差的目标:

利用协方差为0,选择另一组基,这组基的方向一定与第一组基正交

协方差的推广:

将一组N维向量降为K维(K大于0,小于N),其目标是选择K个单位(模为1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为0, 而字段的方差则尽可能大(在正交的约束下,取最大的K个方差)

协方差矩阵

协方差矩阵的推广:

对于更高维度的数据,上述结论依然成立

协方差矩阵对角化的目标:

除主对角线上的元素外,都为0,并且方差从大到小排列

协方差矩阵对角化:

  • 原始数据:X —>协方差矩阵:C
  • 一组基按行组成的矩阵:P
  • 基变换后的数据:Y—>协方差矩阵:D
  • 隐含信息:Y = PX

PCPT的目标:

寻找一个矩阵P,满足PCPT是一个对角矩阵,并且对角元素按从大到小依次排列,那么P的前K行就是要寻找的基,用P的前K行组成的矩阵乘以X就使得X从N维降到了K维并满足上述优化条件

实对称矩阵:

矩阵转置等于其本身

对角化:

除主对角线之外其余元素均为0

实对称矩阵特性:

实对称矩阵必可对角化

协方差最终目标:

P是协方差矩阵C特征向量单位化按行排列出的矩阵,其中每一行都是C的一个特征向量

(六)PCA执行步骤总结

1. 将原始数据按列组成n行m列矩阵X 
2.将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值
3.求出协方差矩阵:
4.求出协方差矩阵的特征值及对应的特征向量
5.将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P;
6.Y=PX即为降维到k维后的数据

(七)PCA实例

1.执行第一步与第二步:

2.计算协方差矩阵:

3.计算协方差矩阵的特征值与特征向量:

4.矩阵P:

5.降维:

(八)PCA优缺点

优点:

1.计算方法简单,容易实现 
2.可以减少指标筛选的工作量
3.消除变量间的多重共线性
4.在一定程度上能减少噪声数据 

缺点:

1.特征必须是连续型变量 
2.无法解释降维后的数据是什么 
3.贡献率小的成分有可能更重要

(九)具体项目案例

“读取 Excel → PCA 降维 → 划分训练/测试集 → 逻辑回归建模 → 输出预测”

1.读取数据

data = pd.read_excel(".\hua.xlsx")
功能:把本地 Excel 文件 hua.xlsx 读成 DataFrame
输入:文件路径(相对路径)
输出:data(行是样本,列包含特征和标签)

2.数据划分(特征与标签)

X = data.iloc[:,:-1]   # 所有行,除最后一列外的所有列 → 特征
y = data.iloc[:,-1]    # 所有行,最后一列 → 标签

功能:把最后一列当作标签,其余列当作特征

3.PCA 降维

pca = PCA(n_components=0.90)
pca.fit(X)
new_x = pca.transform(X)

功能:

•  用保留 90% 方差的准则自动选择主成分个数

•  把原始高维特征 X 映射到新的低维空间 new_x

输出:

•  pca.explained_variance_ratio_:各主成分解释方差占比 

•  new_x:降维后的特征矩阵,形状 (n_samples, n_components)

4.训练/测试集划分

x_train, x_test, y_train, y_test = \
    train_test_split(new_x, y, test_size=0.2, random_state=0)

功能:

•  将降维后的数据按 8:2 比例分为训练集和测试集  

•  random_state=0 保证结果可复现

输出: 

•  x_train, y_train:训练集特征与标签

•  x_test, y_test:测试集特征与标签

5.逻辑回归建模

classifier = LogisticRegression()
classifier.fit(x_train, y_train)

功能:

•  用训练集拟合逻辑回归分类器
输入:

•  x_train, y_train

输出:

•  训练好的模型 classifier

6.预测与输出

train_pred = classifier.predict(x_train)
test_pred  = classifier.predict(x_test)
print(train_pred)
print(test_pred)

功能:

•  分别对训练集和测试集做预测,直接打印预测标签
注意:

• 此时没有计算准确率、混淆矩阵等评估指标

完整代码和结果:

from sklearn.decomposition import PCA
import pandas as pd

data = pd.read_excel(".\hua.xlsx")#数据读取

#数据划分
X = data.iloc[:,:-1]
y = data.iloc[:,-1]

pca = PCA(n_components=0.90)##实例化PCA对象
pca.fit(X) ##进行训练不需要传入y,

print('特征所占百分比:{}'.format(sum(pca.explained_variance_ratio_)))
print(pca.explained_variance_ratio_) 

print('PCA降维后数据:')
new_x = pca.transform(X)
print(new_x)#数据X在主成分空间中的表示。具体来说,这个方法将数据X从原始特征空间转换到主成分空间。

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = \
    train_test_split(new_x, y, test_size = 0.2, random_state = 0)

#导入逻辑回归分类器
from sklearn.linear_model import LogisticRegression

classifier = LogisticRegression()
classifier.fit(x_train, y_train)#传入训练集数据

"""训练集预测"""
train_pred = classifier.predict(x_train)
print(train_pred)

"""测试集预测"""
test_pred = classifier.predict(x_test)
print(test_pred)
特征所占百分比:0.9287327483408421
[0.84389796 0.08483479]
PCA降维后数据:
[[-0.64329795  0.06460986]
 [-1.17974815  0.04201328]
 [-0.10025387  0.3220728 ]
 [ 0.12824342  0.03129845]
 [-1.99954745  0.05762851]
 [ 0.69122892  0.26103899]
 [ 2.56857603 -0.09518828]
 [ 0.05931669  0.19481544]
 [-0.22364171 -0.10724004]
 [ 0.16947924 -0.48623391]
 [-0.72446123  0.41502269]
 [-1.25815543 -0.18114219]
 [ 1.78480362 -0.26420546]
 [ 0.74103318  0.08533927]
 [ 2.28286715 -0.21289989]
 [ 0.05517573  0.20061742]
 [ 0.32254908 -0.76361269]
 [ 0.81862703 -0.04082456]
 [-1.0266783  -0.2353655 ]
 [-0.10155671  0.61750026]
 [ 1.25142092  0.42371837]
 [ 0.69941768  0.16469008]
 [-1.36624474  0.30239396]
 [ 0.81982567  0.35745188]
 [-0.45564024 -0.43812385]
 [ 1.3035028  -0.45925172]
 [-0.04937615 -0.56994931]
 [-0.07294265  0.23790661]
 [-0.29593348 -0.22923122]
 [-1.37196954 -0.13903762]
 [-0.85801237 -0.02490752]
 [-0.39023439 -0.51521122]
 [-1.08871359 -0.26199437]
 [ 1.70273374 -0.34785687]
 [ 1.01037005  0.00652427]
 [-2.22481039 -0.09146336]
 [ 0.57000198  0.10818231]
 [-0.99402196 -0.31628166]
 [ 0.03031743  0.52545196]
 [-0.97596744  0.02299903]
 [-0.19090323  0.67503758]
 [-2.10931376  0.00918616]
 [-0.30273175  0.04565958]
 [-0.0616127  -0.38305347]
 [ 0.18959044  0.82320684]
 [ 1.54277797 -0.26955665]
 [-0.61262168  0.26595184]
 [ 0.93671278  0.63664329]
 [-0.88907936  0.11401778]
 [ 2.3575242  -0.32420972]
 [-1.01759397  0.88079868]
 [-1.03004334 -0.52087367]
 [-0.87270185 -0.07868004]
 [ 0.00340243 -0.11987356]
 [ 1.08602687  0.41402363]
 [-0.80131668 -0.3907531 ]
 [ 0.42050156  0.16131209]
 [-1.52228339 -0.43522714]
 [ 1.11747906  0.32405545]
 [ 2.55855443 -0.15888009]
 [ 0.5185152   0.14112794]
 [-0.9425407   0.03999713]
 [-0.94865621 -0.06116716]
 [ 1.13544592  0.18936678]
 [-0.40324686 -0.03700523]
 [ 0.22983201 -0.60235913]]
[1 0 1 1 1 1 1 1 1 0 0 1 0 0 1 1 0 1 1 0 0 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1
 0 0 0 1 0 0 1 1 1 0 0 1 1 0 0]
[0 1 1 1 0 1 1 1 0 1 1 0 0 1]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张子夜 iiii

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值