python pca降维_MLK | 机器学习的降维"打击"

dd382af2a1d8126cadd4d76057488853.png

"MLK,即Machine Learning Knowledge,本专栏在于对机器学习的重点知识做一次梳理,便于日后温习,内容主要来自于《百面机器学习》一书,结合自己的经验与思考做的一些总结与归纳,本次主要讲解的内容就是特征降维,主要涉及PCA以及一些常见分析方法。"

? 前情回顾

MLK | 那些常见的特征工程

MLK | 模型评估的一些事

? Index

  • PCA降维算法

    • 内积与投影

    • 基与基变换

    • 方差

    • 协方差

    • 协方差矩阵

    • 协方差矩阵对角化

    • PCA算法步骤

    • PCA实例

    • PCA的Python操作

  • LDA降维算法

    • LDA介绍

    • LDA的优缺点

    • LDA的Python操作

? 在机器学习中,我们有的时候会遇到维度灾难,当模型的训练入参有很多的时候,往往是需要很多的时间和资源去训练的,而这不是我们想要看到的结果。一般情况下,我们都是会对源数据进行特征处理,提取对预测更加有效的特征。

有的时候,我们会得到比较高维的特征向量,而这里面往往包含很多的噪声与冗余数据,所以我们需要通过降维的方式去获取特征更加有效的信息,一来提高特征表达能力,二来提高模型训练的效率。

? PCA降维算法

PCA(Principal Components Analysis),即主成分分析,是降维操作中最经典的方法,它是一种线性的、无监督、全局性的降维算法,旨在找到数据中的"主要成分",提取主成分从而达到降维的目的。PCA是一种无监督算法,也就是我们不需要标签也能对数据做降维,这就使得其应用范围更加广泛了,但是PCA也有一个问题,原来的数据中比如包括了年龄,性别,身高等指标降维后的数据既然维度变小了,那么每一维都是什么含义呢?这个就很难解释了,所以PCA本质来说是无法解释降维后的数据的物理含义。

在了解PCA之前,有一些基础的名词需要温习一下:

1. 内积与投影

内积运算将两个向量映射为一个实数,下面是两个维数相同的向量的内积:

255f6a1e42f3686bb3c7c14f633fc4a8.png

假设存在两个点A,B,其在坐标轴的位置如下图:

616041f08ab9b12714aff0f27f3718f9.png

我们从A向B引一条垂线,也就是A在B上的投影,其夹角为a,则投影的矢量长度为|A|cos(a),其中568e5682bbae7a4cb9c1aae1fa6fe0d8.png是向量A的模,也就是A线段的标量长度。

而内积的另一种表现形式为:

9e5c27d720fd755c0e73eec162d3c21c.png

也就是说,当B的模为1的时候,也就是单位向量的时候,内积可以表示为:

269fdff7b459d3cfa08638ddc4485121.png

也就是A与B的内积值等于A向B所在直线投影的矢量长度。

2. 基与基变换

基可以理解为单位向量,基都是正交的(即内积为0,直观来说就是相互垂直),并且是线性无关的。

基变换指的是当前向量和一个基进行内积运算,得到的结果作为新的坐标分量。

假设存在一个点(3,2),一般我们都会取(1,0)和(0,1)为基,也就是我们的X和Y轴方向。如果我们取(1,1)和(-1,1)为我们的基,但我们希望基的模为1,这样子会方便计算,所以可以除以当前的模长,所以上面的基就变成了:b95073ce55c5e1b436b3b7fc73a00ec2.png

如下图所示:

acef2802d5ffc92c3557ce2efc9b1d20.png

所以,进行基变换,只需要进行一次内积运算:

d99a313b7a9fb46cd227c00db07b7f9f.png

3. 方差

一个字段的方差可以看做是每个元素与字段均值的差的平方和的均值,即:

58bd382ef1cef85aae4d989b198c7b0c.png

一般我们都会把均值为化为0,即进行一次变换,所以方差可以表示为:

0b4f865ae8c1526a6b7a584331f9e747.png

4. 协方差

如果单纯地选择方差最大的方向,则无法保证两个字段之间相互独立,因为我们需要的是尽可能多地保留原始信息,但又是相互独立,这里我们引入一下概念,协方差,用来表示两个字段的相关性,公式为:

0caf8f7869e898994d8017978b9b59d4.png

协方差:度量各个维度偏离其均值的程度。协方差的值如果为正值,则说明两者是正相关的(从协方差可以引出“相关系数”的定义),结果为负值就说明负相关的,如果为0,也是就是统计上说的“相互独立”。

