文章目录

  • 机器学习 — 主成分分析(PCA),python(sklearn)实现
  • 一、概念
  • 二、PCA算法内容
  • 三、PCA算法推导
  • 1. 问题描述
  • 2. 数据去均值处理
  • 3. 投影处理
  • 4. 寻找投影方向
  • 5. 拉格朗日求解问题
  • 6. 特征值/特征向量分解
  • 四、算法实现
  • 参考资料


机器学习 — 主成分分析(PCA),python(sklearn)实现

一、概念

主成分分析(Principal Component Analysis,PCA), 是一种统计方法。通过 正交变换 将一组可能存在相关性的变量转换为 一组 线性不相关 的变量,转换后的这组变量叫 主成分

二、PCA算法内容

  1. 基本思想:
    主成分分析是设法将原来众多具有一定相关性(比如 n 个指标),重新组合成一组(k 个)新的互相无关的 综合指标(主成分) 来代替原来的指标。
    主成分分析,是考察多个变量间相关性一种多元统计方法,研究如何通过少数几个主成分来揭示多个变量间的内部结构,即从原始变量中导出少数几个主成分,使它们尽可能多地保留原始变量的信息,且彼此间互不相关。通常数学上的处理就是将原来 n 个指标作线性组合,作为新的综合指标。
  2. PCA工作的机制:
    PCA的工作就是从原始的空间中顺序地找一组相互正交的坐标轴,新的坐标轴的选择与数据本身是密切相关的。其中,第一个新坐标轴选择是原始数据中方差最大的方向,第二个新坐标轴选取是与第一个坐标轴正交的平面中使得方差最大的,第三个轴是与第1,2个轴正交的平面中方差最大的。依次类推,可以得到n个这样的坐标轴。
    通过这种方式获得的新的坐标轴,我们发现,大部分方差都包含在前面k个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面k个含有绝大部分方差的坐标轴。事实上,这相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,实现对数据特征的降维处理。
  3. PCA优化目标:
    PCA(是一种数据降维的方法,即用较少特征的数据表达较多特征地数据(数据压缩,PCA属于有损压缩)。PCA推导有两种主要思路:
  • 最大化数据投影后的的方差(让数据更分散)
  • 最小化投影造成的损失

本文选择的是思路1,即投影后的数据方差最大。

三、PCA算法推导

1. 问题描述

假设有一组待降维的数据,原始数据是两维(f1,f2),利用PCA将两维降为1维,并尽可能多的保留原始数据的信息。

原始数据如下:

f1

f2

D1

1

4

D2

2

5

D3

3

4

D4

4

5

D5

5

2

以 f1 为横坐标,f2 为纵坐标,则6个数据在坐标轴上面的为:

主成分分析法原理及其python实现 python 主成分分析_算法

2. 数据去均值处理

首先利用去均值法将样本均值点移到坐标轴的中心:
f1维的均值 f1_mean = (1+2+3+4+5)/ 5 = 3,
f2维的均值 f2_mean = (4+5+4+5+2)/ 5 = 4
去均值处理后的数据:

f1

f2

D1

-2

0

D2

-1

1

D3

0

0

D4

1

1

D5

2

-2

主成分分析法原理及其python实现 python 主成分分析_主成分分析法原理及其python实现_02

3. 投影处理

原始数据是两维(f1,f2),利用PCA将两维降为1维,并尽可能多的保留原始数据的信息。
做法:
  我们需要找到一个投影方向,使得原始数据在该方向上的投影点分散的最开。
如原始数据点在投影方向上的投影点为:D1’,D2’,D3’,D4’,D5’,目标是:找一个投影方向使得投影点分散程度最大。

主成分分析法原理及其python实现 python 主成分分析_机器学习_03



而分散程度取决于方差,主成分分析法原理及其python实现 python 主成分分析_数据分析_04

(为什么是投影点至坐标中心,因为在上一步进行过将数据中的均值点移至坐标轴中心的操作)

4. 寻找投影方向

如何求令方差最大的投影方向?

主成分分析法原理及其python实现 python 主成分分析_数据分析_05


令投影方向的单位向量为 R ⃗ (u,v),且 u2 + v2 = 1

令向量 ODi ⃗ 在 R ⃗ 上的投影为 di,则 di为:

主成分分析法原理及其python实现 python 主成分分析_数据分析_06


此时:所有投影点至中心距离的方差S2为:

主成分分析法原理及其python实现 python 主成分分析_数据分析_07


设矩阵A为去均值后的数据点,即:

主成分分析法原理及其python实现 python 主成分分析_主成分分析法原理及其python实现_08此时,S2可转化为:

主成分分析法原理及其python实现 python 主成分分析_主成分分析法原理及其python实现_09



这时候先停一下,让我们来看一下变量之间的方差和协方差的计算:

(如果关于协方差不清楚的朋友可以参考:)


  f1 的方差:

主成分分析法原理及其python实现 python 主成分分析_数据分析_10


  f1,f2的协方差:

主成分分析法原理及其python实现 python 主成分分析_主成分分析法原理及其python实现_11


  f1,f2的协方差矩阵C:

主成分分析法原理及其python实现 python 主成分分析_算法_12


我们可以发现上面的 S2可以进一步推导为:

主成分分析法原理及其python实现 python 主成分分析_pca降维_13


所以问题转化为求如下最值问题:

主成分分析法原理及其python实现 python 主成分分析_pca降维_14

5. 拉格朗日求解问题

使用拉格朗日乘子法来求最值:

目标函数:

主成分分析法原理及其python实现 python 主成分分析_主成分分析法原理及其python实现_15

构建拉格朗日的乘子函数如下:

主成分分析法原理及其python实现 python 主成分分析_主成分分析法原理及其python实现_16


F对R ⃗ 进行求偏导,并令偏导为0:

主成分分析法原理及其python实现 python 主成分分析_算法_17

可得:

主成分分析法原理及其python实现 python 主成分分析_算法_18

(可见,λ为C的特征值,R ⃗ 为特征向量)

所以有:

主成分分析法原理及其python实现 python 主成分分析_算法_19


即在在某一主成分上的投影方差 S2 等于C的特征值,我们取最大的特征值即可。

6. 特征值/特征向量分解

对协方差矩阵进行 特征值/特征向量分解:

(如何求特征值特征向量可参考:)


协方差矩阵C为:

主成分分析法原理及其python实现 python 主成分分析_机器学习_20


分解的特征值与特征向量为:λ1,λ2 和 α1,α2

主成分分析法原理及其python实现 python 主成分分析_pca降维_21


我们取特征值 λ1 所对应的特征向量 α1 作为投影的方向向量 R ⃗ 。


数据投影变换后的结果为:

主成分分析法原理及其python实现 python 主成分分析_算法_22


至此,我们便将原来的二维数据降到了一维。

选择的新的主成分为:PC1 = 0.8506 * f1 - 0.5257 * f2,可以看出主成分是原特征的线性组合。

PC1主成分的方差为3.11803,保留了原始数据 3.11803 / (3.11803 + 0.881966) = 77.95%的信息。

四、算法实现

sklearn的算法过程如下:

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : pentiumCM
@Email   : 842679178@qq.com
@Software: PyCharm
@File    : pca_demo.py
@Time    : 2020/4/14 11:22
@desc	 : PCA主成分分析demo
'''
import numpy as np
from sklearn.decomposition import PCA

f1 = [1, 2, 3, 4, 5]
f2 = [4, 5, 4, 5, 2]

data = np.array([f1, f2])

cov_f = np.cov(data)
print("协方差矩阵:", cov_f)
eigenvalue, featurevector = np.linalg.eig(cov_f)

print("特征值:", eigenvalue)
print("特征向量:", featurevector)

data = data.T
pca = PCA(n_components=1)
pca.fit(data)
print("降维后的数据:", pca.transform(data))

# 降维后的各主成分的方差值占总方差值的比例,即方差贡献率
print("方差贡献率:", pca.explained_variance_ratio_)

# 降维后的各主成分的方差值
print("主成分方差:", pca.explained_variance_)

运行的结果:

协方差矩阵: [[ 2.5 -1. ]
 			[-1.   1.5]]
特征值: [3.11803399 0.88196601]
特征向量: [[ 0.85065081  0.52573111]
 		  [-0.52573111  0.85065081]]
降维后的数据: [[-1.70130162]
 			  [-1.37638192]
 			  [ 0.        ]
 			  [ 0.3249197 ]
 			  [ 2.75276384]]
方差贡献率: [0.7795085]
主成分方差: [3.11803399]