降维(二) LDA

\qquad在主成分分析(PCA)中,我们对降维算法PCA做了总结。这里我们就对另外一种经典的降维方法线性判别分析(Linear Discriminant Analysis, 以下简称LDA)做一个总结。LDA在模式识别领域(比如人脸识别,舰艇识别等图形图像识别领域)中有非常广泛的应用,因此我们有必要了解下它的算法原理。

\qquad在学习LDA之前,有必要将其自然语言处理领域的LDA区别开来,在自然语言处理领域, LDA是隐含狄利克雷分布(Latent Dirichlet Allocation,简称LDA),它是一种处理文档的主题模型。我们本文只讨论线性判别分析,因此后面所有的LDA均指线性判别分析。


1、思想

\qquadLDA是一种监督学习降维技术,也就是说它的数据集的每个样本是有类别输出的。这点和PCA不同。PCA是不考虑样本类别输出的无监督降维技术。LDA的思想可以用一句话概括,就是“投影后类内方差最小,类间方差最大”。什么意思呢? 我们要将数据在低维度上进行投影,投影后希望每一种类别数据的投影点尽可能的接近,而不同类别的数据的类别中心之间的距离尽可能的大

\qquad可能还是有点抽象,我们先看看最简单的情况。假设我们有两类数据 分别为红色和蓝色,如下图所示,这些数据特征是二维的,我们希望将这些数据投影到一维的一条直线,让每一种类别数据的投影点尽可能的接近,而红色和蓝色数据中心之间的距离尽可能的大。
降维(二) LDA

\qquad上图中提供了两种投影方式,哪一种能更好的满足我们的标准呢?从直观上可以看出,右图要比左图的投影效果好,因为右图的黑色数据和蓝色数据各个较为集中,且类别之间的距离明显。左图则在边界处数据混杂。以上就是LDA的主要思想了,当然在实际应用中,我们的数据是多个类别的,我们的原始数据一般也是超过二维的,投影后的也一般不是直线,而是一个低维的超平面。

\qquad在我们将上面直观的内容转化为可以度量的问题之前,我们先了解些必要的数学基础知识,这些在后面讲解具体LDA原理时会用到。


2. 瑞利商(Rayleigh quotient)与广义瑞利商(genralized Rayleigh quotient)

\qquad我们首先来看看瑞利商的定义。瑞利商是指这样的函数R(A,x)R(A,x):
R(A,x)=xHAxxHxR(A,x) = \frac{x^HAx}{x^Hx}
\qquad其中x为非零向量,而A为n×nn×n的Hermitan矩阵。所谓的Hermitan矩阵就是满足共轭转置矩阵和自己相等的矩阵,即AH=AA^H=A。如果我们的矩阵A是实矩阵,则满足AT=AA^T=A的矩阵即为Hermitan矩阵。

\qquad瑞利商R(A,x)R(A,x)有一个非常重要的性质,即它的最大值等于矩阵A最大的特征值,而最小值等于矩阵A的最小的特征值,也就是满足
λminxHAxxHxλmax\lambda_{min} \leq \frac{x^HAx}{x^Hx} \leq \lambda_{max}
\qquad具体的证明这里就不给出了。当向量x是标准正交基时,即满足xHx=1x^Hx=1时,瑞利商退化为:R(A,x)=xHAxR(A,x)=x^HAx,这个形式在谱聚类和PCA中都有出现。

