机器学习:python实现LDA降维算法

这次,我们来学习一种经典的降维方法:
线性判别分析(Linear Discriminant Analysis, 以下简称LDA).
在前面博客中(点我)我们讲解了PCA降维算法。
PCA追求的是在降维之后能够最大化保持数据的内在信息,并通过衡量在投影方向上的数据方差的大小来衡量该方向的重要性。
PCA优缺点:
优点:1.最小误差 2.提取了主要信息
缺点:PCA将所有的样本(特征向量集合)作为一个整体对待,去寻找一个均方误差最小意义下的最优线性映射投影,而忽略了类别属性,而它所忽略的投影方向有可能刚好包含了重要的可分性信息。

LDA所追求的目标和PCA不同,不是希望保持数据最多的信息,而是希望数据在降维后能够很容易地被区分开来。
LDA一种有监督的线性降维方法,,也就是说它的数据集的每个样本是有类别输出的。这点和PCA不同。PCA是不考虑样本类别输出的无监督降维技术。
核心思想往线性判别超平面的法向量上投影,使的区分度最大(高内聚,低耦合)。LDA是为了使得降维后的数据点尽可能地容易被区分!
用一句话概括,就是**“投影后类内方差最小,类间方差最大”**。
什么意思呢?
我们要将数据在低维度上进行投影,
投影后希望每一种类别数据的投影点尽可能的接近,
而不同类别的数据的类别中心之间的距离尽可能的大。

LDA算法计算步骤:

  1. 对d维数据进行标准化处理(d为特征数量)
  2. 对每一类别,计算d维的均值向量
  3. 构造类间的散步矩阵和类内的散步矩阵
  4. 计算矩阵的特征值和对应的特征向量
  5. 选取前k个特征值对应的特征向量,构造一个d x k维的转换矩阵W,特征向量以列的形式排列
  6. 使用转换矩阵W将样本映射到新的特征子空间上
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

def lda(data, target, n_dim):
    '''
    :param data: (n_samples, n_features)
    :param target: data class
    :param n_dim: target dimension
    :return: (n_samples, n_dims)
    '''

    clusters = np.unique(target)

    if n_dim > len(clusters)-1:
        print("K is too much")
        print("please input again")
        exit(0)

    #within_class scatter matrix
    Sw = np.zeros((data.shape[1],data.shape[1]))
    for i in clusters:
        datai = data[target == i]
        datai = datai-datai.mean(0)
        Swi = np.mat(datai).T*np.mat(datai)
        Sw += Swi

    #between_class scatter matrix
    SB = np.zeros((data.shape[1],data.shape[1]))
    u = data.mean(0)  #所有样本的平均值
    for i in clusters:
        Ni = data[target == i].shape[0]
        ui = data[target == i].mean(0)  #某个类别的平均值
        SBi = Ni*np.mat(ui - u).T*np.mat(ui - u)
        SB += SBi
    S = np.linalg.inv(Sw)*SB
    eigVals,eigVects = np.linalg.eig(S)  #求特征值,特征向量
    eigValInd = np.argsort(eigVals)
    eigValInd = eigValInd[:(-n_dim-1):-1]
    w = eigVects[:,eigValInd]
    data_ndim = np.dot(data, w)

    return data_ndim

if __name__ == '__main__':
    iris = load_iris()
    X = iris.data
    Y = iris.target
    data_1 = lda(X, Y, 2)

    data_2 = LinearDiscriminantAnalysis(n_components=2).fit_transform(X, Y)


    plt.figure(figsize=(8,4))
    plt.subplot(121)
    plt.title("LDA")
    plt.scatter(data_1[:, 0], data_1[:, 1], c = Y)

    plt.subplot(122)
    plt.title("sklearn_LDA")
    plt.scatter(data_2[:, 0], data_2[:, 1], c = Y)
    plt.savefig("LDA.png",dpi=600)
    plt.show()

run result:
在这里插入图片描述
这里,我们使用了自己编程实现的LDA和调用sklearn自带的LDA对iris数据进行LDA,效果图如上。

PCA和LDA的比较:
相同点:
1)两者均可以对数据进行降维。
2)两者在降维时均使用了矩阵特征分解的思想。
3)两者都假设数据符合高斯分布。

不同点:
1)LDA是有监督的降维方法,而PCA是无监督的降维方法
2)LDA降维最多降到类别数k-1的维数,而PCA没有这个限制。
3)LDA除了可以用于降维,还可以用于分类。
4)LDA选择分类性能最好的投影方向,而PCA选择样本点投影具有最大方差的方向。

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

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

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

注:里面的还有很多知识不是很了解,现在可是用代码实现,大致了解这LDA,后续进行更加深入的了解。

参考和引用:
https://www.cnblogs.com/pinard/p/6244265.html (线性判别分析LDA原理总结)

https://github.com/heucoder/dimensionality_reduction_alo_codes

https://blog.csdn.net/ChenVast/article/details/79227945

https://scikit-learn.org/stable/auto_examples/neighbors/plot_nca_dim_reduction.html#sphx-glr-auto-examples-neighbors-plot-nca-dim-reduction-py

https://www.cnblogs.com/jiahuaking/p/3938541.html

仅用来个人学习和分享,如有错误,请指正。

如若侵权,留言立删。

尊重他人知识产权,不做拿来主义者!

喜欢的可以关注我哦QAQ,

你的关注和喜欢就是我write博文的动力。

猜你喜欢

转载自blog.csdn.net/AugustMe/article/details/97015004