前言
机器学习的东西真是又多又杂啊,之前刷吴恩达就见过主成分分析,即PCA(Principle Component Analysis),没见过线性判别分析,即LDA(Linear Discriminant Analysis)。才知道前者是对无标签数据作压缩的,而后者可以对有标签的二分类、多分类任务的数据作压缩。
本文主要讲述了LDA算法的推导,以及展示了LDA算法的代码实现和应用。
参考资料:
周志华《机器学习》,人称西瓜书
更详细的算法推导:机器学习算法推导&手写实现03——线性判别分析 - 知乎 (zhihu.com)
一、算法推导
由前言可知,LDA相比于PCA,是用来处理有标签数据的,为了使压缩后的数据仍然能表示分类的情况,我们应该让同类的样本尽可能靠近,异类的样本尽可能远离。
数学表示为:给定数据集D={xi,yi}i=1m,该数据集共有m个样本,每个样本包含一个数据,即一个n维的向量xi,以及一个标签,即一个数yi,代表该数据点所在的类别。
当yi∈{0,1},说明这是一个二分类任务,我们先从简单的二分类开始讨论。
1. 二分类
1.1 优化目标
接下来,我们要用数学语言来表示同类的样本尽可能靠近,异类的样本尽可能远离这两个任务。
同类的样本尽可能靠近,也就是同类之间的方差要尽可能小
设压缩前,两个类的协方差矩阵分别为Σ0和Σ1
那么,压缩后的两个类的协方差矩阵为ωTΣ0ω和ωTΣ1ω
定义“类内散度矩阵”(with-class scatter matrix)为
Sω=Σ0+Σ1=x∈X0∑(x−μ0)T+x∈X1∑(x−μ1)T
那么,同类之间的方差要尽可能小,就是要最小化ωTSωω
异类的样本尽可能远离,也就是异类样本的均值的差值要尽可能大
设压缩前,两个类的均值分别为μ0和μ1
那么,压缩后的两个类的均值为ωTμ0和ωTμ1
定义“类间散度矩阵”(between-class scatter matrix)为
Sb=(μ0−μ1)(μ0−μ1)T
那么,异类的样本尽可能远离,就是要最大化ωTSbω
将上述两条件统一到一个式子,我们的优化目标就变为了
最大化 J=ωTSωωωTSbω
1.2 数学推导
由于J=ωTSωωωTSbω分子分母都是关于ω的二次项,因此,求解上述问题与ω的大小无关,只与ω的的方向有关。
我们不妨假设ωTSωω=1,问题转化为
minω −ωTSbω
st. ωTSωω=1
由拉格朗日乘子法,得
L(ω)=−ωTSbω+λ(ωTSωω−1)
令 ∂ω∂L(ω)=−2Sbω+2λSωω=0
得 Sbω=λSωω 1◯
又 Sbω=(μ0−μ1)(μ0−μ1)Tω,其中(μ0−μ1)Tω可看作是个标量,因此Sbω的方向恒与μ0−μ1相同,不妨令
Sbω=λ(μ0−μ1) 2◯
由1◯2◯得
Sωω=μ0−μ1
ω=Sω−1(μ0−μ1)
在实践中,常常对Sω做奇异值分解:Sω=UΣVT,故有Sω−1=VΣ−1UT,从而得到Sω−1
2. 多分类
2.1 问题求解
将问题扩展到多分类,定义所有样本的均值为μ,每个类对应的样本数量为mi,那么重新定义“类间散度矩阵”为
Sb=i=1∑Nmi(μi−μ)(μi−μ)T
设总共由N个类,重新定义“类内散度矩阵”为
Sω=i=1∑Nx∈Xi∑(x−μi)(x−μi)T
在上述二分类中,我们将样本投影到一维空间,也就是一条直线上,而在多分类中,我们将样本投影到N−1维空间,记投影矩阵 W∈Rd×(N−1),其中d表示原样本的维度数。
同理可得
SbW=λSωW
Sω−1SbW=λW
因此W的解是Sω−1Sb的最大N−1个特征值所对应特征向量所组成的矩阵
2.2 全局散度矩阵
除了使用Sb和Sω作为度量的标准,多分类LDA还可以有多种不同的实现,引入“全局散度矩阵”
St=i=1∑m(xi−μ)(xi−μ)T
可以证明 St=Sb+Sω,如下:
Sb=i=1∑Nmi(μi−μ)(μi−μ)T=i=1∑Nmi(μiμiT−μμiT−μiμT+μμT)
其中,miμμiT==x∈Xi∑μxT,miμiμT=x∈Xi∑XμT,那么有
Sb=i=1∑Nx∈Xi∑(μiμiT−μxT−xμT+μμT)
又有
Sω=i=1∑Nx∈Xi∑(x−μi)(x−μi)T=i=1∑Nx∈Xi∑(xxT−μixT−xμiT+μiμiT)
那么,
Sb+Sω=i=1∑Nx∈Xi∑(xxT−μxT−xμT+μμT−μixT−xμiT+2μiμiT)
其中,i=1∑Nx∈Xi∑(−μixT−xμiT+2μiμiT)=0
则有
Sb+Sω=i=1∑Nx∈Xi∑(xxT−μxT−xμT+μμT)=i=1∑Nx∈Xi∑(x−μ)(x−μ)T=i=1∑m(xi−μ)(xi−μ)T=St
证毕
3. 等价模型表示
以上的算法推导是基于maxωωTSωωωTSbω,或者说,基于maxWtr(WTSωW)tr(WTSbW),我们称之为LDA的除法模型。
实际上,LDA还有多种等价的模型表示,比如
(1) 减法模型:
maxWtr(WTSbW)−tr(WTSωW)
st. tr(WTW)=1
求解得到
(Sω−Sb)W=λW
即W是Sω−Sb前N−1个最大特征值对应的特征向量组成的矩阵
(2) 除法正则模型:
maxWtr(WTSωW)tr(WTSbW)+λtr(WTW)
st. tr(WTSωW)=1
由拉格朗日乘子法,得
L=tr(WTSbW)+λtr(WTW)+β(tr(WTSωW)−1)
∂W∂L=2SbW+2λW+2βSωW=0
得
Sω−1(Sb+λI)W=−βW
即W是Sω−1(Sb+λI)前N−1个最大特征值对应的特征向量组成的矩阵
(3) 减法正则模型:
maxWtr(WTSbW)−tr(WTSωW)−λtr(WTW)
st. tr(WTW)=1
求得问题的解仍然是Sω−Sb前N−1个最大特征值对应的特征向量组成的矩阵
二、代码示例
大半都是gpt写的(
X, y = read_data(PATH)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)
accuracy_pca = []
accuracy_lda = []
n_components_range = range(1, 35, 2)
for n_components in n_components_range:
pca = PCA(n_components=n_components)
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.transform(X_test)
knn_pca = KNeighborsClassifier()
knn_pca.fit(X_train_pca, y_train)
y_pred_pca = knn_pca.predict(X_test_pca)
accuracy_pca.append(accuracy_score(y_test, y_pred_pca))
lda = LinearDiscriminantAnalysis(n_components=n_components)
X_train_lda = lda.fit_transform(X_train, y_train)
X_test_lda = lda.transform(X_test)
knn_lda = KNeighborsClassifier()
knn_lda.fit(X_train_lda, y_train)
y_pred_lda = knn_lda.predict(X_test_lda)
accuracy_lda.append(accuracy_score(y_test, y_pred_lda))
fig, ax = plt.subplots()
ax.plot(n_components_range, accuracy_pca, label='PCA')
ax.plot(n_components_range, accuracy_lda, label='LDA')
ax.set_xlabel('n_components')
ax.set_ylabel('Accuracy')
ax.legend()
plt.show()
在ORL数据集的测试结果如下:

其实可以再探讨一下减法模型还有正则模型的性能,但是sklearn貌似不支持(?),得手搓,急着交作业就没再搞了。。