线性判别分析LDA算法与python实现

  降维指的是通过某种数学变换将高维原始空间的属性转变为低维子空间,根据变换形式可将该数学变换分为线性变换和非线性变换,对应的降维算法也被称为线性降维和非线性降维.其中,线性降维算法主要有线性判别分析(linear discriminant analysis,LDA)和主成分分析(Principal Component Analysis,PCA),非线性降维主要有核化思想(如Kernelized PCA)和流形学习(Isomap,LLE,LE等)两类.
  假定有原始空间高维数据 X ∈ R n × m X \in R^{n \times m} XRn×m,其中 n n n为样本数, m m m为样本长度,现我们要求 X X X的低维嵌入 Y ∈ R n × d Y \in R^{n \times d} YRn×d,其中 d < < m d<<m d<<m.线性降维的思想就是求一个权重矩阵 W ∈ R m × d W \in R^{m \times d} WRm×d,使用 W W W X X X进行线性变换 Y = X W Y=XW Y=XW,使得变换前后的数据分布一致.如上所述,LDA和PCA都是线性降维算法,不同的是LDA是监督学习算法,而PCA是面向无标签的数据样本.本文介绍LDA算法.
在这里插入图片描述
  首先盗用西瓜书里的一张图,这张图很清晰地阐释了LDA的核心思想:图中的数据简化为二维降维到一维,降维过程中,LDA算法使得低维空间中,同一类的数据尽可能接近,使得不同类数据尽可能远离.如上文所述,LDA是一种监督学习算法,即数据具有label,这里与西瓜书保持一致,使用了二分类问题的数据,分别记为 X 0 ∈ R n 0 × m X_0 \in R^{n_0 \times m} X0Rn0×m X 1 ∈ R n 1 × m X_1 \in R^{n_1 \times m} X1Rn1×m.我们的目标是找到一个变换矩阵 W ∈ R m × d W \in R^{m \times d} WRm×d对原始数据 X X X进行线性变换 Y = X W Y=XW Y=XW,且变换后的 Y Y Y满足上述性质.记 μ 0 ∈ R m × 1 , μ 1 ∈ R m × 1 , Σ 0 ∈ R m × m , Σ 1 ∈ R m × m \mu_0 \in R^{m \times 1},\mu_1 \in R^{m \times 1},\Sigma_0 \in R^{m \times m},\Sigma_1 \in R^{m \times m} μ0Rm×1,μ1Rm×1,Σ0Rm×m,Σ1Rm×m分别为 X 0 X_0 X0的均值, X 1 X_1 X1的均值, X 0 X_0 X0的协方差, X 1 X_1 X1的协方差,则: μ i = 1 n i ∑ x ∈ X i x \mu_i=\frac{1}{n_i} \sum_{x \in X_i} x μi=ni1xXix Σ i = ∑ x ∈ X i ( x − μ i ) ( x − μ i ) T \Sigma_i=\sum_{x \in X_i}(x-\mu_i)(x-\mu_i)^T Σi=xXi(xμi)(xμi)T 首先我们希望变换后的类间距离越大越好,我们定义类间距离为类中心的 l 2 l_2 l2距离,所以该步骤我们的目标是: m a x W   ∣ ∣ W T μ 0 − W T μ 1 ∣ ∣ 2 2 {\rm max}_W \ ||W^T\mu_0-W^T\mu_1||_2^2 maxW WTμ0WTμ122 即: m a x W   W T ( μ 0 − μ 1 ) ( μ 0 − μ 1 ) T W {\rm max}_W \ W^T(\mu_0-\mu_1)(\mu_0-\mu_1)^T W maxW WT(μ0μ1)(μ0μ1)TW 其次我们希望变换后的类内协方差越小越好,即: m i n W W T ( Σ 0 + Σ 1 ) W {\rm min}_W W_T (\Sigma_0+\Sigma_1) W minWWT(Σ0+Σ1)W   现定义两个矩阵,类内散度矩阵(intra-class scatter matrix) S a ∈ R m × m S_a \in R^{m \times m} SaRm×m与类间散度矩阵(inter-class scatter matrix) S r ∈ R m × m S_r \in R^{m \times m} SrRm×m: S a = Σ 0 + Σ 1 S_a=\Sigma_0+\Sigma_1 Sa=Σ0+Σ1 S r = ( μ 0 − μ 1 ) ( μ 0 − μ 1 ) T S_r=(\mu_0-\mu_1)(\mu_0-\mu_1)^T Sr=(μ0μ1)(μ0μ1)T 我们约束 W T S a W = 1 W^T S_a W=1 WTSaW=1,所以最后的优化问题可以写成: m i n W   − W T S r W {\rm min}_W \ -W^T S_r W minW WTSrW s t .    W T S a W = 1 st. \ \ W^T S_a W=1 st.  WTSaW=1 定义拉格朗日函数为: L ( W ) = − W T S r W + λ ( W T S a W − 1 ) L(W)=-W^T S_r W + \lambda (W^T S_a W-1) L(W)=WTSrW+λ(WTSaW1) 对上述方程求 W W W的偏导,得到: S r W = λ S a W S_rW=\lambda S_aW SrW=λSaW 由上式可知, W ∈ R m × d W \in R^{m \times d} WRm×d的闭解为矩阵 S a − 1 S r S_a^{-1}S_r Sa1Sr最大的 d d d个特征值对应的 m m m维特征向量.这里公布一下代码和实验结果,代码略简略,只考虑了三维降到二维.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_classification
