您的位置:首页 > 编程语言 > Python开发

LDA线性判别分析原理及python应用(葡萄酒案例分析)

2020-08-14 22:43 2011 查看

目录

线性判别分析(LDA)数据降维及案例实战

  一、LDA是什么

  二、计算散布矩阵

  三、线性判别式及特征选择

  四、样本数据降维投影

  五、完整代码

  结语

 

一、LDA是什么

  • LDA概念及与PCA区别

LDA线性判别分析(Linear Discriminant Analysis)也是一种特征提取、数据压缩技术。在模型训练时候进行LDA数据处理可以提高计算效率以及避免过拟合。它是一种有监督学习算法。

与PCA主成分分析(Principal Component Analysis)相比,LDA是有监督数据压缩方法,而PCA是有监督数据压缩及特征提取方法。PCA目标是寻找数据集最大方差方向作为主成分,LDA目标是寻找和优化具有可分性特征子空间。其实两者各有优势,更深入详细的区分和应用等待之后的学习,这里我仍然以葡萄酒数据集分类为案例记录原理知识的学习和具体实现步骤。

对比我之前记录的PCA请看:PCA数据降维原理及python应用(葡萄酒案例分析)

    LDA内部逻辑实现步骤
  • 标准化d维数据集。
  • 计算每个类别的d维均值向量。
  • 计算跨类散布矩阵 
    import pandas as pd
    import numpy as np
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    import matplotlib.pyplot as plt
    
    # load data
    df_wine = pd.read_csv('D:\\PyCharm_Project\\maching_learning\\wine_data\\wine.data', header=None)  # 本地加载
    # df_wine=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',header=None)#服务器加载
    
    # split the data,train:test=7:3
    x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, stratify=y, random_state=0)
    
    # standardize the feature 标准化单位方差
    sc = StandardScaler()
    x_train_std = sc.fit_transform(x_train)
    x_test_std = sc.fit_transform(x_test)
    
    # 计算均值向量
    np.set_printoptions(precision=4)
    mean_vecs = []
    for label in range(1, 4):
    mean_vecs.append(np.mean(x_train_std[y_train == label], axis=0))
    # print("Mean Vectors %s:" % label,mean_vecs[label-1])
    
    # 计算类内散布矩阵
    k = 13
    Sw = np.zeros((k, k))
    for label, mv in zip(range(1, 4), mean_vecs):
    Si = np.zeros((k, k))
    # for row in x_train_std[y_train==label]:
    #     row,mv=row.reshape(n,1),mv.reshape(n,1)
    #     Si+=(row-mv).dot((row-mv).T)
    Si = np.cov(x_train_std[y_train == label].T)
    Sw += Si
    # print("类内散布矩阵:",Sw.shape[0],"*",Sw.shape[1])
    # print("类内标签分布:",np.bincount(y_train)[1:])
    
    # 计算跨类散布矩阵
    mean_all = np.mean(x_train_std, axis=0)
    Sb = np.zeros((k, k))
    for i, col_mv in enumerate(mean_vecs):
    n = x_train[y_train == i + 1, :].shape[0]
    col_mv = col_mv.reshape(k, 1)  # 列均值向量
    mean_all = mean_all.reshape(k, 1)
    Sb += n * (col_mv - mean_all).dot((col_mv - mean_all).T)
    # print("跨类散布矩阵:", Sb.shape[0], "*", Sb.shape[1])
    
    # 计算广义特征值
    eigen_vals, eigen_vecs = np.linalg.eig(np.linalg.inv(Sw).dot(Sb))
    eigen_pairs = [(np.abs(eigen_vals[i]), eigen_vecs[:, i]) for i in range(len(eigen_vals))]
    eigen_pairs = sorted(eigen_pairs, key=lambda k: k[0], reverse=True)
    # print(eigen_pairs[0][1][:,np.newaxis].real) # 第一特征向量
    # print("特征值降序排列:")
    # for eigen_val in eigen_pairs:
    #     print(eigen_val[0])
    
    # 线性判别捕捉,计算辨识力
    tot = sum(eigen_vals.real)
    discr = []
    # discr=[(i/tot) for i in sorted(eigen_vals.real,reverse=True)]
    for i in sorted(eigen_vals.real, reverse=True):
    discr.append(i / tot)
    # print(discr)
    cum_discr = np.cumsum(discr)  # 计算累加方差
    # plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
    # plt.bar(range(1,14),discr,alpha=0.5,align='center',label='独立辨识力')
    # plt.step(range(1,14),cum_discr,where='mid',label='累加辨识力')
    # plt.ylabel('"辨识力"比')
    # plt.xlabel('线性判别')
    # plt.ylim([-0.1,1.1])
    # plt.legend(loc='best')
    # plt.show()
    
    # 转换矩阵
    w = np.hstack((eigen_pairs[0][1][:, np.newaxis].real, eigen_pairs[1][1][:, np.newaxis].real))
    # print(w)
    
    # 样本数据投影到低维空间
    x_train_lda = x_train_std.dot(w)
    colors = ['r', 'g', 'b']
    marks = ['s', 'x', 'o']
    for l, c, m in zip(np.unique(y_train), colors, marks):
    plt.scatter(x_train_lda[y_train == l, 0],
    x_train_lda[y_train == l, 1] * -1,
    c=c, label=l, marker=m)
    plt.xlabel('LD 1')
    plt.ylabel('LD 2')
    plt.legend(loc='lower right')
    plt.show()
    View Code

     

    结语

    这篇记录了这几天学习的LDA实现数据降维的方法,仍然以葡萄酒数据集为案例,在上面一步步的拆分中,我们更加清楚线性判别分析LDA方法的内部实现,在这个过程,对于初步学习的我感觉能够认识和理解更深刻,当然以后数据处理使用LDA方法时候会用到一些第三方库的类,实现起来更加方便,加油学习,期待下一篇LDA实现更简洁的方法!

    我的博客园:https://www.cnblogs.com/chenzhenhong/p/13504526.html

    我的CSDN博客:原创 LDA数据压缩原理及python应用(葡萄酒案例分析)

     

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/Charzous/article/details/108007441

     

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: