Fisher线性判别法也即FLD实在PCA降维的基础上再进一步考虑样本间的信息。算法目标是找到一个投影轴,使各分类的类内样本在投影轴上的投影间距最小,同时样本间的投影间距最大。原理不难,公式推导遍地都是,尽管看不太懂吧..但是掌握核心几个公式以后就不妨碍我们用程序来实现它。
但是网上的例子多数是基于二分类的,那么对于多类别的样本如何使用FLD判别呢,这个问题没有太多的论述。所以想出了如下的办法去在多个分类的样本中应用FLD:对样本中的分类两两结合计算对应的w向量,测试数据进来后分别应用这些w向量对其进行FLD判断,判断成功的分类在最终结果中加一分,最后遍历了所有w后,得分最高的那个分类即是测试数据的分类结果。办法虽然笨,但是基本还算能完成功能吧..
import os
import sys
import numpy as np
from numpy import *
import operator
import matplotlib
import matplotlib.pyplot as plt
def class_mean(samples):#求样本均值
aver = np.mean(samples,axis = 1)
return aver
def withclass_scatter(samples,mean):#求类内散度
dim,num = samples.shape()
samples_m = samples - mean
s_with = 0
for i in range(num):
x = samples_mean[:,i]
s_in += dot(x,x.T)
return s_in
def get_w(s_in1,s_in2,mean1,mean2):#得到权向量
sw = s_in1 + s_in2
w = dot(sw.I,(mean1-mean2))
return w
def classify(test,w,mean1,mean2):#分类算法
cen_1 = dot(w.T,mean1)
cen_2 = dot(w.T,mean2)
g = dot(w.T,sample)
return abs(pos - cen_1)<abs(pos - cen2)
if __name__=='__main__':
class_num = 分类数
class_name={}
test = 测试数据
ws = {}
result={}
for i in range(k):
class_name[i]=group[i]
for i in range(k):
result[i]=0
for i in range(k):#第一次循环计算权向量的值
for j in range(k):
if i==j:
break
mean1 = class_mean(class_name[i])
mean2 = class_mean(class_name[j])
s_in1 = withclass_scatter(class_name[i],mean1)
s_in2 = withclass_scatter(class_name[j],mean2)
w[i,j] = get_w(s_in1,s_in2,mean1,mean2)
for i in range(k):#第二次循环在测试数据上应用权向量
for j in range(k):
if i==j:
break
w = w[i,j]
if classify(test,w,mean1,mean2):
result[i]+=1
else result[j]+=1
final_result = filter(lambda x:max(result.values())==result[x],result)[0]#找出得分最高的分类作为最终结果