拉格朗日乘子法实现lda
时间: 2025-03-11 16:26:48 浏览: 7
使用拉格朗日乘子法实现LDA
在线性判别分析(LDA)中,目标是最小化类内散布矩阵并最大化类间散布矩阵。为了达到这一目的,在约束条件下优化目标函数可以采用拉格朗日乘子法。
具体来说,对于给定的数据集 (X) 和类别标签 (y), 需要找到一个投影方向 (\mathbf{w}),使得不同类别的数据在这个方向上的分布尽可能分开而同一类内的样本点尽量聚集在一起。这可以通过求解下面的广义特征值问题来完成:
[ S_W^{-1}S_B\mathbf{w}=\lambda\mathbf{w} ]
其中 (S_W) 是类内散布矩阵,(S_B) 表示类间散布矩阵[^1]。
通过引入拉格朗日乘数项,形成新的目标函数:
[ J(\mathbf{w},\alpha)=\frac{\mathbf{w}^TS_B\mathbf{w}}{\mathbf{w}^TS_W\mathbf{w}}-\alpha (\mathbf{w}^T\mathbf{w}-1)]
这里 (\alpha) 就是拉格朗日乘子。对上面的目标函数关于 (\mathbf{w}) 进行偏微分,并令其等于零得到最优解条件下的方程组。最终会发现该方程实际上就是之前提到过的广义特征值分解的形式[^2]。
下面是简单的 Python 实现例子,演示了如何利用 numpy
库计算 LDA 的最佳投影向量:
import numpy as np
def lda(X, y):
classes = np.unique(y)
mean_vectors = []
for cl in classes:
mean_vectors.append(np.mean(X[y==cl], axis=0))
overall_mean = np.mean(X, axis=0)
Sw = np.zeros((X.shape[1], X.shape[1]))
Sb = np.zeros((X.shape[1], X.shape[1]))
for idx, mv in zip(classes, mean_vectors):
class_sc_mat = np.zeros((X.shape[1], X.shape[1]))
for row in X[y == idx]:
row, mv = row.reshape(X.shape[1], 1), mv.reshape(X.shape[1], 1)
class_sc_mat += (row-mv).dot((row-mv).T)
Sw += class_sc_mat
for i, mean_vec in enumerate(mean_vectors):
n = X[y==i+1,:].shape[0]
mean_vec = mean_vec.reshape(X.shape[1], 1)
overall_mean = overall_mean.reshape(X.shape[1], 1)
Sb += n * (mean_vec - overall_mean).dot((mean_vec - overall_mean).T)
eig_vals, eig_vecs = np.linalg.eig(np.linalg.inv(Sw).dot(Sb))
# Make a list of (eigenvalue, eigenvector) tuples
eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))]
# Sort the eigenvalue pairs from high to low
eig_pairs.sort(key=lambda x: x[0], reverse=True)
w = eig_pairs[0][1][:, np.newaxis]
return w.real
此代码片段实现了基本的两分类情况下的 LDA 投影向量计算逻辑。实际应用中可能还需要考虑多分类情形以及数值稳定性等问题[^3]。
相关推荐














