线性判别分析LDA:详解及数学原理

本文介绍了线性判别分析(LDA)的基本思想和数学原理,它是一种用于监督学习的降维技术。LDA旨在通过最大化类间散度和最小化类内散度来寻找最佳投影方向。文章详细阐述了LDA的目标函数,并通过Python代码展示了如何计算投影向量,从而将数据投影到低维空间中,以实现分类和可视化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


简介

        线性判别分析 (Linear Discriminant Analysis,简称 LDA)是一种经典的线性学习方法。并且LDA是一种监督学习降维技术

思想:
        给定训练样例集,设法将样例投影到一条直线上,使得同类样例的投影点尽可能接近、 异类样例 的投影点尽可能远离(有些像中心损失的思想)。
        在对新样本进行分类时,将其投影到 同样的这条直线上,再根据投影点的位置来确定新样本的类别。
在这里插入图片描述

数学分析

        给定数据集 D ∈ { ( X i , Y i ) } i − 1 m D\in \lbrace(Xi , Yi)\rbrace^m_{i-1} D{(XiYi)}i1m,旦 Y i ∈ { 0 , 1 } Y_i \in\lbrace {0, 1 }\rbrace Yi{01} , 令 X i , μ i , Σ i X_i,\mu_i,\Sigma_i Xi,μi,Σi 分别表示第 i ∈ { 0 , 1 } i\in \lbrace{0 , 1}\rbrace i{01} 类样例的集合、均值向量、协方差矩阵。

这里小小的回忆一下协方差与协方差矩阵: 协方差矩阵是一个矩阵,其每个元素是各个向量元素之间的协方差。而协方差描述了向量之间的相关程度(关于协方差,可以看这篇博客写的很好:终于明白协方差的意义了

        若将数据投影到直线 w w w上 ,则两类样本的中心在直线上的投影分别为 w T μ 0 w_Tμ_0 wTμ0 w T μ 1 w_Tμ_1 wTμ1

        若将所有样本点都投影到直线上,则两类样本的协方差分别为 w T Σ 0 w w_T\Sigma_0w wTΣ0w w T Σ 1 w w_T\Sigma_1w wTΣ1w

        欲使同类样例的投影点尽可能接近,可以让同类样例投影点的协方差尽可能小:即 w T Σ 0 w + w T Σ 1 w w_T\Sigma_0w+w_T\Sigma_1w wTΣ0w+wTΣ1w 尽可能小

        使异类样例的投影点尽可能远离,类中心之间的距离尽可能大,即: ∣ ∣ w T μ 0 − w T μ 1 ∣ ∣ 2 2 ||w_Tμ_0-w_Tμ_1||^2_2 wTμ0wTμ122 尽可能大( ∣ ∣ ⋅ ∣ ∣ 2 2 ||\centerdot ||^2_2 22 为L2范数的平方)

        同时考虑二者,即最大化下式:
在这里插入图片描述
类内散度矩阵:

在这里插入图片描述
类问散度矩阵:

在这里插入图片描述
J J J函数可重写为:

在这里插入图片描述
也被称为 S b S_b Sb S w S_w Sw 的"广义瑞利商"

那么 w w w如何求呢

        对于广义瑞利商,分子分母上的 w T ∗ ∗ w w^T**w wTw,只与其方向有关,我们可以将 w T S w w w^TS_ww wTSww看作1,因此最大化原函数 J J J变为最小化:
在这里插入图片描述
由拉格朗日乘子法,上式等价于:
在这里插入图片描述
S b w S_bw Sbw 的方向恒为 μ 0 − μ 1 μ_0- μ_1 μ0μ1,令:
在这里插入图片描述
w w w
在这里插入图片描述

Python实现简单的LDA

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification

def func(x, w):
    return np.dot((x), w)

def LDA(X, y):
    # 根据标签分为两个数据集
    X1 = np.array([X[i] for i in range(len(X)) if y[i] == 0])
    X2 = np.array([X[i] for i in range(len(X)) if y[i] == 1])

    len1 = len(X1)
    len2 = len(X2)
    # 求中心点
    X1_Center = np.mean(X1, axis=0)
    print(X1_Center)
    X2_Center = np.mean(X2, axis=0)
    print(X2_Center)
    # 求协方差
    cov1 = np.dot((X1 - X1_Center ).T, (X1 - X1_Center ))
    cov2 = np.dot((X2 - X2_Center).T, (X2 - X2_Center))
    # 求类内散度
    Sw = cov1 + cov2
    # 求w
    # np.mat()将输入解释为一个矩阵
    # np.mat().I求逆
    w = np.dot(np.mat(Sw).I, (X1_Center - X2_Center).reshape((len(X1_Center), 1)))

    # 输出
    X1_new = func(X1, w)
    X2_new = func(X2, w)
    y1_new = [1 for i in range(len1)]
    y2_new = [2 for i in range(len2)]
    return X1_new, X2_new, y1_new, y2_new

if '__main__' == __name__:
    X, y = make_classification(n_samples=500, n_features=2, n_redundant=0, n_classes=2,
                               n_informative=1, n_clusters_per_class=1, class_sep=0.5, random_state=10)

    X1_new, X2_new, y1_new, y2_new = LDA(X, y)

    plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
    plt.show()

    plt.plot(X1_new, y1_new, 'b*')
    plt.plot(X2_new, y2_new, 'ro')
    plt.show()

下面是均值向量输出:

[-4.91767118e-01 -4.15692170e-04]
[ 0.50795852 -0.12563275]

原始数据分布:
在这里插入图片描述
经过LDA后的数据分布:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂奔的菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值