LDA方法的主要思想是,将空间中的样本点投影到一个超平面上,令同一类的样本点之间距离相对近,不同类的样本点之间距离相对远。
需要最大化,其中w是超平面的“斜率”(也就是我们要求的变量),S_B是组间方差,S_w是类内方差
解得之后对下式进行特征值分解
下面上代码。采用的是iris数据集。
from sklearn import datasets
import numpy as np
from matplotlib import pyplot as plt
def Load_Dataset():
iris=datasets.load_iris()
return iris.data,iris.target
def LDA(data, target):
# 计算每个类别的均值
mean_vecs=[]
for label in range(0,2):
mean_vecs.append(np.mean(data[label==target],axis=0))
# 计算S_w
d=4 # iris数据集中,每行数据有4个feature
S_w=np.zeros((d,d))
for label,u_i in zip(range(0,2),mean_vecs):
S_i=np.zeros((d,d))
for x in data[target==label]:
x=x.reshape(d,1)
u_i=u_i.reshape(d,1)
S_i+=(x-u_i).dot((x-u_i).T)
S_w+=S_i
# 计算S_B
u_2=np.mean(data,axis=0)
S_B=np.zeros((d,d))
for i,u_1 in enumerate(mean_vecs):
n=data[target==i,:].shape[0]
u_1=u_1.reshape(d,1)
u_2=u_2.reshape(d,1)
S_B+=n*(u_1-u_2).dot((u_1-u_2).T)
# 计算W
eig_vals,eig_vecs=np.linalg.eig(np.linalg.inv(S_w).dot(S_B))
eig_pairs=[(np.abs(eig_vals[i]),eig_vecs[:,i])for i in range(len(eig_vals))]
eig_pairs=sorted(eig_pairs,key=lambda k:k[0],reverse=True)
W=np.hstack((eig_pairs[0][1][:,np.newaxis].real,eig_pairs[1][1][:,np.newaxis].real))
# 将W投影
W_proj=data.dot(W)
# 画图
plt.scatter(W_proj[target==0,0],W_proj[target==0,1],c='r')
plt.scatter(W_proj[target==1,0],W_proj[target==1,1],c='g')
plt.scatter(W_proj[target==2,0],W_proj[target==2,1],c='b')
plt.xlabel("X")
plt.ylabel("Y")
plt.show
运行结果(结果看起来好像不太好丫= =)