24/11/2 算法笔记 拆解LDA

发布于:2024-11-03 ⋅ 阅读:(121) ⋅ 点赞:(0)

LDA大致的理解就是:找到一条直线,同类别样例到投影点尽可能接近,不同类别尽可能远离

以下是几个关键点:

1.投影:

2.类间散度矩阵:考虑使用不同样例的投影点远,要一个标准来衡量类间的距离

LDA采用两个类别的均值向量μ i ,    i ∈ { 0 , 1 } 在直线上的投影间的距离:

内积是投影,上面是两个投影间的距离。

3.类内散度矩阵,表示同类样例的投影

方差:度量一组数据间离散程度,方差越大越分散

协方差:一维样本,求出的就是方差

              二维样本,反映两维度相关性

              三维样本,各个维度总体相关性

4.目标函数

根据LDA的目标,我们需要使得同类样例间的投影点尽可能接近,即使得w^T Sw​W尽可能小,

异类样例间的投影点尽可能远离,即使得 w^TS_bw尽可能大,综合可以得到目标函数j

代码复现:

class LDA(object):
    """
    线性判别分析
    """
    def __init__(self,data,target,d) -> None:
        self.data = data
        self.target = target
        self.d = d
        self.labels = set(target)
        self.mu = self.data.mean(axis=0)
    def device(self):
        """
        功能:将传入的数据集按target分成不同的类别集合并求出对应集合的均值向量
        """
        self.classify,self.classmu = {},{}
        for label in self.labels:
            self.classify[label] = self.data[self.target ==label]
            self.classmu[label] = self.classify[label].mean(axis = 0)
    def getSt(self):
        """
        功能:计算全局散度矩阵
        """
        self.St = np.dot((self.data-self.mu).T,(self.data-self.mu))

    def getSb(self):
        """
        功能:计算类内散度矩阵
        """
        self.Sb = np.zero((self.data.shape[1],self.data.shape[1]))
        for i in self.labels:
            #获取类别i样例集合
            classi = self.classify[i]
            #获取类别i的均值向量
            mui = self.classmu[i]
            self.Sb += len(classi)*np.dot((mui - self.mu)reshape(-1,1),(mui - self.mu).reshape(1,-1))

    def getW(self):
        """
        功能:计算w
        """
        self.divide()
        self.getSt()
        self.getSb()
        #St = Sw +Sb
        self.Sw = self.St - self.Sb
        #计算Sw-1*Sb 的特征值和特征向量
        #eig_vectors[:i]与 eig_values相对应
        eig_values, eig_vectors = np.linalg.eig(np.linalg.inv(self.Sw).dot(self.Sb))
        #寻找d个最大非零广义特征值
        topd = (np.argsort(eig_values)[::-1])[:self.d]
        #用d个最大非零广义特征值组成的向量组成w
        self.w = eig_vectors[:,topd]
        


网站公告

今日签到

点亮在社区的每一天
去签到