机器学习-一篇入门

【算法】一篇入门之-LDA线性判别

作者 : 老饼 发表日期 : 2023-07-06 02:09:08 更新日期 : 2024-10-16 15:17:56
本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com



LDA线性判别分析是机器学习中的一种降维技术与类别判别方法,它应用于有类别标签的样本

本文先介绍LDA,再讲解LDA应用于变量降维、应用于类别判别的原理,最后展示LDA的代码实现例子

通过本文可以快速了解LDA线性判别是什么,以及如何使用LDA来对变量降维、对样本类别进行判别




    01.什么是线性判别LDA    




本节讲解LDA是什么,以及LDA的判别成份与成份贡献是什么





        什么是LDA线性判别         


LDA(Linear Discriminant Analysis)全称为线性判别分析,它只应用于有类别标签的数据
 LDA是什么
LDA的数学作用是使用一个线性变换A,对中心化后的X进行转换
使得转换后的数据Y的类内协方差为单位矩阵,类间协方差为对角矩阵
 即,LDA的模型表达式为:
 
其中,Y满足:
  ,
 D是一个对角矩阵,且对角元素由大到小排列,即
如何理解LDA变换的意义
 声明:下面以不太严谨的说法来描述LDA对数据变换之后的意义
 
经LDA变换后,类间协方差为对角矩阵,则代表每个类别中心在各维之间互不相关
 而类内协方差为,则代表独立看每类样本,各维之互不相关的,且每维方差为1
 LDA的几何意义
即每类样本在内部各维方差都为1,且互不相关,而每类样本的中心在各维也互不相关






     LDA的求解方法      


事实上,LDA中的A的求解拆分为两步:
1. 先找出一个,令中心化的X满足协方差为单位矩阵                      
2. 找出一个,进一步使A1变换后的数据满足类间协方差为对角矩阵
最后就可得到所要找的LDA变换
LDA的求解公式和推导略为复杂,在此省略,详见《》







    02. LDA的判别成份与贡献     




本节介绍LDA的判别成份与成份贡献,进一步理解LDA的意思





       LDA的意义-判别成份与成份贡献       


下面先讲解类间方差的意义,再进一步解释LDA的判别成份与成份贡献
类间方差的意义

由于每一维的类间方差代表类别中心在该维的离散程度,越大越易于区分是哪个类别
 类间方差的意义
因此各维的类间方差代表了它所包含的"类别信息",越大代表包含越多"类别信息"
 极致地,类间方差为0时则类别中心在该维没有任何区别,该维也就没任何类别信息
 LDA的判别成份与成份贡献  
一般把LDA变换后的各个称为判别成份(component),第i个y称为第i个判别成份
由于LDA的类间协方差D为对角矩阵,可知每个包含的"类别信息"是纯粹、不重叠的
  因此,定义判别成份的判别成份贡献为:
 
  其中,的类间方差,即类间协方差矩阵的第个对角元素
由于类间协方差矩阵D的对角元素由大到小排序,故的贡献也由大到小





        如何直观地理解LDA判别分析         


 根据上述分析,可以将LDA理解为从X中抽出一个个包含着类别判别信息的
 LDA的意义
每个y都独立地包含着一部分X中蕴含的类别信息 ,第i个y包含的判别信息占比为
因此,使用LDA来将X转换为y,可以更方便我们分析样本的类别信息以及类别信息的构成







    03. LDA线性判别的用途     




本节讲解LDA线性判别如何应用于变量降维与类别判别





       LDA的用途-变量降维       


由于LDA的成份贡献代表了一个判别成份里包含了多少X中用于区分类别的信息 
因此,我们可以通过忽略掉一些贡献过少的判别成份,从而起到降维的作用
 LDA应用于变量降维
注意到 的贡献由大到小排列,因此在实际操作中,只要截取前k列即可
备注:截取y的前k列,实际也就是截取A的前k列,即





     LDA的用途-类别判别     


LDA用于类别判别,是指将X进行LDA转换为y后,再利用贝叶斯线性判别模型进行类别判别
 这是因为贝叶斯线性判别模型要求类内协方差矩阵为,而经过转换后的y适用于这一条件
 LDA的用途-类别判别
