Fisher辨别分析

2023-12-14 13:59
文章标签 分析 fisher 辨别

本文主要是介绍Fisher辨别分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 问题要求

在UCI数据集上的Iris和Sonar数据上验证算法的有效性。训练和测试样本有三种方式(三选一)进行划分:

(一) 将数据随机分训练和测试,多次平均求结果

(二)K折交叉验证

(三)留1法

针对不同维数,画出曲线图。

  • 问题分析

(一)数据集

1.Iris数据集是常用的分类实验数据集,由Fisher收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。数据集包含150个数据样本,分为3类,每类50个数据,每个数据包含4个属性。可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。

2.在Sonar数据集中有两类(字母“R”(岩石)和“M”(矿井)),分别有97个和111个数据,每个数据有60维的特征。这个分类任务是为了判断声纳的回传信号是来自金属圆柱还是不规则的圆柱形石头。

(二)Fisher线性判别分析

1.方法总括

Fisher线性判别方法可概括为把 d 维空间的样本投影到一条直线上,形成一维空间,即通过降维去解决两分类问题。如何根据实际数据找到一条最好的、最易于分类的投影方向,是 Fisher 判别方法所要解决的基本问题。

2. 求解过程

(1)核心思想

假设有一集合 D 包含 m 个 n 维样本{x1, x2, …, xm},第一类样本集合记为 D1,规模为 N1,第二类样本集合记为 D2,规模为 N2。若对 xi 的分量做线性组合可得标量:yi = wTxi(i=1,2,…,m)这样便得到 m 个一维样本 yi 组成的集合, 并可分为两个子集 D’1 和 D’2。计算阈值 yo,当 yi>yo 时判断 xi 属于第一类, 当 yi<yo 时判断 xi 属于第二类,当 yi=yo 时 xi 可判给任何一类或者拒收。(2)具体推导

相关书籍或网站上都有具体推导过程,这里不再赘述。

  (3)样本划分

采用留1法划分训练集和数据集,该方法是K折法的一种极端情况。

在K折法中,将全部训练集 S分成 k个不相交的子集,假设 S中的训练样例个数为 N,那么每一个子集有 N/k 个训练样例,相应的子集称作 {s1,s2,…,sk}。每次从分好的子集中里面,拿出一个作为测试集,其它k-1个作为训练集,根据训练训练出模型或者假设函数。然后把这个模型放到测试集上,得到分类率,计算k次求得的分类率的平均值,作为该模型或者假设函数的真实分类率。

当取K的值为样本个数N时,即将每一个样本作为测试样本,其它N-1个样本作为训练样本。这样得到N个分类器,N个测试结果。用这N个结果的平均值来衡量模型的性能,这就是留1法。在UCI数据集中,由于数据个数较少,采用留一法可以使样本利用率最高。

  • 仿真结果
  • 1.Iris数据集

由于Fisher分类器只能将样本划分为两类,则将三份数据两两分类并采取留1法进行划分。由仿真效果可看出划分界限十分明显,Fisher算法分类的表现较好。

  • 2.Sonar数据集

由仿真结果可看出,维度在30维之前时,纬度越高,Fisher判别的准确率越高;维度在30维之后,Fisher判别的准确率趋于稳定,在75%左右。cc8cfcda482b46a0916a91422586f04a.png27dadc84a38e4c4aa0631cdafdfcb5aa.png6a0e8c27c89c4d9e869bbcde1dc2b89c.png

代码如下:

(1)iris数据集

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
print(mpl.get_backend())Iris = pd.read_csv('iris.data', header=None, sep=',')def Fisher(X1, X2, t):# 各类样本均值向量m1 = np.mean(X1, axis=0)m2 = np.mean(X2, axis=0)m1 = m1.reshape(4, 1)m2 = m2.reshape(4, 1)m = m1 - m2# 样本类内离散度矩阵s1 = np.zeros((4, 4))   # s1,s2此时均为数组s2 = np.zeros((4, 4))if t == 0:  # 第一种情况for i in range(0, 49):s1 += (X1[i].reshape(4, 1) - m1).dot((X1[i].reshape(4, 1) - m1).T)for i in range(0, 50):s2 += (X2[i].reshape(4, 1) - m2).dot((X2[i].reshape(4, 1) - m2).T)if t == 1:  # 第二种情况for i in range(0, 50):s1 += (X1[i].reshape(4, 1) - m1).dot((X1[i].reshape(4, 1) - m1).T)for i in range(0, 49):s2 += (X2[i].reshape(4, 1) - m2).dot((X2[i].reshape(4, 1) - m2).T)# 总类内离散度矩阵sw = s1 + s2sw = np.mat(sw, dtype='float')m = np.mat(m, dtype='float')# 最佳投影方向w = np.linalg.inv(sw).dot(m)# 在投影后的一维空间求两类的均值m1 = np.mat(m1, dtype='float')m2 = np.mat(m2, dtype='float')m_1 = (w.T).dot(m1)m_2 = (w.T).dot(m2)# 计算分类阈值w0w0 = -0.5 * (m_1 + m_2)return w, w0def Classify(X,w,w0):y = (w.T).dot(X) + w0return y#数据预处理
Iris = Iris.iloc[0:150,0:4]
iris = np.mat(Iris)Accuracy = 0iris1 = iris[0:50, 0:4]
iris2 = iris[50:100, 0:4]
iris3 = iris[100:150, 0:4]G121 = np.ones(50)
G122 = np.ones(50)
G131 = np.zeros(50)
G132 = np.zeros(50)
G231 = np.zeros(50)
G232 = np.zeros(50)# 留一法验证准确性
# 第一类和第二类的线性判别
count = 0
for i in range(100):if i <= 49:test = iris1[i]test = test.reshape(4, 1)train = np.delete(iris1, i, axis=0)w, w0 = Fisher(train, iris2, 0)if (Classify(test, w, w0)) >= 0:count += 1G121[i] = Classify(test, w, w0)else:test = iris2[i-50]test = test.reshape(4, 1)train = np.delete(iris2, i-50, axis=0)w, w0 = Fisher(iris1, train, 1)if (Classify(test, w, w0)) < 0:count += 1G122[i-50] = Classify(test, w, w0)
Accuracy12 = count/100
print("第一类和二类的分类准确率为:%.3f"%(Accuracy12))# 第二类和第三类的线性判别
count = 0
for i in range(100):if i <= 49:test = iris2[i]test = test.reshape(4, 1)train = np.delete(iris2, i, axis=0)w, w0 = Fisher(train, iris3, 0)if (Classify(test, w, w0)) >= 0:count += 1G231[i] = Classify(test, w, w0)else:test = iris3[i-50]test = test.reshape(4, 1)train = np.delete(iris3, i-50, axis=0)w, w0 = Fisher(iris2, train, 1)if (Classify(test, w, w0)) < 0:count += 1G232[i-50] = Classify(test, w, w0)
Accuracy23 = count/100
print("第二类和第三类的分类准确率为:%.3f"%(Accuracy23))# 第一类和第三类的线性判别
count = 0
for i in range(100):if i <= 49:test = iris1[i]test = test.reshape(4, 1)train = np.delete(iris1, i, axis=0)w, w0 = Fisher(train, iris3, 0)if (Classify(test, w, w0)) >= 0:count += 1G131[i] = Classify(test, w, w0)else:test = iris3[i-50]test = test.reshape(4, 1)train = np.delete(iris3, i-50, axis=0)w,w0 = Fisher(iris1, train, 1)if (Classify(test, w, w0)) < 0:count += 1G132[i-50] = Classify(test, w, w0)
Accuracy13 = count/100
print("第一类和第三类的分类准确率为:%.3f"%(Accuracy13))# 作图
y1 = np.zeros(50)
y2 = np.zeros(50)
plt.figure(1)
plt.ylim((-0.5, 0.5))# 画散点图
plt.scatter(G121, y1, color='red', marker='.')
plt.scatter(G122, y2, color='blue', marker='.')
plt.xlabel('Class:1-2')
plt.show()plt.figure(2)
plt.ylim((-0.5, 0.5))
# 画散点图
plt.scatter(G231, y1, c='red',  marker='.')
plt.scatter(G232, y2, c='blue', marker='.')
plt.xlabel('Class:2-3')
plt.show()plt.figure(3)
plt.ylim((-0.5, 0.5))
# 画散点图
plt.scatter(G131, y1, c='red', marker='.')
plt.scatter(G132, y2, c='blue', marker='.')
plt.xlabel('Class:1-3')
plt.show()

(2)Sonar数据集

import numpy
import pandas as pd
import numpy as np
import matplotlib.pyplot as pltpath=r'sonar.all-data.txt'
df = pd.read_csv(path, header=None, sep=',')def Fisher(X1, X2, n, t):# 各类样本均值向量m1 = np.mean(X1, axis=0)m2 = np.mean(X2, axis=0)m1 = m1.reshape(n, 1)m2 = m2.reshape(n, 1)m = m1 - m2# 样本类内离散度矩阵s1 = np.zeros((n, n))   # s1,s2此时均为数组s2 = np.zeros((n, n))if t == 0:  # 第一种情况for i in range(0, 96):s1 += (X1[i].reshape(n, 1) - m1).dot((X1[i].reshape(n, 1) - m1).T)for i in range(0, 111):s2 += (X2[i].reshape(n, 1) - m2).dot((X2[i].reshape(n, 1) - m2).T)if t == 1:  # 第二种情况for i in range(0, 97):s1 += (X1[i].reshape(n, 1) - m1).dot((X1[i].reshape(n, 1) - m1).T)for i in range(0, 110):s2 += (X2[i].reshape(n, 1) - m2).dot((X2[i].reshape(n, 1) - m2).T)# 总类内离散度矩阵sw = s1 + s2sw = np.mat(sw, dtype='float')m = numpy.mat(m, dtype='float')# 最佳投影方向w = np.linalg.inv(sw).dot(m)# 在投影后的一维空间求两类的均值m_1 = (w.T).dot(m1)m_2 = (w.T).dot(m2)# 计算分类阈值w0w0 = -0.5 * (m_1 + m_2)return w, w0def Classify(X,w,w0):y = (w.T).dot(X) + w0return y# 数据预处理
Sonar = df.iloc[0:208,0:60]
sonar = np.mat(Sonar)# 分十次计算准确率
Accuracy = np.zeros(60)
accuracy_ = np.zeros(10)
for n in range(1,61):for t in range(10):sonar_random = (np.random.permutation(sonar.T)).T   # 对原sonar数据进行每列打乱sonar1 = sonar_random[0:97, 0:n]sonar2 = sonar_random[97:208, 0:n]count = 0# 留一法验证准确性for i in range(208):    # 取每一维度进行测试if i <= 96:test = sonar1[i]test = test.reshape(n, 1)train = np.delete(sonar1, i, axis=0)w, w0 = Fisher(train, sonar2, n, 0)if (Classify(test, w, w0)) >= 0:count += 1else:test = sonar2[i-97]test = test.reshape(n, 1)train = np.delete(sonar2, i-97, axis=0)w, w0 = Fisher(sonar1, train, n, 1)if (Classify(test, w, w0)) < 0:count += 1accuracy_[t] = count / 208for k in range(10):Accuracy[n - 1] += accuracy_[k]Accuracy[n - 1] = Accuracy[n - 1] / 10print("数据为%d维时,准确率为:%.3f" % (n, Accuracy[n - 1]))# 作图
x = np.arange(1, 61, 1)
plt.xlabel('dimension')
plt.ylabel('Accuracy')
plt.ylim((0.5, 0.8))            # y坐标的范围
plt.plot(x, Accuracy, 'b')
plt.show()

这篇关于Fisher辨别分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/492799

相关文章

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

python-nmap实现python利用nmap进行扫描分析

《python-nmap实现python利用nmap进行扫描分析》Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里,可以使用python-nmap这个python库,它提供了... 目录前言python-nmap的基本使用PortScanner扫描PortScannerAsync异

Oracle数据库执行计划的查看与分析技巧

《Oracle数据库执行计划的查看与分析技巧》在Oracle数据库中,执行计划能够帮助我们深入了解SQL语句在数据库内部的执行细节,进而优化查询性能、提升系统效率,执行计划是Oracle数据库优化器为... 目录一、什么是执行计划二、查看执行计划的方法(一)使用 EXPLAIN PLAN 命令(二)通过 S

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置