今天来分享一个关于模式识别的课程:对鸢尾花进行Fisher判别的实验
文章目录
一、什么是Fisher判别?
Fisher判别,也称为线性判别分析(Linear Discriminant Analysis,简称LDA),是一种用于降维和分类的经典方法,它通过将数据投影到低维空间中的坐标轴上,使得同一类别的数据点尽可能靠近,不同类别之间的距离尽可能地远离来实现分类。具体来说,Fisher判别是通过对数据求解类内离散度矩阵和类间离散度矩阵的比值来得到一个投影方向,并将数据投影到这个方向上,使得相同类别内的方差小、不同类别之间的方差大。这样就可以在低维空间中保留数据的主要特征,同时将数据分类。Fisher判别广泛用于模式识别、计算机视觉、生物信息学、质谱分析等领域。
二、实验内容
任意选取鸢尾花数据集中的两类,通过Fisher判别对这两类进行分类。
- 读取CSV数据,选择两类的特征作为训练数据(X1, X2),并且将其分为训练集和测试集,划分比例为8:2
- 分别求这两类特征的均值(m1, m2)
- 分别计算这两类特征的类内散度矩阵(S1, S2)
- 计算方向向量(W)
- 计算投影后的均值W0(公式:W0 = -(w(T)*m1+w(T)*m2)/2)
- 将测试数据带入W*X+W0中得到分类结果
- 得出分类准确率
三、实验步骤
1.准备好进行Fisher判别的数据集
我以鸢尾花数据集为例(共150个数据):
1.引入库
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
2.读取数据,并划分数据集
path = r'D:\ziranyuyanchuli\Pycharm\模式识别实验\实验一\iris.csv'
data = pd.read_csv(path, header=0)
x = []
y = []
y.append(data["Species"])
for x1, x2 in zip(data["Sepal.Width"], data["Sepal.Length"]):
x.append([x1, x2])
X = np.array(x)
X1 = X[:, 1]
X2 = X[:, 0]
train1 = X1[:150]
train2 = X2[:150]
注
:path中的路径是你数据集所使用的路径
3.计算样本均值
m1 = np.mean(train1, axis=0).reshape(-1, 1)
m2 = np.mean(train2, axis=0).reshape(-1, 1)
print("第一种的均值:", m1)
print("第二种的均值:", m2)
4.计算类内散度矩阵
s1 = np.cov(train1, rowvar=False)
s2 = np.cov(train2, rowvar=False)
sw = np.mat(s1 + s2)
print("类内散度矩阵:", sw)
5.求方向向量w,投影后的均值w0
w = np.linalg.inv(sw) * (m1 - m2)
w0 = (m1 * w.T + m2 * w.T) / 2
print("方向向量:", w)
print("投影后的均值:", w0)
6.测试准确率
# 代码将kind1和kind2分别初始化为0,然后提取每个数据集的前30个样本分别存放在test1和test2中。
kind1 = 0
kind2 = 0
# 提取每个数据集的前60个样本分别存放在test1和test2中
test1 = X1[:60]
test2 = X2[:60]
# 代码使用for循环迭代30次,对于每次迭代,使用np.dot(w.T, test1[i])计算第i个测试样本与方向向量w的点积y,若y大于或等于阈值w0,则把kind1加1。表示分类正确。
for i in range(60):
y = np.dot(w.T, test1[i])
if y >= w0:
kind1 = kind1 + 1
for i in range(60):
y = np.dot(w.T, test2[i])
if y < w0:
kind2 = kind2 + 1
correct = (kind1 + kind2) / 120
print("测试准确率:{:.2%}".format(correct))
四、实验结果
总结
好了,今天的小实验到这里就结束喽,分享快乐,嘿嘿,希望能和小伙伴们一起进步。
注
:相关数据集和实验报告我会上传到我的主页资源中,免费的,有需要可以自取!