\qquad以上就是瑞利商的内容,现在我们再看看广义瑞利商。广义瑞利商是指这样的函数R(A,B,x):
R(A,x)=xHAxxHBxR(A,x) = \frac{x^HAx}{x^HBx}
\qquad其中x为非零向量,而A,BA,Bn×nn×n的Hermitan矩阵。B为正定矩阵。它的最大值和最小值是什么呢?其实我们只要通过将其通过标准化就可以转化为瑞利商的格式。我们令x=B12xx′=B^{1\over 2}x,则分母转化为:
xHBx=xH(B1/2)HBB1/2x=xHB1/2BB1/2x=xHxx^HBx = x'^H(B^{-1/2})^HBB^{-1/2}x' = x'^HB^{-1/2}BB^{-1/2}x' = x'^Hx'
\qquad而分子转化为:
xHAx=xHB1/2AB1/2xx^HAx = x'^HB^{-1/2}AB^{-1/2}x'
\qquad此时我们的R(A,B,x)R(A,B,x)转化为R(A,B,x)R(A,B,x′):
R(A,B,x)=xHB1/2AB1/2xxHxR(A,B,x') = \frac{x'^HB^{-1/2}AB^{-1/2}x'}{x'^Hx'}
\qquad利用前面的瑞利商的性质,我们可以很快的知道,R(A,B,x)R(A,B,x)的最大值为矩阵B1/2AB1/2B^{−1/2}AB^{−1/2}的最大特征值,或者说矩阵B1AB^{−1}A的最大特征值,而最小值为矩阵B1AB^{−1}A的最小特征值。


3 二类LDA原理

\qquad现在我们回到LDA的原理上,我们在第一节说讲到了LDA希望投影后希望同一种类别数据的投影点尽可能的接近,而不同类别的数据的类别中心之间的距离尽可能的大,但是这只是一个感官的度量。现在我们首先从比较简单的二类LDA入手,严谨的分析LDA的原理。

\qquad假设我们的数据集D={(x1,y1),(x2,y2),...,((xm,ym))}D=\{(x_1,y_1), (x_2,y_2), ...,((x_m,y_m))\},其中任意样本xix_i为n维向量,yi0,1y_i∈{0,1}。我们定义Nj(j=0,1)N_j(j=0,1)为第j类样本的个数,Xj(j=0,1)X_j(j=0,1)为第j类样本的集合,而μj(j=0,1)μ_j(j=0,1)为第j类样本的均值向量,定义Σj(j=0,1)Σ_j(j=0,1)为第j类样本的协方差矩阵(严格说是缺少分母部分的协方差矩阵)。
\qquadμjμ_j 的表达式为:
μj=1NjxXjx    (j=0,1)\mu_j = \frac{1}{N_j}\sum\limits_{x \in X_j}x\;\;(j=0,1)
\qquadΣjΣ_j的表达式为:
Σj=xXj(xμj)(xμj)T    (j=0,1)\Sigma_j = \sum\limits_{x \in X_j}(x-\mu_j)(x-\mu_j)^T\;\;(j=0,1)
\qquad由于是两类数据,因此我们只需要将数据投影到一条直线上即可。假设我们的投影直线是向量w,则对任意一个样本本xix_i,它在直线w的投影为wTxiw^Tx_i,对于我们的两个类别的中心点μ0,μ1μ_0,μ_1,在在直线w的投影为wTμ0w^Tμ_0wTμ1w^Tμ_1。由于LDA需要让不同类别的数据的类别中心之间的距离尽可能的大,也就是我们要最大化wTμ0wTμ122||w^Tμ_0−w^Tμ_1||^2_2,同时我们希望同一种类别数据的投影点尽可能的接近,也就是要同类样本投影点的协方差wTΣ0ww^TΣ_0wwTΣ1ww^TΣ_1w尽可能的小,即最小化wTΣ0w+wTΣ1ww^TΣ_0w+w^TΣ_1w。综上所述,我们的优化目标为:
arg  maxw    J(w)=wTμ0wTμ122wTΣ0w+wTΣ1w=wT(μ0μ1)(μ0μ1)TwwT(Σ0+Σ1)w\underbrace{arg\;max}_w\;\;J(w) = \frac{||w^T\mu_0-w^T\mu_1||_2^2}{w^T\Sigma_0w+w^T\Sigma_1w} = \frac{w^T(\mu_0-\mu_1)(\mu_0-\mu_1)^Tw}{w^T(\Sigma_0+\Sigma_1)w}
\qquad我们一般定义类内散度矩阵SwS_w为:
Sw=Σ0+Σ1=xX0(xμ0)(xμ0)T+xX1(xμ1)(xμ1)TS_w = \Sigma_0 + \Sigma_1 = \sum\limits_{x \in X_0}(x-\mu_0)(x-\mu_0)^T + \sum\limits_{x \in X_1}(x-\mu_1)(x-\mu_1)^T
\qquad同时定义类间散度矩阵SbS_b为:
Sb=(μ0μ1)(μ0μ1)TS_b = (\mu_0-\mu_1)(\mu_0-\mu_1)^T
\qquad这样我们的优化目标重写为:
arg  maxw    J(w)=wTSbwwTSww\underbrace{arg\;max}_w\;\;J(w) = \frac{w^TS_bw}{w^TS_ww}
\qquad仔细一看上式,这不就是我们的广义瑞利商嘛!这就简单了,利用我们第二节讲到的广义瑞利商的性质,我们知道我们的J(w)J(w)最大值为矩阵Sw1SbS^{−1}_wS_b的最大特征值,而对应的w为Sw1SbS^{−1}_wS_b的最大特征值对应的特征向量!

\qquad注意到对于二类的时候,SbwS_bw的方向恒为μ0μ1μ_0−μ_1,不妨令Sbw=λ(μ0μ1)S_bw=λ(μ_0−μ_1),将其带入:(Sw1Sb)w=λw(S^{−1}_wS_b)w=λw,可以得到w=Sw1(μ0μ1)w=S^{−1}_w(μ_0−μ_1), 也就是说我们只要求出原始二类样本的均值和方差就可以确定最佳的投影方向ww了。


4、多类LDA原理

\qquad有了二类LDA的基础,我们再来看看多类别LDA的原理。

\qquad假设我们的数据集D=(x1,y1),(x2,y2),...,((xm,ym))D={(x_1,y_1),(x_2,y_2),...,((x_m,y_m))},其中任意样本xix_i为n维向量,yiC1,C2,...,Cky_i∈{C_1,C_2,...,C_k}。我们定义Nj(j=1,2...k)N_j(j=1,2...k)为第j类样本的个数,Xj(j=1,2...k)X_j(j=1,2...k)为第j类样本的集合,而μj(j=1,2...k)μ_j(j=1,2...k)为第j类样本的均值向量,定义Σj(j=1,2...k)Σ_j(j=1,2...k)为第j类样本的协方差矩阵。在二类LDA里面定义的公式可以很容易的类推到多类LDA。

\qquad由于我们是多类向低维投影,则此时投影到的低维空间就不是一条直线,而是一个超平面了。假设我们投影到的低维空间的维度为dd,对应的基向量为(w1,w2,...wd)(w_1,w_2,...w_d),基向量组成的矩阵为WW, 它是一个n×dn×d的矩阵。

\qquad此时我们的优化目标应该可以变成为:
WTSbWWTSwW\frac{W^TS_bW}{W^TS_wW}
\qquad其中Sb=j=1kNj(μjμ)(μjμ)TS_b = \sum\limits_{j=1}^{k}N_j(\mu_j-\mu)(\mu_j-\mu)^Tμμ为所有样本均值向量。Sw=j=1kSwj=j=1kxXj(xμj)(xμj)TS_w = \sum\limits_{j=1}^{k}S_{wj} = \sum\limits_{j=1}^{k}\sum\limits_{x \in X_j}(x-\mu_j)(x-\mu_j)^T

\qquad但是有一个问题,就是WTSbWW^TS_bWWTSwWW^TS_wW都是矩阵,不是标量,无法作为一个标量函数来优化!也就是说,我们无法直接用二类LDA的优化方法,怎么办呢?一般来说,我们可以用其他的一些替代优化目标来实现。

\qquad常见的一个LDA多类优化目标函数定义为:
arg  maxW    J(W)=diagWTSbWdiagWTSwW\underbrace{arg\;max}_W\;\;J(W) = \frac{\prod\limits_{diag}W^TS_bW}{\prod\limits_{diag}W^TS_wW}
\qquad其中diagA\prod\limits_{diag}A为A的主对角线元素的乘积,W为n×dn×d的矩阵。
J(W)J(W)的优化过程可以转化为:
J(W)=i=1dwiTSbwii=1dwiTSwwi=i=1dwiTSbwiwiTSwwiJ(W) = \frac{\prod\limits_{i=1}^dw_i^TS_bw_i}{\prod\limits_{i=1}^dw_i^TS_ww_i} = \prod\limits_{i=1}^d\frac{w_i^TS_bw_i}{w_i^TS_ww_i}

\qquad仔细观察上式最右边,这不就是广义瑞利商嘛!最大值是矩阵Sw1SbS^{−1}_wS_b的最大特征值,最大的d个值的乘积就是矩阵Sw1SbS^{−1}_wS_b的最大的d个特征值的乘积,此时对应的矩阵W为这最大的d个特征值对应的特征向量张成的矩阵。

\qquad由于W是一个利用了样本的类别得到的投影矩阵,因此它的降维到的维度d最大值为k1k-1。为什么最大维度不是类别数k呢?因为SbS_b中每个μjμμ_j−μ的秩为1,因此协方差矩阵相加后最大的秩为k(矩阵的秩小于等于各个相加矩阵的秩的和),但是由于如果我们知道前k1k-1μjμ_j后,最后一个μkμ_k可以由前k-1个μjμ_j线性表示,因此SbS_b的秩最大为k1k-1,即特征向量最多有k1k-1个。


5、LDA算法流程

\qquad在第三节和第四节我们讲述了LDA的原理,现在我们对LDA降维的流程做一个总结。

输入:数据集D=(x1,y1),(x2,y2),...,((xm,ym))D={(x_1,y_1),(x_2,y_2),...,((x_m,y_m))},其中任意样本xix_i为n维向量,yiC1,C2,...,Cky_i∈{C_1,C_2,...,C_k},降维到的维度d。
输出:降维后的样本集DD′

(1)计算类内散度矩阵SwS_w

(2)计算类间散度矩阵SbS_b

(3)计算矩阵Sw1SbS^{−1}_wS_b

(4)计算Sw1SbS^{−1}_wS_b的最大的d个特征值和对应的d个特征向量(w1,w2,...wd)(w_1,w_2,...w_d),得到投影矩阵W;

(5)对样本集中的每一个样本特征xix_i,转化为新的样本zi=WTxiz_i=W^Tx_i

(6)得到输出样本集D=(z1,y1),(z2,y2),...,((zm,ym))D′={(z_1,y_1),(z_2,y_2),...,((z_m,y_m))}

\qquad以上就是使用LDA进行降维的算法流程。实际上LDA除了可以用于降维以外,还可以用于分类。一个常见的LDA分类基本思想是假设各个类别的样本数据符合高斯分布,这样利用LDA进行投影后,可以利用极大似然估计计算各个类别投影数据的均值和方差,进而得到该类别高斯分布的概率密度函数。当一个新的样本到来后,我们可以将它投影,然后将投影后的样本特征分别带入各个类别的高斯分布概率密度函数,计算它属于这个类别的概率,最大的概率对应的类别即为预测类别。


6、简单实现(python)

下面是使用iris数据集的部分数据进行降维的简单实现:

from sklearn import datasets
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

class LDA:
    def lda(self, X, y, n_components):
        """
        LDA实现
        
        :param X: 样本特征
        :param y: 样本标签
        :param n_components: 降维保留的维度
        :return: z: 降维后数据  recon_mat: 重构数据
        """
        n, m = np.shape(X)
        y_list = np.unique(y)
        y_class = np.shape(y_list)[0]
        if n_components > y_class - 1:
            return
        X_avg = np.average(X, axis=0)
        # 类间散度
        Sb = np.zeros([m, m])
        # 类内散度
        Sw = np.zeros([m, m])
        # 对每一类数据求散度
        for elem in y_list:
            class_index = np.where(y == elem)
            X_elem = X[class_index]
            X_elem_rows, _ = np.shape(X_elem)
            X_elem_avg = np.average(X_elem, axis=0)
            
            # 类间散度
            X_elem_sub = X_elem_avg - X_avg
            X_elem_behind_div = np.mat(X_elem_sub).T * np.mat(X_elem_sub)
            Sb += X_elem_rows * X_elem_behind_div
            
            # 类内散度
            X_item_sub = X_elem - X_elem_avg
            X_item_in_div = np.mat(X_item_sub).T * np.mat(X_item_sub)
            Sw += X_item_in_div
        
        # 避免矩阵无法求逆导致的错误
        try:
            Sw_inv = np.linalg.inv(Sw)
        except np.linalg.LinAlgError:
            raise("matrix cannot be inverse...")
        else:
            # 求特征值特征向量
            S = np.dot(Sw_inv, Sb)
            eig_value, eig_vec = np.linalg.eig(np.mat(S))
            eig_value_sort = np.argsort(eig_value)
            eig_max_index = eig_value_sort[-1:-(n_components + 1):-1]
            # 特征向量矩阵W
            W = eig_vec[:, eig_max_index]
            z = X * W
            # 重构数据
            recon_mat = z * W.T
            return z, recon_mat


if __name__ == '__main__':
    # 测试数据使用sklearn中的鸢尾花数据
    iris = datasets.load_iris()

    data = pd.DataFrame(iris.data, columns=iris.feature_names)
    data['class'] = iris.target

    # 只取两列属性,两个类别
    data = data[data['class'] != 2]
    X = np.array(data[data.columns.drop('class')].iloc[:, 0:2])
    y = np.array(data['class'])

    LDA = LDA()
	
	# 降维
    z, recon_mat = LDA.lda(X, y, 1)
    print(z)
    
    # 可视化
    for i in range(np.shape(y)[0]):
        if y[i] == 0:
            plt.scatter(X[i, 0], X[i, 1], c='b')
            plt.scatter(recon_mat[i, 0], recon_mat[i, 1], c='y')
        else:
            plt.scatter(X[i, 0], X[i, 1], c='r')
            plt.scatter(recon_mat[i, 0], recon_mat[i, 1], c='g')

    plt.show()

运行结果:

[[0.50779082]
 [0.76910571]
 [0.48772607]
 [0.50209183]
 [0.367101  ]
 [0.38716575]

 ...
  [1.44382328]
 [1.27440194]
 [1.35192973]
 [1.66773987]
 [1.28306871]
 [1.42945752]]

降维(二) LDA


7、LDA vs PCA

\qquadLDA用于降维,和PCA有很多相同,也有很多不同的地方,因此值得好好的比较一下两者的降维异同点。

首先我们看看相同点

  • 两者均可以对数据进行降维

  • 两者在降维时均使用了矩阵特征分解的思想。

  • 两者都假设数据符合高斯分布

我们接着看看不同点

  • LDA是有监督的降维方法,而PCA是无监督的降维方法

  • LDA降维最多降到类别数k-1的维数,而PCA没有这个限制。

  • LDA除了可以用于降维,还可以用于分类

  • LDA选择分类性能最好的投影方向,而PCA选择样本点投影具有最大方差的方向。

这点可以从下图形象的看出,在某些数据分布下LDA比PCA降维较优。
降维(二) LDA

当然,某些某些数据分布下PCA比LDA降维较优,如下图所示:
降维(二) LDA


8、LDA算法小结

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

LDA算法的主要优点有:

  • 在降维过程中可以使用类别的先验知识经验,而像PCA这样的无监督学习则无法使用类别先验知识。
  • LDA在样本分类信息依赖均值而不是方差的时候,比PCA之类的算法较优。

LDA算法的主要缺点有:

  • LDA不适合对非高斯分布样本进行降维,PCA也有这个问题。
  • LDA降维最多降到类别数k-1的维数,如果我们降维的维度大于k-1,则不能使用LDA。当然目前有一些LDA的进化版算法可以绕过这个问题。
  • LDA在样本分类信息依赖方差而不是均值的时候,降维效果不好。
  • LDA可能过度拟合数据。

引用:
本文理论部分引自下文:
http://www.cnblogs.com/pinard/p/6244265.html