所以,我们的目标就是让两个字段的协方差为0,为了协方差为0,选择第二个基的时候,必须要在第一个基的正交方向上选择。

我们说的PCA降维,就是把N维的特征,降到K维(0 < K < N),也就是说要选择k个单位正交基,并且尽可能让方差最大化。

5. 协方差矩阵

在统计学与概率论中,协方差矩阵的每个元素是各个向量元素之间的协方差,是从标量随机变量到高维度随机向量的自然推广。

假设存在矩阵X:

c6b7e5b071e1a0619d21f735c1bc026d.png

其协方差矩阵为:

2d77fcd932e13ee56955b78ecb4fe65e.png

可以看出,协方差矩阵的对角线元素为两个字段的方差,而其他元素为矩阵的协方差,按照我们之前的说法,我们需要得到协方差为0,并且方差最大的转换。

6. 协方差矩阵对角化

根据上述推导,我们发现要达到优化目前,等价于将协方差矩阵对角化:即除对角线外的其它元素化为0,并且在对角线上将元素按大小从上到下排列,这样我们就达到了优化目的。这样说可能还不是很明晰,我们进一步看下原矩阵与基变换后矩阵协方差矩阵的关系。

设原始数据矩阵X对应的协方差矩阵为C,而P是一组基按行组成的矩阵,设Y=PX,则Y为X对P做基变换后的数据。设Y的协方差矩阵为D,我们推导一下D与C的关系:

1b5e796ebe0a6f2bb8883a731c15bfe7.png

我们要找的P不是别的,而是能让原始协方差矩阵对角化的P。换句话说,优化目标变成了寻找一个矩阵P,满足PCP^T是一个对角矩阵,并且对角元素按从大到小依次排列,那么P的前K行就是要寻找的基,用P的前K行组成的矩阵乘以X就使得X从N维降到了K维并满足上述优化条件。

7. PCA算法步骤

设有mXn维数据。

1)将原始数据按列组成n行m列矩阵X

2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值

3)求出协方差矩阵C=1mXXT

4)求出协方差矩阵的特征值及对应的特征向量

5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P

6)Y=PX即为降维到k维后的数据

8. PCA实例

假设存在2维数据baeea6546b1e52806ee419c2cdd7a454.png:,需要将其降至1维。

1)均值归0:目前每个维度的均值均为0,无需变换。

2)求协方差矩阵

ce3c8f2eff147c98d89aa833ba726490.png

3)求解特征值以及特征向量

69e666ba3ea0f903f0b81adfb1b48994.png

aea91e0217d7acd4b6a76fc81cca1779.png

可以参考:https://jingyan.baidu.com/article/27fa7326afb4c146f8271ff3.html  

4)标准化特征向量

d03eb1c1ce2793d4e2aefeef292da665.png

5)得到对角矩阵P并验证对角化  

e86823c57ffa24ab7d7861c28b7c2e3a.png

c0fb089f5d8d3fbc9204b571161d5021.png

6)因为需要得到1维矩阵,因此用P的第一行乘以原矩阵即可:

783897d803f40b2fa52edc1a2939443a.png

降维投影如下图所示:

3d113ccfe9f283b893b8823dbb751524.png

9. Python操作

# 使用sklearn进行PCA降维
import numpy as np
from sklearn.decomposition import PCA
X = np.array([[-1,2,66,-1], [-2,6,58,-1], [-3,8,45,-2], [1,9,36,1], [2,10,62,1], [3,5,83,2]])  #导入数据,维度为4
print('原矩阵X:\n', X)

pca = PCA(n_components=2)   #降到2维
pca.fit(X)                  #训练
newX=pca.fit_transform(X)   #降维后的数据

print('贡献率:', pca.explained_variance_ratio_)
print('降维后矩阵:\n', newX)

'''
参数解释:
n_components:  我们可以利用此参数设置想要的特征维度数目,可以是int型的数字,也可以是阈值百分比,如95%,让PCA类根据样本特征方差来降到合适的维数,也可以指定为string类型,MLE。
copy:bool类型,TRUE或者FALSE,是否将原始数据复制一份,这样运行后原始数据值不会改变,默认为TRUE。
whiten:bool类型,是否进行白化(就是对降维后的数据进行归一化,使方差为1),默认为FALSE。如果需要后续处理可以改为TRUE。
explained_variance_: 代表降为后各主成分的方差值,方差值越大,表明越重要。
explained_variance_ratio_: 代表各主成分的贡献率。
inverse_transform(): 将降维后的数据转换成原始数据,X=pca.inverse_transform(newX)。
'''

