一、PCA(主成分分析)
主成分分析(PCA)实现一般有两种,一种是对于方阵用特征值分解去实现的,一种是对于不是方阵的用奇异值(SVD)分解去实现的。
1.1 PCA主成分分析的矩阵原理-特征值与奇异值
1.1.1 特征值
特征值很好理解,特征值和特征向量代表了一个矩阵最鲜明的特征方向。多个特征值和特征向量的线性组合可以表示此矩阵。选取特征值最大的特征值对应的特征向量,此特征向量在组成矩阵的线性组合中所占的比重是最大的。一般选取前一半就可,实现降维。
1.1.2 奇异值
这里主要谈谈如何用SVD去解PCA的问题。PCA的问题其实是一个基的变换,使得变换后的数据有着最大的方差。方差的大小描述的是一个变量的信息量。我们在讲一个东西的稳定性的时候,往往说要减小方差,如果一个模型的方差很大,那就说明模型不稳定了。但是对于我们用于机器学习的数据(主要是训练数据),方差大才有意义,不然输入的数据都是同一个点,那方差就为0了,这样输入的多个数据就等同于一个数据了。以下面这张图为例子:
这个假设是一个摄像机采集一个物体运动得到的图片,上面的点表示物体运动的位置,假如我们想要用一条直线去拟合这些点,那我们会选择什么方向的线呢?当然是图上标有signal的那条线。如果我们把这些点单纯的投影到x轴或者y轴上,最后在x轴与y轴上得到的方差是相似的(因为这些点的趋势是在45度左右的方向,所以投影到x轴或者y轴上都是类似的),如果我们使用原来的xy坐标系去看这些点,容易看不出来这些点真正的方向是什么。但是如果我们进行坐标系的变化,横轴变成了signal的方向,纵轴变成了noise的方向,则就很容易发现什么方向的方差大,什么方向的方差小了。
一般来说,方差大的方向是信号的方向,方差小的方向是噪声的方向,我们在数据挖掘中或者数字信号处理中,往往要提高信号与噪声的比例,也就是信噪比。对上图来说,如果我们只保留signal方向的数据,也可以对原数据进行不错的近似了。
PCA的全部工作简单点说,就是对原始的空间中顺序地找一组相互正交的坐标轴,第一个轴是使得方差最大的,第二个轴是在与第一个轴正交的平面中使得方差最大的,第三个轴是在与第1、2个轴正交的平面中方差最大的,这样假设在N维空间中,我们可以找到N个这样的坐标轴,我们取前r个去近似这个空间,这样就从一个N维的空间压缩到r维的空间了,但是我们选择的r个坐标轴能够使得空间的压缩使得数据的损失最小。
1、还是假设我们矩阵每一行表示一个样本,每一列表示一个feature,用矩阵的语言来表示,将一个m * n的矩阵A的进行坐标轴的变化,P就是一个变换的矩阵从一个N维的空间变换到另一个N维的空间,在空间中就会进行一些类似于旋转、拉伸的变化。
2、而将一个m * n的矩阵A变换成一个m * r的矩阵,这样就会使得本来有n个feature的,变成了有r个feature了(r < n),这r个其实就是对n个feature的一种提炼,我们就把这个称为feature的压缩。用数学语言表示就是:
3、但是这个怎么和SVD扯上关系呢?之前谈到,SVD得出的奇异向量也是从奇异值由大到小排列的,按PCA的观点来看,就是方差最大的坐标轴就是第一个奇异向量,方差次大的坐标轴就是第二个奇异向量…我们回忆一下之前得到的SVD式子:
4、在矩阵的两边同时乘上一个矩阵V,由于V是一个正交的矩阵,所以V转置乘以V得到单位阵I,所以可以化成后面的式子:
5、将后面的式子与A * P那个m * n的矩阵变换为m * r的矩阵的式子对照看看,在这里,其实V就是P,也就是一个变化的向量。这里是将一个m * n 的矩阵压缩到一个m * r的矩阵,也就是对列进行压缩,如果我们想对行进行压缩(在PCA的观点下,对行进行压缩可以理解为,将一些相似的sample合并在一起或者将一些没有太大价值的sample去掉)怎么办呢?同样我们写出一个通用的行压缩例子:
6、这样就从一个m行的矩阵压缩到一个r行的矩阵了,对SVD来说也是一样的,我们对SVD分解的式子两边乘以U的转置U’:
7、这样我们就得到了对行进行压缩的式子。可以看出,其实PCA几乎可以说是对SVD的一个包装,如果我们实现了SVD,那也就实现了PCA了。
1.1.3 数学原理
数学角度看PCA:协方差矩阵对角化。即求矩阵的特征值。
特征值越大,证明这根轴越重要;特征值小的置为0,就降维了
同样对于一个具有n个特征的集合来说,很难说这n个特征都是完全有必要的,所以我们就想办法来精简一些特征。选取少于n个的基向量组,将数据投影在这个向量组上,减少空间的同时又能保证信息量。首先需要明确的一点是什么才算好的基向量?首先举一个将二维空间的数据投影到一维空间的情况。如上图所示,对于空间中的这些点,我们应该怎么投影才能够尽可能的保持数据的信息量呢?通过上图中可以看出,如果将数据投影到PC1上,那么所有的数据点较为分散,与之相反,如果投影到PC2上,则数据较为集中。考虑一个极端的情况,假如所有的点在投影之后全部集中在一个点上,这样好吗?当然不!如果所有的点都集中到一个点上,那就说明所有的点都没有差别,信息全部丢失了。所以我们希望当数据点投影到某个坐标轴之上以后,数据越分散越好,而衡量一组数据是否发散恰好有一个统计名词“方差”,也就是说投影过后的点值方差越大越好。同时,如果数据被投影到多个基向量上,那么我们希望这些基向量之间的耦合程度越小越好,也就说基向量之间应该是正交的,如图三所示(建议点击链接去相应网站查看3D演示)。因为如果不考虑基向量之间的正交性,只考虑方差最大的话,那么所求得的值其实都是一样的。关于在不同的基向量上的投影的线性相关度也有一个度量标准–协方差。那么我们的目标明确了,使得相同特征之间方差越大越好,不同特征之间协方差越小越好。
1.2 PCA代码
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
# 载入样本
iris = load_iris()
X, y = iris.data, iris.target
# 降维、设置参数
pca3 = PCA(n_components=3) # 降到3d
X3 = pca3.fit_transform(X)
print(pca3.explained_variance_ratio_)
pca2 = PCA(n_components=2) # 降到2d
X2 = pca2.fit_transform(X)
print(pca2.explained_variance_ratio_)
# 绘图
ax = mplot3d.Axes3D(plt.figure(figsize=(4, 3)))
ax.scatter(X3[:, 0], X3[:, 1], X3[:, 2], s=88, c=y, alpha=0.5)
plt.show()
plt.scatter(X2[:, 0], X2[:, 1], s=88, c=y, alpha=0.5)
plt.show()
out:
[0.92461872 0.05306648 0.01710261]
[0.92461872 0.05306648]
二、LDA
2.1 代码
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
# 载入样本
iris = load_iris()
X, y = iris.data, iris.target
# 降维、设置参数
lda3 = LinearDiscriminantAnalysis(n_components=3)
lda3.fit(X, y)
X3 = lda3.transform(X)
print(lda3.explained_variance_ratio_)# [0.9912126 0.0087874]
# 绘图
plt.scatter(X3[:, 0], X3[:, 1], s=88, c=y, alpha=0.5)
plt.show()