多分类Fisher线性判别算法

来源:互联网 发布:剑与魔法坐骑进阶数据 编辑:程序博客网 时间:2024/05/22 08:14

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 pltdef class_mean(samples):#求样本均值    aver = np.mean(samples,axis = 1)    return averdef 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_indef get_w(s_in1,s_in2,mean1,mean2):#得到权向量    sw = s_in1 + s_in2    w = dot(sw.I,(mean1-mean2))    return wdef 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]#找出得分最高的分类作为最终结果