from mpl_toolkits.mplot3d import Axes3D
np.random.seed(0)

def createDataSet(n=100):
	X0 = np.array(np.random.random((n, 3)) + 1)
	X1 = np.array(np.random.random((n, 3)) - 1)
	return X0, X1

def compute_W(X0, X1):
	mean0 = np.mean(X0, axis=0)
	mean1 = np.mean(X1, axis=0)
	diff = np.expand_dims(mean0 - mean1, axis = 1)
	Sr = np.matmul(diff, diff.T)
	cov0 = np.matmul((X0 - mean0).T, (X0 - mean0))
	cov1 = np.matmul((X1 - mean1).T, (X1 - mean1))
	Sa = cov0 + cov1
	# print(Sa)
	tmp = np.matmul(np.linalg.pinv(Sa), Sr)
	# tmp = np.matmul(np.linalg.pinv(-Sr), Sa)
	eig_val, eig_vector = np.linalg.eig(tmp)
	return eig_vector[:, [0,1]]

def LDA(X0, X1):
	W = compute_W(X0, X1)
	return np.matmul(X0, W), np.matmul(X1, W)

if __name__ == '__main__':
	X0, X1 = createDataSet()
	Y0, Y1 = LDA(X0, X1)

	fig = plt.figure()
	ax = fig.add_subplot(121, projection='3d')
	ax.scatter(X0[:, 0], X0[:, 1], X0[:, 2], c=[1,0,0], cmap=plt.cm.hot)
	ax.scatter(X1[:, 0], X1[:, 1], X1[:, 2], c=[0,0,1], cmap=plt.cm.hot)
	ax2 = fig.add_subplot(122)
	ax2.scatter(Y0[:, 0], Y0[:, 1], c=[1,0,0], cmap=plt.cm.hot)
	ax2.scatter(Y1[:, 0], Y1[:, 1], c=[0,0,1], cmap=plt.cm.hot)
	plt.show()

在这里插入图片描述
  在LDA中,我们约束 W T S a W = 1 W^T S_a W=1 WTSaW=1,可能是提出算法的学者觉得类内相似对比类间差异不那么重要吧,现在我们探索一下另一种情况,我们约束 W T S r W = 1 W^T S_r W=1 WTSrW=1,那么优化问题变成了: m i n W   W T S a W {\rm min}_W \ W^T S_a W minW WTSaW s t .    W T S r W = 1 st. \ \ W^T S_r W=1 st.  WTSrW=1 定义拉格朗日函数为: L ( W ) = W T S a W + λ ( W T S r W − 1 ) L(W)=W^T S_a W + \lambda (W^T S_r W-1) L(W)=WTSaW+λ(WTSrW1) 对上述方程求 W W W的偏导,得到: − S a W = λ S r W -S_aW=\lambda S_rW SaW=λSrW 由上式可知, W ∈ R m × d W \in R^{m \times d} WRm×d的闭解为矩阵 − S r − 1 S a -S_r^{-1}S_a Sr1Sa最大的 d d d个特征值对应的 m m m维特征向量.代码中只需将21行注释,并恢复22行即可,下图展示了用这种约束得到的实验结果,可以看出两种约束并没有什么很大的差异,当然可能在高阶上第一种方法表现更优异,这里就不往下探索了.
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LDA(Linear Discriminant Analysis) 线性判别分析是一种常用的机器学习算法,主要用于分类任务。下面是Python实现LDA线性判别分析的示例代码: ```python import numpy as np from sklearn.preprocessing import StandardScaler class LDA: def __init__(self, n_components): self.n_components = n_components self.linear_discriminants = None def fit(self, X, y): n_features = X.shape[1] class_labels = np.unique(y) # 计算各类别均值向量 mean_overall = np.mean(X, axis=0) mean_class = np.zeros((len(class_labels), n_features)) for c in class_labels: X_c = X[y == c] mean_class[c] = np.mean(X_c, axis=0) # 计算类内散度矩阵 within_class_scatter = np.zeros((n_features, n_features)) for c in class_labels: X_c = X[y == c] cov = (X_c - mean_class[c]).T.dot(X_c - mean_class[c]) within_class_scatter += cov # 计算类间散度矩阵 between_class_scatter = np.zeros((n_features, n_features)) for c in class_labels: n_c = X[y == c].shape[0] mean_c = mean_class[c].reshape(n_features, 1) mean_overall = mean_overall.reshape(n_features, 1) between_class_scatter += n_c * (mean_c - mean_overall).dot((mean_c - mean_overall).T) # 计算投影矩阵 eigen_values, eigen_vectors = np.linalg.eig(np.linalg.inv(within_class_scatter).dot(between_class_scatter)) eigen_vectors = eigen_vectors.T idxs = np.argsort(abs(eigen_values))[::-1] eigen_vectors = eigen_vectors[idxs] self.linear_discriminants = eigen_vectors[0:self.n_components] def transform(self, X): return np.dot(X, self.linear_discriminants.T) ``` 以上代码使用了NumPy和Scikit-learn库,其中fit()方法用于拟合模型,transform()方法用于将数据投影到LDA的特征向量上。需要注意的是,在使用LDA之前应该对数据进行标准化处理,以避免数值计算上的不稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值