如何向10岁小孩解释LDA(线性判别分析)算法

文摘   2024-08-12 20:11   广东  

线性判别分析 (LDA) 是一种非常常见的用于监督分类问题的技术,让我们一起了解一下什么是 LDA 以及它是如何工作的。

image-20240812162435586

什么是线性判别分析

LDA是一种降维技术,常用于机器学习和模式分类应用中的预处理步骤。

降维技术的主要目标是通过将特征从高维空间转换到低维空间,移除冗余和相关特征,从而减少数据的维度。

image-20240812162627079

如上图,LDA是一种监督分类技术,它在降维过程中考虑了标签,这类降维技术广泛应用于生物识别、生物信息学和化学等领域,而PCA(主成分分析)是一种非监督的降维方法。

LDA的工作原理

LDA的目标是将高维空间中的特征投影到低维空间。

这可以通过三个步骤来实现:

  • 第一步是计算不同类别之间的可分性(即不同类别均值之间的距离),也称为类间方差。

其中,

  • 第二步是计算每个类别中均值与样本之间的距离,这被称为类内方差。

其中,

  • 第三步是构建一个低维空间,使得类间方差最大化,同时类内方差最小化。记 为低维空间的投影向量,这个过程被称为 Fisher 判别准则 (Fisher’s criterion)。目标函数可以写为:

简单来说,目标函数使不同类投影后的类间方差最大,相同类投影后的类内方差最小,即不同类越远越好,相同类越聚集越好。

如下图,右边的投影向量要好于左边的投影向量。

image-20240812171712151
  • 第四步是求解目标函数最大值对应的投影矩阵P,根据广义瑞利商性质(这里不展开),当投影向量满足下面等式时,目标函数达到最大。

根据的公式,我们知道在数据集给定的情况下,是已知的。因此上述方程是已知矩阵的特征向量和特征值求解,比较简单,不懂的可以看看线性代数的特征向量和特征值的求解方法。

LDA代码实战

代码的数据集是银行票据鉴定数据集,该数据集公开可在 UCI 机器学习库中获取(https://archive.ics.uci.edu/ml/datasets/banknote+authentication#)。

数据集中包含的属性有:小波变换图像的方差(连续型)、小波变换图像的偏度(连续型)、小波变换图像的峰度(连续型)、图像的熵(连续型),以及类别(整数型,0-非真实,1-真实)。

在开始LDA之前,首先导入所有必要的依赖项。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

现在使用 Pandas 的 read_csv 函数将数据集加载到 DataFrame 中。

columns = ["var","skewness","curtosis","entropy","class"]
df = pd.read_csv("http://archive.ics.uci.edu/ml/machine-learning-databases/00267/\
data_banknote_authentication.txt"
,index_col=False, names = columns)

数据集包含总共 1372 个实例,其中 762 个是非真实票据,610 个是真实票据。属性的数据分布可以通过单变量和多变量图来查看:

f, ax = plt.subplots(14, figsize=(10,3))
vis1 = sns.distplot(df["var"],bins=10, ax= ax[0])
vis2 = sns.distplot(df["skewness"],bins=10, ax=ax[1])
vis3 = sns.distplot(df["curtosis"],bins=10, ax= ax[2])
vis4 = sns.distplot(df["entropy"],bins=10, ax=ax[3])
f.savefig('subplot.png')

image-20240812191557469
sns.pairplot(df, hue="class")

image-20240812193439502

现在,我们将计算两个类别的四维均值向量(4 = 特征数量)。与 PCA 不同,在 LDA 中不需要对数据进行标准化,因为标准化不会影响结果。LDA 的主要结果不受标准化影响的原因是,LDA 处理的是类间协方差与类内协方差的比率,而不是协方差的绝对值(如 PCA 所做的那样)。

mean_vec = []
for i in df["class"].unique():
    mean_vec.append( np.array((df[df["class"]==i].mean()[:4]) ))
print(mean_vec)

下一步是计算类间矩阵()和类内矩阵():

SW = np.zeros((4,4))
for i in range(1,4): #2 is number of classes
    per_class_sc_mat = np.zeros((4,4))
    for j in range(df[df["class"]==i].shape[0]):
        row, mv = df.loc[j][:4].reshape(4,1), mean_vec[i].reshape(4,1)
        per_class_sc_mat += (row-mv).dot((row-mv).T)
    SW += per_class_sc_mat
print('within-class Scatter Matrix:\n', SW)
overall_mean = np.array(df.drop("class", axis=1).mean())
SB = np.zeros((4,4))
for i in range(2): #2 is number of classes
    n = df[df["class"]==i].shape[0]
    mv = mean_vec[i].reshape(4,1)
    overall_mean = overall_mean.reshape(4,1# make column vector
    SB += n * (mv - overall_mean).dot((mv - overall_mean).T)
print('between-class Scatter Matrix:\n', SB)

然后求的特征值和特征向量:

e_vals, e_vecs = np.linalg.eig(np.linalg.inv(SW).dot(SB))
print('Eigenvectors \n%s' %e_vecs)
print('\nEigenvalues \n%s' %e_vals)

现在,我们需要选择与前-k 个特征值对应的前-k 个特征向量。选择 k 的标准取决于每个方向上可能保留的方差量。对于数据压缩,我们通常选择保留 99% 方差的维度,而对于可视化,我们将维度设置为 2 或 3。在这里,我们将选择前两个特征值对应的特征向量用于可视化。由于最大的特征值对应的特征向量几乎保留了 100% 的方差,因此可以忽略其他三个特征值。变换矩阵 将是:

W = np.hstack((e_vecs[0][1].reshape(4,1), e_vecs[1][1].reshape(4,1)))
print('Matrix W:\n', W.real)

现在,我们需要将 4 维特征空间  转换为 2 维特征子空间

X_lda = X.dot(W)
df["PC1"] = X_lda[:,0]
df["PC2"] = X_lda[:,1]

可视化lda降维后的数据分布:

vis = sns.lmplot(data = df[["PC1","PC2","class"]], x = "PC1", y = "PC2",fit_reg=False, hue = "class",\
                 size = 6, aspect=1.5, scatter_kws = {'s':50}, )
vis.savefig("lda.png")

image-20240812194535106

显示变量和类别的数据分布:

sns.pairplot(df[["PC1","PC2","class"]], hue="class")

image-20240812194657140

从上述图中可以看出,只用 PC1 就足以有效地区分两个类别

也可以使用scikit-learn库实现LDA:

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
model = LDA(n_components=3)
X_lda = model.fit_transform(X, y)
df["PC1"] = X_lda[:,0]
sns.regplot(data = df[["PC1","class"]], x = "PC1",y = "class", fit_reg=False,scatter_kws = {'s':50}, )

image-20240812194950155

在这里我们可以看到,LDA降维后的第一个特征就能够很好的区分类别。

结论

LDA算法既可以用来降维,又可以用来分类,但是目前来说,主要还是用于降维。在我们进行图像识别相关的数据分析时,LDA是一个有力的工具。

欢迎扫码关注:

机器学习实战
多名大厂算法工程师共同运营,主要专注机器学习算法、深度学习算法、计算机视觉等领域技术干货分享,一天进步一点点
 最新文章