Python:Generalized Discriminant Analysis (GDA) 手工代码实现 Kernel LDA

"""
Auther:Deniu He
Date:2021-03-16
"""
import numpy as np
from sklearn.datasets import load_iris
from sklearn.metrics.pairwise import rbf_kernel
import matplotlib.pyplot as plt
from scipy.linalg import block_diag

class GDA():
    def __init__(self,X,y,gamma):
        self.X = X
        self.y = y
        self.N = self.X.shape[0]    ## the number of training samples
        self.labels = np.unique(y)  ## the labels
        self.nClass = len(self.labels)  ## the number of labels(classes)
        self.nSample = []
        self.nAtt = self.X.shape[1]   ## the number of features(attributes)
        self.m = np.mean(self.X,axis=0)  ## the mean of all samples
        self.Mean = self.get_Mean()
        self.B = self.get_B()
        self.W = self.get_W()
        self.K = rbf_kernel(X=self.X,gamma=gamma)
        print("B::",self.B.shape)
        print("W::",self.W.shape)
        print("K::",self.K.shape)
        # self.L,self.U = np.linalg.eig(np.linalg.pinv(self.W @ self.K)@ (self.B @ self.K))
        self.L, self.U = np.linalg.eig(np.dot(np.linalg.inv(np.dot(self.W,self.K)),np.dot(self.B,self.K)))


    def get_Mean(self):
        Mean = np.zeros((self.nClass,self.nAtt))
        for i, lab in enumerate(self.labels):
            idx_list = np.where(self.y == lab)
            Mean[i] = np.mean(self.X[idx_list],axis=0)
            self.nSample.append(len(idx_list))
        return Mean

    def get_B(self):
        Diag = []
        for i, lab in enumerate(self.labels):
            idx_list = np.where(self.y == lab)
            nSub = np.size(idx_list)
            subMat = np.ones((nSub,nSub)) * (1/nSub)
            if i == 0:
                Diag = block_diag(subMat)
            else:
                Diag = block_diag(Diag,subMat)
        Diag = (1/self.N) * Diag
        B = Diag - (1/self.N)*np.ones((self.N,self.N))
        return B

    def get_W(self):
        A_M = []
        B_M = []
        for i, lab in enumerate(self.labels):
            idx_list = np.where(self.y == lab)
            nSub = np.size(idx_list)
            aMat = np.eye(nSub) * (1/nSub)
            bMat = np.ones((nSub,nSub)) * (1/self.N)
            if i == 0:
                A_M = block_diag(aMat)
                B_M = block_diag(bMat)
            else:
                A_M = block_diag(A_M,aMat)
                B_M = block_diag(B_M,bMat)
        W = A_M - B_M
        return W

    def DR(self,n_component):
        trans_X = []
        ord_ids = np.flipud(np.argsort(self.L))
        for i in range(n_component):
            tar_ids = ord_ids[i]
            u = self.U[:,tar_ids]
            if trans_X == []:
                 trans_X = self.K @ self.U[:,tar_ids] /np.sqrt(u@self.K@u)
            else:
                trans_X = np.vstack((trans_X,self.K @ self.U[:,tar_ids] /np.sqrt(u@self.K@u)))
        return trans_X.T


if __name__ == '__main__':
    X,y = load_iris(return_X_y=True)
    gamma = 10
    gda = GDA(X=X,y=y,gamma=gamma)
    print(gda.DR(n_component=2))

 有些问题:求出的特征值是复数

哪个大神帮忙修改一下

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DeniuHe

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

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

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

打赏作者

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

抵扣说明:

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

余额充值