output:

ebc447de6f9618cb6b32128bc25afc3d.png

? LDA降维算法

线性判别分析(Linear Discriminant Analysis,LDA)是一种有监督学习算法,也是经常被拿来降维,它和PCA的区别在于是否存在标签,其中心思想就是—— 最大化类间距离和最小化类内距离。

7143792a6157e8e3489ccde3a63e7e9a.png

而PCA的不足在于不能很好地分开不同类别的数据,如下图:

ca8f89dafbf902332627b59fa9d2ace7.png

LDA算法既可以用来降维,又可以用来分类,但是目前来说,主要还是用于降维。在我们进行图像识别图像识别相关的数据分析时,LDA是一个有力的工具。下面总结下LDA算法的优缺点:

优点:

1)在降维过程中可以使用类别的先验知识经验,而像PCA这样的无监督学习则无法使用类别先验知识。

2)LDA在样本分类信息依赖均值而不是方差的时候,比PCA之类的算法较优。

缺点:

1)LDA不适合对非高斯分布样本进行降维,PCA也有这个问题。

2)LDA降维最多降到类别数k-1的维数,如果我们降维的维度大于k-1,则不能使用LDA。当然目前有一些LDA的进化版算法可以绕过这个问题。

3)LDA在样本分类信息依赖方差而不是均值的时候,降维效果不好。

4)LDA可能过度拟合数据。       

Python操作

import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
y = np.array([1, 1, 1, 2, 2, 2])
clf = LinearDiscriminantAnalysis()
clf.fit(X, y)  
LinearDiscriminantAnalysis(n_components=None, priors=None, shrinkage=None,
              solver='svd', store_covariance=False, tol=0.0001)
print(clf.predict([[-0.8, -1]]))

? Reference

1)Reference十分钟搞定PCA主成分分析

https://blog.csdn.net/tangyudi/article/details/80188302#comments

2)PCA的数学原理

http://blog.codinglabs.org/articles/pca-tutorial.html  

a6f705c43e2634a108018346abbd7756.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PCA(Principal Component Analysis)是一种常用的降维算法,它通过线性变换将高维数据映射到低维空间中,且尽可能多地保留原始数据的信息。PCA的核心思想是将原始数据投影到新的坐标系上,新坐标系的选择是使得投影后数据方差最大的方向,也就是数据的主成分方向。以下是PCA降维的步骤: 1. 数据预处理:对数据进行标准化处理,使得每个特征的均值为0,方差为1。 2. 计算协方差矩阵:协方差矩阵反映了特征之间的相关性,计算公式为:$\Sigma=\frac{1}{n-1}(X-\bar{X})^{T}(X-\bar{X})$,其中 $X$ 为 $n$ 行 $m$ 列的数据矩阵,$\bar{X}$ 为 $m$ 维向量,表示每一列的均值。 3. 计算特征值和特征向量:对协方差矩阵进行特征值分解,得到特征值和特征向量。 4. 选取主成分:将特征值按照从大到小的顺序排列,选择前 $k$ 个特征值对应的特征向量,组成新的 $k$ 维特征空间。 5. 投影到新的特征空间:将原始数据投影到新的 $k$ 维特征空间中,得到降维后的数据。 下面是Python实现PCA降维的代码: ```python import numpy as np class PCA: def __init__(self, n_components): self.n_components = n_components def fit_transform(self, X): # 数据预处理 X_std = (X - np.mean(X, axis=0)) / np.std(X, axis=0) # 计算协方差矩阵 cov_mat = np.cov(X_std.T) # 计算特征值和特征向量 eigenvals, eigenvecs = np.linalg.eig(cov_mat) # 选取前n个特征向量 idx = eigenvals.argsort()[::-1] eigenvecs = eigenvecs[:, idx][:, :self.n_components] # 投影到新的特征空间 X_new = np.dot(X_std, eigenvecs) return X_new ``` 使用示例: ```python import numpy as np from sklearn.datasets import load_iris # 加载数据 iris = load_iris() X = iris.data # PCA降维 pca = PCA(n_components=2) X_new = pca.fit_transform(X) # 可视化 import matplotlib.pyplot as plt plt.scatter(X_new[:,0], X_new[:,1], c=iris.target) plt.show() ``` 这里使用了鸢尾花数据集进行演示,将原始数据从4维降到了2维,并将结果可视化出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值