其中,贝叶斯线性判别函数如下:
 
                   (1)
             其中,:Y第k类样本的中心,即第k类样本的均值        
                                      :样本属于类别k的概率 ,即第k类样本在总样本的占比     
 即先用LDA将X转为y,再用(1)式得到各类别的判别值,判别值最大的类别就是样本所属类别
LDA面向x的判别函数
如果想直接对x判别,而不是对y进行判别,则可以使用下式:
  
 其中
  
                                                   
   其中, :X第k类样本的中心,即第k类样本的均值
                                :X第k类样本LDA变换后的中心,即第k类样本的均值 
  :X的中心,即的均值                 
   :LDA中的变换矩阵A                     
                                    :样本属于类别k的概率 ,即第k类样本在总样本的占比     
 推导过程如下:
        将 们代入(1)式,则可得到:
                                    
从上述结果,即可得到线性判别的系数与阈值







    04. LDA的代码实现    




本节展示如何使用LDA线性判别进行降维的代码实现例子





       LDA线性判别-代码实现     


在sklearn中使用LinearDiscriminantAnalysis可以构建一个LDA模型,
当solver=svd 时,LDA使用的算法是类间协方差对角化,solver=eigen 时,使用的算法则是Fisher-LDA
 LDA的具体实现代码如下:
'''
sklearn使用LDA的例子
'''
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

#加载数据
iris = datasets.load_iris()                                           # 加载iris数据
X = iris.data                                                         # 用于建模的X
y = iris.target                                                       # 用于建模的y
target_names = iris.target_names                                      # 各个类别的名称
																	  
#------------LDA线性判别模型训练与预测-----------------             
# solver=svd   时,使用的算法是类间协方差对角化                        
# solver=eigen 时,使用的算法是Fisher-LDA                             
lda = LinearDiscriminantAnalysis(n_components=2,solver='svd')         # 初始化LDA,n_components代表降到多少维
clf = lda.fit(X, y)                                                   # 训练LDA模型
Xt = clf.transform(X)                                                 # 用训练好的LDA对数据进行降维
pred_y = clf.predict(X)                                               # 用训练好的LDA进行类别预测

#------------打印结果-----------------
# 降维函数transform就是(X-clf.xbar_)@clf.scalings_[:,:n_components]
# 判别函数predict  就是(X@clf.coef_.T+clf.intercept_).argmax(axis=1)
print('\n各维贡献占比p=',clf.explained_variance_ratio_)               # 贡献占比
print('\n样本均值xbar=',clf.xbar_)                                    # 样本均值
print('\n变换矩阵A=',clf.scalings_)                                   # 变换矩阵A,A的列并不全是有效的,只有前K-1列有效,K是类别个数
print('\n判别模型系数W=',clf.coef_)                                   # 用于判别的模型系数
print('\n判别模型阈值b=',clf.intercept_)                              # 用于判别的阈值
																    
# 各类别在降维后(新特征空间)的样本分布                            
plt.figure()                                                          # 初始化画布
colors = ["navy", "turquoise", "darkorange"]                          # 设置颜色
for color, i, target_name in zip(colors, [0, 1, 2], target_names):    # 逐类别画出样本点
    plt.scatter(Xt[y==i,0],Xt[y==i,1],color=color,label=target_name)  # 画出样本点,并以颜色标示类别
plt.legend(loc="best", shadow=False, scatterpoints=1)                 # 设置图例
plt.rcParams["font.sans-serif"] = ["SimHei"]                          # 设置中文
plt.rcParams['axes.unicode_minus'] = False                            # 设置坐标轴负号显示方式
plt.rcParams["figure.figsize"] = (2, 4)                               # 设置figure_size尺寸
plt.title("各类别在降维后(新特征空间)的分布")                         # 设置标题
plt.show()
运行结果如下:
 LDA降维的效果  
LDA代码运行结果
从图中可以看到,进行LDA转换后,在横轴就已经能很好地区分类别了,而纵轴则没什么区分
从各维贡献占比也可以看出,第一维的类别信息贡献已经达到了99%,第二维只有0.8%,基本没什么用
 因此,在该例中,其实只需要一维,就足以表示类别信息了,因此建模时可以只取第1个判别成份进行建模
从打印结果可知,最终得到的LDA变换与判别模型如下:
 
一、 LDA变换                                                                                        
对x进行LDA变换的公式如下:                             
           
 
二、LDA判别模型                                                                              
对x进行类别判别时,判别值计算公式如下:                          
                                    












 End 









联系老饼