本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com
LDA线性判别分析是机器学习中的一种降维技术与类别判别方法,它应用于有类别标签的样本
本文先介绍LDA,再讲解LDA应用于变量降维、应用于类别判别的原理,最后展示LDA的代码实现例子
通过本文可以快速了解LDA线性判别是什么,以及如何使用LDA来对变量降维、对样本类别进行判别
本节讲解LDA是什么,以及LDA的判别成份与成份贡献是什么
什么是LDA线性判别
LDA(Linear Discriminant Analysis)全称为线性判别分析,它只应用于有类别标签的数据
LDA是什么
LDA的数学作用是使用一个线性变换A,对中心化后的X进行转换
使得转换后的数据Y的类内协方差为单位矩阵,类间协方差为对角矩阵
即,LDA的模型表达式为:
其中,Y满足:
,
D是一个对角矩阵,且对角元素由大到小排列,即
如何理解LDA变换的意义
声明:下面以不太严谨的说法来描述LDA对数据变换之后的意义
经LDA变换后,类间协方差为对角矩阵,则代表每个类别中心在各维之间互不相关
而类内协方差为,则代表独立看每类样本,各维之互不相关的,且每维方差为1
即每类样本在内部各维方差都为1,且互不相关,而每类样本的中心在各维也互不相关
LDA的求解方法
事实上,LDA中的A的求解拆分为两步:
1. 先找出一个,令中心化的X满足协方差为单位矩阵
2. 找出一个,进一步使A1变换后的数据满足类间协方差为对角矩阵
最后就可得到所要找的LDA变换
LDA的求解公式和推导略为复杂,在此省略,详见《》
本节介绍LDA的判别成份与成份贡献,进一步理解LDA的意思
LDA的意义-判别成份与成份贡献
下面先讲解类间方差的意义,再进一步解释LDA的判别成份与成份贡献
类间方差的意义
由于每一维的类间方差代表类别中心在该维的离散程度,越大越易于区分是哪个类别
因此各维的类间方差代表了它所包含的"类别信息",越大代表包含越多"类别信息"
极致地,类间方差为0时则类别中心在该维没有任何区别,该维也就没任何类别信息
LDA的判别成份与成份贡献
一般把LDA变换后的各个称为判别成份(component),第i个y称为第i个判别成份
由于LDA的类间协方差D为对角矩阵,可知每个包含的"类别信息"是纯粹、不重叠的
因此,定义判别成份的判别成份贡献为:
其中,是的类间方差,即类间协方差矩阵的第个对角元素
由于类间协方差矩阵D的对角元素由大到小排序,故的贡献也由大到小
如何直观地理解LDA判别分析
根据上述分析,可以将LDA理解为从X中抽出一个个包含着类别判别信息的
每个y都独立地包含着一部分X中蕴含的类别信息 ,第i个y包含的判别信息占比为
因此,使用LDA来将X转换为y,可以更方便我们分析样本的类别信息以及类别信息的构成
本节讲解LDA线性判别如何应用于变量降维与类别判别
LDA的用途-变量降维
由于LDA的成份贡献代表了一个判别成份里包含了多少X中用于区分类别的信息
因此,我们可以通过忽略掉一些贡献过少的判别成份,从而起到降维的作用
注意到 的贡献由大到小排列,因此在实际操作中,只要截取前k列即可
备注:截取y的前k列,实际也就是截取A的前k列,即
LDA的用途-类别判别
LDA用于类别判别,是指将X进行LDA转换为y后,再利用贝叶斯线性判别模型进行类别判别
这是因为贝叶斯线性判别模型要求类内协方差矩阵为,而经过转换后的y适用于这一条件
其中,贝叶斯线性判别函数如下:
(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)式,则可得到:
从上述结果,即可得到线性判别的系数与阈值
本节展示如何使用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转换后,在横轴就已经能很好地区分类别了,而纵轴则没什么区分
从各维贡献占比也可以看出,第一维的类别信息贡献已经达到了99%,第二维只有0.8%,基本没什么用
因此,在该例中,其实只需要一维,就足以表示类别信息了,因此建模时可以只取第1个判别成份进行建模
从打印结果可知,最终得到的LDA变换与判别模型如下:
一、 LDA变换
对x进行LDA变换的公式如下:
二、LDA判别模型
对x进行类别判别时,判别值计算公式如下:
End