之前我们讨论的 PCA降维,对样本数据来言,可以是没有类别标签 y 的。如果我们做回归时,如果特征太多,那么会产生不相关特征引入、过度拟合等问题。我们可以使用PCA 来降维,但 PCA 没有将类别标签考虑进去,属于无监督的。
假设我们对一张 100*100 像素的图片做人脸识别, 每个像素是一个特征,那么会有 10000 个特征,而对应的类别标签 仅仅是 0/1 值, 1 代表是人脸。这么多特征不仅训练复杂,而且不必要特征对结果会带来不可预知的影响,但我们想得到降维后的一些最佳特征(与 关系最密切的),怎么办呢?
LDA是一种监督学习的降维技术,也就是说它的数据集的每个样本是有类别输出的。LDA的基本思想:给定训练样例集,设法将样例投影到一条直线上,使得同类样例的投影点尽可能接近、异类样例的投影点中心尽可能远离。更简单的概括为一句话,就是“投影后类内方差最小,类间方差最大”。
可能还是有点抽象,我们先看看最简单的情况。假设我们有两类数据分为 “+”和“-”,如下图所示,这些数据特征是二维的,我们希望将这些数据投影到一维的一条直线,让每一种类别数据的投影点尽可能的接近,而“+”和“-”数据中心之间的距离尽可能的大。
我们将这个最佳的向量称为 ,那么样例 到方向向量 上的投影可以用下式来计算
当 是二维的,我们就是要找一条直线(方向为 )来做投影,然后寻找最能使样本点分离的直线。
接下来我们从定量的角度来找到这个最佳的 。
给定数据集 , ,令 、 、 、 分别表示第 类示例的样本个数、样本集合、均值向量、协方差矩阵。
的表达式:
的表达式:
由于是两类数据,因此我们只需要将数据投影到一条直线上即可。假设我们的投影直线是向量 ,则对任意一个样本 ,它在直线 的投影为 ,对于我们的两个类别的中心点 , ,在直线 的投影为 和 ,分别用 和 来表示。
什么是最佳的 呢?我们首先发现,能够使投影后的两类样本中心点尽量分离的直线是好的直线,定量表示就是:
但是只考虑 行不行呢?不行,看下图
样本点均匀分布在椭圆里,投影到横轴 上时能够获得更大的中心点间距 ,但是由于有重叠, 不能分离样本点。投影到纵轴 上,虽然 较小,但是能够分离样本点。因此我们还需要考虑同类样本点之间的方差,同类样本点之间方差越小, 就越难以分离。
我们引入另外一个度量值,称作散列值( scatter),对投影后的类求散列值,如下:
从公式中可以看出,只是少除以样本数量的方差值,散列值的几何意义是样本点的密集程度,值越大,越分散,反之,越集中。
而我们想要的投影后的样本点的样子是:不同类别的样本点越分开越好,同类的越聚集越好,也就是均值差越大越好,散列值越小越好。正好,我们同时考虑使用 和 来度量,则可得到欲最大化的目标:
接下来的事就比较明显了,我们只需寻找使 最大的 即可。
先把散列值公式展开:
我们定义上式中的中间那部分:
这个公式的样子不就是少除以样例数的协方差矩阵么,称为散列矩阵( scatter matrices)。
我们继续定义“类内散度矩阵”(within-class scatter matrix):
以及“类间散度矩阵”(between-class scatter matrix) [公式] :
则 可以重写为:
这就是LDA欲最大化的目标。即 与 的“广义瑞利商”(generalized Rayleigh quotient)。
如何确定 呢?
注意到 式中的分子和分母都是关于 的二次项,因此 的解与 的长度无关,只与其方向有关( 为投影后直线的方向),不失一般性,令 ,则式 等价于:
由拉格朗日乘子法,上式等价于:
其中 为拉格朗日乘子。注意到 的方向恒为 ,不妨令:
将其带入上式得:
也就是说我们只要求出原始二类样本的均值和方差就可以确定最佳的投影方向 了。
PCA(主成分分析)和LDA(线性判别分析)有很多的相似点,其本质是要将初始样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样:PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。
PCA和LDA都可以用于降维,两者没有绝对的优劣之分,使用两者的原则实际取决于数据的分布。由于LDA可以利用类别信息,因此某些时候比完全无监督的PCA会更好。下面我们举一个LDA降维可能更优的例子。
我们首先生成三类三维特征的数据,代码如下:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
from sklearn.datasets.samples_generator import make_classification
X, y = make_classification(n_samples=1000, n_features=3, n_redundant=0, n_classes=3, n_informative=2,
n_clusters_per_class=1,class_sep =0.5, random_state =10)
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)
ax.scatter(X[:, 0], X[:, 1], X[:, 2],marker='o',c=y)
<mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x18e30110438>
首先我们看看使用PCA降维到二维的情况,注意PCA无法使用类别信息来降维,代码如下:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o',c=y)
plt.show()
[0.43377069 0.3716351 ]
[1.21083449 1.0373882 ]
由于PCA没有利用类别信息,我们可以看到降维后,样本特征和类别的信息关联几乎完全丢失。
现在我们再看看使用LDA的效果,代码如下:
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis(n_components=2)
lda.fit(X,y)
X_new = lda.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o',c=y)
plt.show()
可以看出降维后样本特征和类别信息之间的关系得以保留。一般来说,如果我们的数据是有类别标签的,那么优先选择LDA去尝试降维;当然也可以使用PCA做很小幅度的降维去消去噪声,然后再使用LDA降维。如果没有类别标签,那么肯定PCA是最先考虑的一个选择了。
LDA算法既可以用来降维,又可以用来分类,但是目前来说,主要还是用于降维。在我们进行图像识别图像识别相关的数据分析时,LDA是一个有力的工具。下面总结下LDA算法的优缺点。
LDA算法的主要优点有:
LDA算法的主要缺点有: