本小节将介绍线性判别分析(Linear Discriminant Analysis, LDA),它是一种分类算法,同时也是一种有监督的降维算法。
李航老师的《统计学习方法》中提到,统计学习方法都是由模型、策略和算法构成的,因此本文在算法推导也主要从这三部分进行展开讨论。
LDA的主要思想是:给定训练集,想办法将这些样本投影到一条直线上,使得投影后同类的样本尽可能靠近,不同类的样本尽可能远离;在对新样本进行分类时,将其投影到同样的这条直线上,再根据投影点的位置来确定新样本的类别。 所以我们的模型就是要找到这条投影后的直线 y = w T x y=w^{T}x y=wTx
上面我们讨论了LDA就是要找到一个投影向量 w w w,使得投影后满足:“类内差异小、类间差异大”。类内差异我们可以用同一个类的方差来衡量,方差越大表示数据波动越大,差异越大,反之差异越小;类间差异可以用两个类的均值向量之间的距离来衡量,如果两个类的均值向量距离较大,表明它们相距越远,差距越大。为了简化运算,这里假设只有两个类,z={0,1},计算均值向量 u 0 = ∑ i x i , ( y i = 0 ) u_{0}=\sum_{i}x_i,(y_{i}=0) u0=i∑xi,(yi=0) u 1 = ∑ i x i , ( y i = 1 ) u_{1}=\sum_{i}x_i,(y_{i}=1) u1=i∑xi,(yi=1)由于 x x x在 w w w方向上的投影就是 x x x与 w w w做内积,所以类别0和1在 w w w上的投影分别为 w T u 0 w^{T}u_{0} wTu0和 w T u 1 w^{T}u_{1} wTu1。同一类别之间的差异小等价于 w T u 0 w^{T}u_{0} wTu0和 w T u 1 w^{T}u_{1} wTu1自身的方差较小。令 s 0 , s 1 s_{0},s_{1} s0,s1分别为投影后类别0和1的方差,那么 s 0 = V a r ( w T u 0 ) = w T V a r ( u 0 ) w = w T s c 0 w s_{0}=Var(w^{T}u_{0})=w^{T}Var(u_{0})w=w^Ts_{c0}w s0=Var(wTu0)=wTVar(u0)w=wTsc0w s 1 = w T s c 1 w s_{1}=w^Ts_{c1}w s1=wTsc1w 其中 s c 0 , s c 1 s_{c0},s_{c1} sc0,sc1分别表示投影前类别1和类别2的方差。所以用 s 0 + s 1 s_{0}+s_{1} s0+s1就表示了投影后的类内样本距离。 对于类间样本距离,我们直接用两个均值向量的之间的欧式距离表示 ∣ ∣ w T u 0 − w T u 1 ∣ ∣ 2 2 ||w^Tu_{0}-w^Tu_{1}||^2_2 ∣∣wTu0−wTu1∣∣22 所以要满足类内小,类间大,我们可以采用如下损失函数 J ( w ) = − ∣ ∣ w T u 0 − w T u 1 ∣ ∣ 2 2 s 0 + s 1 J(w)=-\frac{||w^Tu_{0}-w^Tu_{1}||^2_2}{s_{0}+s_{1}} J(w)=−s0+s1∣∣wTu0−wTu1∣∣22 = − w T ( u 0 − u 1 ) ( u 0 − u 1 ) T w w T ( s c 0 + s c 1 ) w =-\frac{w^T(u_0-u_1)(u_0-u_1)^Tw}{w^T(s_{c0}+s_{c1})w} =−wT(sc0+sc1)wwT(u0−u1)(u0−u1)Tw通过最小化损失函数 J ( w ) J(w) J(w)即可求得最优的投影方向。 w ∗ = a r g m i n J ( w ) w^*=argminJ(w) w∗=argminJ(w)
怎么求解 a r g m i n J ( w ) argmin J(w) argminJ(w)呢?为了方便运算,不妨令 s b = ( u 0 − u 1 ) ( u 0 − u 1 ) T s_{b}=(u_0-u_1)(u_0-u_1)^T sb=(u0−u1)(u0−u1)T,表示类间散度矩阵(between-class scatter matrix);令 s w = s 0 + s 1 s_{w}=s_{0}+s_{1} sw=s0+s1表示类内散度矩阵(within-class scatter matrix),则 J ( w ) = − w T s b w w T s w w J(w)=-\frac{w^Ts_bw}{w^Ts_ww} J(w)=−wTswwwTsbw又由于分子分母都有 w T 和 w w^T和w wT和w,所以最终的计算结果将与 w w w的大小无关(会上下约掉),只与 w w w的方向有关。所以不妨令 w T s w w = 1 w^Ts_ww=1 wTsww=1,则优化方程可以写成如下形式 min w − w T s b w s.t. w T s w w = 1 \begin{aligned} \min _{\boldsymbol{w}} &-\boldsymbol{w}^{\mathrm{T}} \mathbf{s}_{b} \boldsymbol{w} \\ \text { s.t. } & \boldsymbol{w}^{\mathrm{T}} \mathbf{s}_{w} \boldsymbol{w}=1 \end{aligned} wmin s.t. −wTsbwwTsww=1根据拉格朗日乘子法,可以求得 s b w = λ s w w s_bw=\lambda s_ww sbw=λsww,又因为 s b w s_bw sbw的方向是 u 0 − u 1 u_0-u_1 u0−u1,所以不妨令 s b w = λ ( u 0 − u 1 ) s_bw=\lambda (u_0-u_1) sbw=λ(u0−u1),从而 λ s w w = λ ( u 0 − u 1 ) \lambda s_ww=\lambda (u_0-u_1) λsww=λ(u0−u1),求得 w ∗ = s w − 1 ( u 0 − u 1 ) w^*=s^{-1}_w(u_0-u_1) w∗=sw−1(u0−u1)
LDA在降维方向应用比较多,在分类方面应用反而不多,因为投影到新的坐标轴后,有可能带来线性不可分的情况。但是这种思想是可以借鉴的,所谓的降维打击吧,这跟svm和神经网络这种先升维再分类的思想刚好反过来。
这里主要使用sklearn这个库来实现机器学习算法。
由于是分类问题,所以我们可以直接使用准确率来评估模型
print('ACC:%.3f'%(accuracy_score(y_test,y_pred))) ACC:0.971其实上面用的方法是留出法,我们也可以使用交叉验证法来计算模型误差。这样就把划分训练集和测试集、建立模型以及评估模型这几步合并在一起。
acc = np.mean(cross_val_score(LinearDiscriminantAnalysis(),X,y,cv=10,scoring='accuracy')) print('ACC:%.3f'%(acc)) ACC:0.956可以看到两者比较接近。
(1)在降维过程中可以使用类别的先验知识经验,而像PCA这样的无监督学习则无法使用类别先验知识。
(1)当总共有K个类别时,LDA最多降到K-1维,而PCA没有这个限制