线性判别分析(Linear Discriminate Analysis, LDA)通过正交变换将一组可能存在相关性的变量降维变量,目标是将高维数据投影至低维后,同类的数据之间距离尽可能近、不同类数据之间距离尽可能远。
应用场景:
对于拟合、分类算法,可以利用主成分分析对输入数据实现降维,去除冗余数据可以提高计算效率并提高计算精度;
对于难以进行可视化的高维数据可以利用主成分分析映射至二维进行可视化,方便进行展示,如果需要展示的数据从属于多个类别,LDA的降维效果优于PCA。
由于LDA本身降维时就以分离不同类数据为目的,因此对于二分类问题可以直接降至一维进行分类。
缺点:
利用LDA降维时有最大维数限制,若输入数据的总类别数为 C C C则最大维数是 C − 1 C-1 C−1,这意味着在对高维但类别数较少的问题进行降维时LDA可能会导致大量信息的丢失。
符号约定:
记总样本个数为 n n n,每个初始样本所含特征数为 N N N,最终选择的主成分所含特征数为 K K K
记第 i i i个样本的第 j j j个特征为: x i j x_{ij} xij
记 n n n个初始样本为: X 1 , X 2 , . . . , X n X_1,X_2,...,X_n X1,X2,...,Xn
每个初始样本为一个 N N N维向量,第 i i i个样本为 X i = [ x i 1 x i 1 . . . x i N ] X_i=\begin{bmatrix}x_{i1} &x_{i1} & ... &x_{iN} \end{bmatrix} Xi=[xi1xi1...xiN]
记降维后的样本为: Y 1 , Y 2 , . . . , Y n Y_1,Y_2,...,Y_n Y1,Y2,...,Yn,每个主成分同样是 K K K维向量
设样本共有 C C C类,第 i i i类含有的样本数为 n i n_i ni
计算流程:
第一步:计算类内均值与总均值
类内均值为:
u i = 1 n i ∑ X ∈ c l a s s i X u_i=\frac{1}{n_i}\sum_{X\in{class i}}{X} ui=ni1X∈classi∑X
类间均值为:
u = 1 n ∑ i = 1 n X i u=\frac{1}{n}\sum_{i=1}^n{X_i} u=n1i=1∑nXi
类内均值与类间均值均为 N N N维向量
第二步:计算类间散度矩阵 S b S_b Sb与类内散度矩阵 S W S_W SW
类间散度矩阵为:
S b = ∑ i = 1 C n i ( u i − u ) ( u i − u ) T S_b=\sum_{i=1}^{C}n_i(u_i-u)(u_i-u)^T Sb=i=1∑Cni(ui−u)(ui−u)T
类内散度矩阵为:
S w = ∑ i = 1 C ∑ X k ∈ c l a s s i ( u i − X k ) ( u i − X k ) T S_w=\sum_{i=1}^{C}\sum_{X_k\in{classi}}(u_i-X_k)(u_i-X_k)^T Sw=i=1∑CXk∈classi∑(ui−Xk)(ui−Xk)T
类间散度矩阵 S b S_b Sb与类内散度矩阵 S W S_W SW均为 N N N阶方阵。类间散度矩阵 S b S_b Sb实质上是各类数据均值的协方差矩阵,类内散度矩阵 S W S_W SW实质上是各类数据的协方差矩阵的平均值。
第三步:计算矩阵 S w − 1 S b S_w^{-1}S_b Sw−1Sb的特征值与特征向量
我们希望类内数据的散度尽可能小,而各类数据均值的散度尽可能大,因此构造矩阵 S = S w − 1 S b S=S_w^{-1}S_b S=Sw−1Sb
计算矩阵 S S S的特征值并将其由大到小排列,记为 λ 1 , … λ ( C − 1 ) λ_1,…λ_(C-1) λ1,…λ(C−1)记其对应的特征量为 v 1 , … v ( C − 1 ) v_1,…v_(C-1) v1,…v(C−1)
矩阵 S S S仅有 C − 1 C-1 C−1个特征向量的原因是, u i ( i = 1 , 2 , . . . , C ) u_i(i=1,2,...,C) ui(i=1,2,...,C)与 u u u是线性相关的,因此 S b S_b Sb的秩为 C − 1 C-1 C−1,进而 S S S的秩也仅为 C − 1 C-1 C−1
第四步:对初始特征进行线性变换
选取前K个特征值对应的特征向量,组成投影矩阵:
W = [ v 1 , … , v K ] W=[v_1,…,v_K] W=[v1,…,vK]
则新样本为:
[ Y 1 , … , Y n ] = W T [ X 1 , … , X n ] [Y_1,…,Y_n ]=W^T [X_1,…,X_n] [Y1,…,Yn]=WT[X1,…,Xn]
利用sklearn库中的函数实现线性判别分析
所选数据为39节点电网仿真数据,包含5000个样本,每个样本包含160个特征量,即 n = 5000 , N = 160 n=5000, N=160 n=5000,N=160
这些样本根据运行状态可以被分为三类,即:稳定、不稳定、潮流不收敛,因此经过LDA降维后至多保留两个特征
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
test_features, test_labels = read_data(ADDRESS)
#从地址ADDRESS读取初始特征与标签,此函数为自定义函数
lda = LDA(n_components=2)
#创建LDA类,参数n_components为主成分所含特征数,令其为'mle'则自动选取特征数,由于原始数据只有3类,因此特征最多只能保留两个
lda_feature = lda.fit_transform(test_features)
#得到线性变换后的2个特征
for i in range(2):
print(lda.explained_variance_ratio_[i])
#lda.explained_variance_ratio_为2个特征向量
LDA
类的参数n_components
为主成分包含的特征数,默认为1,也可以设定为字符串’mle’自动选取特征数
函数pca.fit_transform
函数输入值为原始数据,输出为主成分,同时将会利用输入的原始数据训练模型
pca.explained_variance_ratio_
为得到的 K K K个特征向量
利用得到的两个特征向量作图,可以得到如下结果:
可以看出三类样本在映射后的平面上分离程度较高
如果希望利用同样的模型提取新数据的主成分,则可以利用transform
函数实现:
lda_feature = lda.fit_transform(test_features)#利用测试数据训练模型
lda_feature_new=lda.transform(new_data)#利用训练好的模型提取新数据的特征