24/11/2 算法笔记 拆解LDA
LDA大致的理解就是:找到一条直线,同类别样例到投影点尽可能接近,不同类别尽可能远离
以下是几个关键点:
1.投影:
2.类间散度矩阵:考虑使用不同样例的投影点远,要一个标准来衡量类间的距离
LDA采用两个类别的均值向量μ i , i ∈ { 0 , 1 } 在直线上的投影间的距离:
内积是投影,上面是两个投影间的距离。
3.类内散度矩阵,表示同类样例的投影
方差:度量一组数据间离散程度,方差越大越分散
协方差:一维样本,求出的就是方差
二维样本,反映两维度相关性
三维样本,各个维度总体相关性
4.目标函数
根据LDA的目标,我们需要使得同类样例间的投影点尽可能接近,即使得w^T SwW尽可能小,
异类样例间的投影点尽可能远离,即使得 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]