第1关:线性判别分析——基于随机生成数据的降维处理
#encoding=utf8
import numpy as np
from numpy.linalg import inv
def lda(X, y):
'''
input:X(ndarray):待处理数据(shape: [样本数, 特征数])
y(ndarray):待处理数据标签,标签分别为0和1(shape: [样本数,])
output:X_new(ndarray):处理后的数据(shape: [样本数, 1],一维投影结果)
'''
#********* Begin *********#
# 1. 划分第一类(标签0)和第二类(标签1)样本
X0 = X[y == 0] # 标签为0的所有样本(shape: [n0, d],n0为类别0样本数,d为特征数)
X1 = X[y == 1] # 标签为1的所有样本(shape: [n1, d],n1为类别1样本数)
# 2. 计算两类样本的中心点(均值向量)
mu0 = np.mean(X0, axis=0) # 类别0的均值向量(shape: [d,])
mu1 = np.mean(X1, axis=0) # 类别1的均值向量(shape: [d,])
# 3. 计算两类样本的协方差矩阵(无偏协方差,除以n-1)
# 协方差矩阵公式:cov = (X - mu)^T @ (X - mu) / (n-1)
cov0 = np.cov(X0, rowvar=False) # 类别0的协方差矩阵(shape: [d, d])
cov1 = np.cov(X1, rowvar=False) # 类别1的协方差矩阵(shape: [d, d])
# 4. 计算类内散度矩阵 S_w(两类协方差矩阵的加权和,权重为样本数占比)
n0 = len(X0)
n1 = len(X1)
S_w = (n0 / (n0 + n1)) * cov0 + (n1 / (n0 + n1)) * cov1 # 加权类内散度(也可直接求和:n0*cov0 + n1*cov1,结果等价)
# 5. 计算最优投影方向 w(LDA核心公式:w = S_w^{-1} @ (mu1 - mu0))
# 由于S_w可能接近奇异,实际中可加正则项避免逆矩阵计算失败(此处简化用inv)
w = inv(S_w) @ (mu1 - mu0)
# 归一化w(可选,不影响投影结果的相对关系)
w = w / np.linalg.norm(w)
# 6. 将原始数据投影到w方向,得到新样本集(矩阵乘法:X @ w,shape: [样本数, 1])
X_new = X @ w.reshape(-1, 1) # 确保w为列向量,投影后为一维数据
#********* End *********#
return X_new
第2关:利用scikit-learn实现线性判别分析——对随机生成数据进行降维操作
#encoding=utf8
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
def lda(x, y):
'''
input:x(ndarray):待处理数据(shape: [样本数, 特征数])
y(ndarray):待处理数据标签(shape: [样本数,],支持二分类/多分类)
output:x_new(ndarray):降维后数据(shape: [样本数, 降维后的特征数])
'''
#********* Begin *********#
# 1. 初始化LDA模型(默认降维到 min(类别数-1, 原始特征数) 维)
lda_model = LinearDiscriminantAnalysis()
# 2. 拟合数据(学习投影方向)并执行降维
x_new = lda_model.fit_transform(x, y)
#********* End *********#
return x_new


雷达卡


京公网安备 11010802022788号







