最近在研究数据处理相关的算法,打算整理相关的知识点,以便日后复习之用。
一、主成分分析
最近在学习有关数据降维相关的知识,而主成分分析是数据降维的一种常用手段,所以学习了一下,顺便记录在博客里头,督促自己学习。
对于一组样本数据,数据的维度有时会很大,比如图片,这会对我们进行数据分析造成麻烦,为了便于我们处理数据,我们需要对数据降维。在数据的诸多特征(维度)中,有一些是不必要的,或者说是冗余的,通过数据降维,可能会牺牲一定的准确度,但是却能加快数据分析的速度。主成分分析的思路是通过计算协方差矩阵的特征值与特征向量,找到前k个特征向量(对应k个新的特征),使得数据尽可能地分散开,这基于一个假设,即数据的方差越大,对应的信息越多,这和信息熵是对应的。
二、步骤及方法
规范化
规范化也称为标准化,由于每个数据的每个维度的取值范围不一样,它们对数据的影响也不同。取值范围大的维度会削弱取值范围小的维度的影响,这对于数据分析来说是不利的,我们需要将数据进行规范化处理,规范化的方法很多,这里用Z-score 标准化。
x
′
=
x
−
μ
σ
x'=\frac{x-\mu}{\sigma}
x′=σx−μ
μ
\mu
μ是x的均值,
σ
\sigma
σ为其标准差,这样,标准化后的数据的均值为0,方差为1。
协方差矩阵
接下来就要计算协方差矩阵了,这个我在之前的博客里头提到过,可以参考
协方差矩阵
特征值和特征向量
计算协方差矩阵的特征值和特征向量,选取前k大的特征值对应的特征向量,假设原数据是m维的,则这k个特征向量可以组成一个m*k的矩阵,与原来的数据矩阵相乘后可以将原数据维度降为k维。
原协方差矩阵是半正定矩阵,证明如下:
n*m的数据矩阵X的协方差矩阵为
C
x
=
X
T
X
C_x=X^TX
Cx=XTX
对于特征值
λ
\lambda
λ,根据特征值的定义,存在向量v,使得
C
x
v
=
λ
v
C_xv=\lambda v
Cxv=λv
而且
v
T
λ
v
=
v
T
C
x
v
=
v
T
X
T
X
v
=
(
X
v
)
T
X
v
=
∣
∣
X
v
∣
∣
2
≥
0
v^{T}\lambda v=v^TC_xv\\=v^TX^TXv\\=(Xv)^TXv\\=||Xv||^2\\\geq0
vTλv=vTCxv=vTXTXv=(Xv)TXv=∣∣Xv∣∣2≥0
又有
v
T
λ
v
=
λ
v
T
v
=
λ
∣
∣
v
∣
∣
2
≥
0
v^{T}\lambda v=\lambda v^Tv=\lambda||v||^2\geq0
vTλv=λvTv=λ∣∣v∣∣2≥0
于是
λ
≥
0
\lambda\geq0
λ≥0
因此我们可以得出,数据的协方差矩阵为半正定矩阵,对于选取的k个特征值,我们要求
λ
1
≥
λ
2
≥
.
.
.
≥
λ
k
≥
0
\lambda_1\geq\lambda_2\geq...\geq\lambda_k\geq0
λ1≥λ2≥...≥λk≥0
三、效果
先利用鸢尾花数据集进行测试,采用python的scikit-learn进行pca降维。
代码如下:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
from sklearn.datasets import load_iris
iris=load_iris()
iris_data=iris['data']
iris_label=iris['target']
from sklearn.decomposition import PCA
pca=PCA(n_components=3)
pca.fit(iris_data)
print(pca.explained_variance_ratio_)
鸢尾花的数据集有4个特征,我们先尝试将其降维为3,3个特征对应的方差比例如下:
[0.92461872 0.05306648 0.01710261]
然后将其可视化
然后我们再将其降至两个维度,代码如下:
pca=PCA(n_components=2)
pca.fit(iris_data)
print(pca.explained_variance_ratio_)
# [0.92461872 0.05306648]
代码中的输出值为其方差对应的比例,前两个特征基本占到了方差比例的97%。
可视化如下:
X_new=pca.transform(iris_data)
fig=plt.figure()
ax=fig.add_subplot(111)
for i in range(X_new.shape[0]):
ax.scatter(X_new[i,0],X_new[i,1],marker='o',c=colors[iris_label[i]])
plt.show()
可视化的效果如下:
可以看到,在二维的条件下基本是线性可分的了。
总结
PCA是数据降维的方法之一,普通的PCA是线性的,当然还有非线性的PCA,之后我会整理相关的博客。降维的方法还有很多,比如流形学习,自编码器等,自编码的相关内容可以参考我之前的博客,流形学习我会在非线性降维里头进行整理。
参考资料
- A step by step explanation of Principal Component Analysis
- 用scikit-learn学习主成分分析(PCA)
- Principal Component Analysis (PCA)
PCA的数学推导部分可以参考第三个链接。