多分类Fisher线性判别算法

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]#找出得分最高的分类作为最终结果
                 
            


以下是使用Python编程语言和NumPy库实现Fisher线性判别算法的示例代码: ```python import numpy as np class FisherLinearDiscriminant: def __init__(self, n_components): self.n_components = n_components self.w = None # 投影向量 def fit(self, X, y): # 计算每个类别的均值向量 class_means = [] for i in np.unique(y): class_means.append(np.mean(X[y == i], axis=0)) class_means = np.array(class_means) # 计算类内散度矩阵和类间散度矩阵 S_w = np.zeros((X.shape[1], X.shape[1])) S_b = np.zeros((X.shape[1], X.shape[1])) for i in np.unique(y): X_i = X[y == i] class_mean_i = class_means[i] S_w += np.dot((X_i - class_mean_i).T, (X_i - class_mean_i)) S_b += X_i.shape[0] * np.dot((class_mean_i - np.mean(X, axis=0)).reshape(-1, 1), (class_mean_i - np.mean(X, axis=0)).reshape(1, -1)) # 解决广义特征向量问题,得到最佳的投影方向 eig_vals, eig_vecs = np.linalg.eig(np.dot(np.linalg.inv(S_w), S_b)) eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:, i]) for i in range(len(eig_vals))] eig_pairs.sort(reverse=True, key=lambda x: x[0]) self.w = np.hstack([eig_pairs[i][1].reshape(-1, 1) for i in range(self.n_components)]) def transform(self, X): # 将数据投影到最佳方向上 return np.dot(X, self.w) def fit_transform(self, X, y): self.fit(X, y) return self.transform(X) ``` 在上述代码中,首先定义了一个FisherLinearDiscriminant类,其中包含了fit、transform和fit_transform三个方法,分别用于训练模型、将数据投影到最佳方向上和同时训练模型和将数据投影到最佳方向上。在fit方法中,计算了每个类别的均值向量、类内散度矩阵和类间散度矩阵,并解决了广义特征向量问题,得到最佳的投影方向。在transform方法中,将数据投影到最佳方向上。在fit_transform方法中,先调用fit方法训练模型,然后调用transform方法将数据投影到最佳方向上,并返回投影后的数据。 可以使用以下代码来测试FisherLinearDiscriminant类的功能: ```python from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载鸢尾花数据集 iris = load_iris() X = iris.data y = iris.target # 将数据集随机分成训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 使用Fisher线性判别进行降维 fld = FisherLinearDiscriminant(n_components=2) X_train_fld = fld.fit_transform(X_train, y_train) X_test_fld = fld.transform(X_test) # 训练逻辑回归模型 from sklearn.linear_model import LogisticRegression clf = LogisticRegression() clf.fit(X_train_fld, y_train) # 预测测试集的标签 y_pred = clf.predict(X_test_fld) # 计算模型的准确率 acc = accuracy_score(y_test, y_pred) print("Accuracy:", acc) ``` 在测试代码中,首先加载了鸢尾花数据集,并将数据集随机分成训练集和测试集。然后使用Fisher线性判别进行降维,将原始的4维数据降到2维。接着训练了一个逻辑回归模型,并使用测试集来评估模型的准确率。运行代码后,可以得到模型的准确率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值