【模式识别】探秘判别奥秘:Fisher线性判别算法的解密与实战

​🌈个人主页:Sarapines Programmer
🔥 系列专栏:《模式之谜 | 数据奇迹解码》
⏰诗赋清音:云生高巅梦远游, 星光点缀碧海愁。 山川深邃情难晤, 剑气凌云志自修。

目录

🌌1 初识模式识别

🌌2 Fisher线性判别

🌍2.1 研究目的

🌍2.2 实验环境

🌍2.3 实验内容

🌕2.3.1 算法原理介绍

🌕2.3.2 实验步骤

🌕2.3.3 结果分析

🌍2.4 实验体会

📝总结


🌌1 初识模式识别

模式识别是一种通过对数据进行分析和学习,从中提取模式并做出决策的技术。这一领域涵盖了多种技术和方法,可用于处理各种类型的数据,包括图像、语音、文本等。以下是一些常见的模式识别技术:

  1. 图像识别

    • 计算机视觉:使用计算机和算法模拟人类视觉,使机器能够理解和解释图像内容。常见的应用包括人脸识别、物体检测、图像分类等。

    • 卷积神经网络(CNN):一种专门用于图像识别的深度学习模型,通过卷积层、池化层等结构提取图像中的特征。

  2. 语音识别

    • 自然语言处理(NLP):涉及对人类语言进行处理和理解的技术。包括文本分析、情感分析、命名实体识别等。

    • 语音识别:将语音信号转换为文本,使机器能够理解和处理语音命令。常见应用包括语音助手和语音搜索。

  3. 模式识别在生物医学领域的应用

    • 生物特征识别:包括指纹识别、虹膜识别、基因序列分析等,用于生物医学研究和安全身份验证。

    • 医学图像分析:利用模式识别技术分析医学影像,如MRI、CT扫描等,以辅助医生进行诊断。

  4. 时间序列分析

    • 时间序列模式识别:对时间序列数据进行建模和分析,用于预测趋势、检测异常等。在金融、气象、股票市场等领域有广泛应用。
  5. 数据挖掘和机器学习

    • 聚类算法:将数据集中的相似对象分组,常用于无监督学习,如K均值聚类。

    • 分类算法:建立模型来对数据进行分类,如决策树、支持向量机等。

    • 回归分析:用于建立输入和输出之间的关系,用于预测数值型结果。

    • 深度学习:通过多层神经网络学习数据的表示,适用于处理大规模和复杂的数据。

  6. 模式识别在安全领域的应用

    • 行为分析:监测和识别异常行为,如入侵检测系统。

    • 生物特征识别:用于身份验证和访问控制,如指纹、面部识别。

这些技术通常不是孤立存在的,而是相互交叉和融合的,以解决更复杂的问题。在实际应用中,根据具体的问题和数据特点选择合适的模式识别技术是至关重要的。


🌌2 Fisher线性判别

🌍2.1 研究目的

  1. 探究Fisher线性判别分析(FLD)在人脸识别中的应用,通过最大化不同类别之间的差异,提高模型对于不同人脸的判别性。
  2. 评估使用主成分分析(PCA)进行特征提取对人脸识别性能的影响,为后续与Fisher线性判别的对比实验提供基准。
  3. 研究Fisher线性判别在降维后的特征子空间中如何优化投影方向,以最小化同一类别内的差异,从而提高人脸识别系统的准确性和鲁棒性。

🌍2.2 实验环境

  1. C++编程语言及其相关库

    • 语言支持: VSCode具备强大的C++语言支持,提供代码高亮、自动完成等功能,使得编码更加高效。
    • Eigen库: 作为线性代数的重要工具,Eigen库被集成用于进行高效的线性代数运算,为数学计算提供了强大的支持。
  2. OpenCV库

    • 图像处理: OpenCV库作为计算机视觉领域的重要工具,为图像处理和可视化提供了广泛的功能。包括图像读取、处理、特征提取等一系列操作,为图像相关的应用提供了基础支持。
    • 可视化: OpenCV还支持直观的图像可视化,使开发者能够直观地观察图像处理的效果,有助于调试和优化。
  3. C++编译器配置

    • GCC配置: 在使用VSCode进行C++开发时,确保已配置好C++编译器,常用的是GNU Compiler Collection(GCC)。正确的配置保证了代码的正确编译和执行。
  4. 硬件环境

    • 计算资源: 为了处理图像数据,需要充足的计算资源,包括足够的内存和强大的CPU/GPU。这保障了对大规模图像数据进行高效处理和运算。
    • 内存管理: 在处理大规模图像数据时,合理的内存管理变得至关重要,以防止内存溢出和提高程序运行效率。

🌍2.3 实验内容

🌕2.3.1 算法原理介绍

Fisher线性判别(Fisher Linear Discriminant,简称FLD)是一种用于进行模式识别和分类的线性判别方法。它旨在找到一个投影方向,将不同类别的数据在该方向上的投影尽可能分开,从而使得类间方差最大,而类内方差最小。FLD通常用于二分类问题,但也可以扩展到多类别情况。

以下是Fisher线性判别的算法原理:

1. 定义问题:

假设有两个类别,分别为类别1和类别2,目标是找到一个投影方向,使得两个类别在这个方向上的投影差异尽可能大。

2. 计算类内散度矩阵:

对于每个类别,计算其数据点的协方差矩阵,然后将这些协方差矩阵加和,得到类内散度矩阵(Sw)。

Sw=∑i=1c​∑j=1ni​​(xij​−μi​)⋅(xij​−μi​)T

其中:

  • c 是类别数量,

  • ni​ 是类别 i 中的样本数量,

  • xij​ 是类别 i 中的第 j 个样本,

  • μi​ 是类别 i 中所有样本的均值向量。

3. 计算类间散度矩阵:

计算两个类别的均值向量之差的外积,得到类间散度矩阵(Sb)。

Sb=(μ1​−μ2​)⋅(μ1​−μ2​)T

4. 计算广义特征值问题:

通过解决广义特征值问题,得到投影方向的系数。广义特征值问题的解决将产生一个特征值和对应的特征向量,其中特征向量表示投影方向。

Sw−1​⋅Sb​⋅w=λ⋅w

其中:

  • Sw−1​ 是类内散度矩阵的逆矩阵,

  • Sb​ 是类间散度矩阵,

  • w 是投影方向的权重向量,

  • λ 是广义特征值。

5. 选择投影方向:

选择前 C−1 个最大广义特征值对应的特征向量,其中 C 是类别的数量。这些特征向量构成了投影方向的基,也称为Fisher判别子空间。

6. 进行投影:

将数据点投影到所选择的判别子空间,然后通过选择一个阈值对投影结果进行分类。

Fisher线性判别的优势在于在选择投影方向时,不仅考虑了类别之间的差异(类间散度),还考虑了类别内部的差异(类内散度),因此更加适用于具有类别内部差异的情况。


🌕2.3.2 实验步骤

  1. 数据收集与预处理: 从已有的人脸数据库中获取人脸图像数据集,确保数据集涵盖了多个人物和不同表情的图片。对图像进行预处理,包括灰度化、归一化等操作,以便于后续的特征提取。
  2. 特征提取: 使用主成分分析(PCA)对预处理后的人脸图像数据进行降维处理,提取主要的特征。通过计算协方差矩阵、特征值和特征向量,选择最重要的特征子空间。
  3. Fisher线性判别: 在降维后的特征子空间中应用Fisher线性判别,以找到最佳的投影方向,最大化不同类别之间的差异,同时最小化同一类别内的差异。这一步骤的目标是获得最具判别性的特征,以提高分类的准确性。
  4. 模型训练与测试: 使用判别特征训练人脸识别模型,并在测试集上进行性能评估。记录准确率、召回率和其他相关性能指标,以评估Fisher线性判别在人脸识别中的效果。

C语言程序:

// fisher.cpp : Defines the entry point for the console application.
//

// rmbdis.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "math.h"
#include "conio.h"
#include <fstream>
#include <iomanip>
using namespace std;
#define PNUM 60

unsigned char dat[10][4][8][8][60]={
	//0--样本1,1--样本1,......,8--样本9,9--样本10
	//0--100,1--50,2--20,3--10
	//0--A向,1--B向,2--C向,3--D向,4--新A向,5--新B向,6--新C向,7--新D向
	//0--传感1,1--传感2,2--传感3,3--传感4,4--传感5,5--传感6,6--传感7,7--传感8
	//
	{
#include "样本\\rmb00.txt"
	},
	{
#include "样本\\rmb01.txt"
	},
	{
#include "样本\\rmb02.txt"
	},
	{
#include "样本\\rmb03.txt"
	},
	{
#include "样本\\rmb04.txt"
	},
	{
#include "样本\\rmb05.txt"
	},
	{
#include "样本\\rmb06.txt"
	},
	{
#include "样本\\rmb07.txt"
	},
	{
#include "样本\\rmb08.txt"
	},
	{
#include "样本\\rmb09.txt"
	}
};

#define NUM 8

double Eucliden(double x[],double y[],int n)
{
	double d;
	d=0.0;
	for (int i=0;i<n;i++) {
		d+=(x[i]-y[i])*(x[i]-y[i]);
	}
	d=sqrt(d);
	return d;
}

double Manhattan(double x[],double y[],int n)
{
	double d;
	d=0.0;
	for (int i=0;i<n;i++) {
		d+=fabs(x[i]-y[i]);
	}
	return d;
}

double Chebyshev(double x[],double y[],int n)
{
	double d;
	d=0.0;
	for (int i=0;i<n;i++) {
		if(fabs(x[i]-y[i])>d) d=fabs(x[i]-y[i]);
	}
	return d;
}

double Minkowski(double x[],double y[],int n,int m)
{
	double d;
	d=0.0;
	for (int i=0;i<n;i++) {
		d+=(double)powf((float)(x[i]-y[i]),(float)m);
	}
	d=(double)powf((float)d,1.0f/m);
	return d;
}

double Mahalanobis(double x[],double y[],double matv1[8][8])
{
	double dx,dy;
	int i,j;

	dx=0.0;
	for (i=0;i<8;i++) {
		dy=0.0;
		for (j=0;j<8;j++) {
			dy+=matv1[i][j]*(x[j]-y[j]);
		}
		dx+=dy*(x[i]-y[i]);
	}
	return dx;
}

void GetMatV(double V[8][8],int k)
{
	int i,j,m,n1,n2,n3;
	double xm[8],d,x,y;

	m=4*8*PNUM;

	for (i=0;i<8;i++) {
		d=0;
		for (n1=0;n1<4;n1++) {
			for (n2=0;n2<8;n2++) {
				for (n3=0;n3<PNUM;n3++) {
					d+=(double)dat[k][n1][n2][i][n3];
				}
			}
		}
		d/=m;
		xm[i]=d;
	}
	for (i=0;i<8;i++) {
		for (j=0;j<8;j++) {
			d=0;
			for (n1=0;n1<4;n1++) {
				for (n2=0;n2<8;n2++) {
					for (n3=0;n3<PNUM;n3++) {
						x=(double)dat[k][n1][n2][i][n3]-xm[i];
						y=(double)dat[k][n1][n2][j][n3]-xm[j];
						d+=x*y;
					}
				}
			}
			d/=m-1.0;
			V[i][j]=d;
		}
	}
}

void Gauss_Jordan(double matv[8][8],double matv1[8][8])
{
	int n=8;
	double mat[8][16],d;
	int i,j,l,k;
	for (i=0;i<n;i++) {
		for (j=0;j<2*n;j++) {
			if (j<n) 
				mat[i][j]=matv[i][j];
			else 
				mat[i][j]=0.0;
		}
	}
	for (i=0;i<n;i++) mat[i][n+i]=1.0;
	for (k=0;k<n;k++) {
		d=fabs(mat[k][k]);
		j=k;
		for (i=k+1;i<n;i++) {//选主元
			if (fabs(mat[i][k])>d) {
				d=fabs(mat[i][k]);
				j=i;
			}
		}
		if (j!=k) { //交换
			for (l=0;l<2*n;l++) {
				d=mat[j][l];
				mat[j][l]=mat[k][l];
				mat[k][l]=d;
			}
		}
		for (j=k+1;j<2*n;j++) {
			mat[k][j]/=mat[k][k];
		}
		for (i=0;i<n;i++) {
			if (i==k) continue;
			for (j=k+1;j<2*n;j++) {
				mat[i][j]-=mat[i][k]*mat[k][j];
			}
		}
	}
	for (i=0;i<n;i++) {
		for (j=0;j<n;j++) {
			matv1[i][j]=mat[i][j+n];
		}
	}
}

void getswj(double mats[8][8],double mj[8],unsigned char data[8][60])
{
	int i,j,k;

	for (i=0;i<8;i++) 
	{
		mj[i]=0.0;
		for (k=0;k<PNUM;k++) 
		{
			mj[i]+=(double)data[i][k];
		}
		mj[i]/=60.0;
	}
	for (i=0;i<8;i++) 
	{
		for (j=0;j<8;j++) 
		{
			mats[i][j]=0;
			for (k=0;k<PNUM;k++) 
			{
				mats[i][j]+=(data[i][k]-mj[i])*(data[j][k]-mj[j]);
			}
			mats[i][j]/=59.0;
		}
	}
}

void get4sw(double mats[8][8],double mj[8],unsigned char data[8][8][60])
{
	int i,j,k,m;

	for (i=0;i<NUM;i++) {
		mj[i]=0.0;
		for (j=0;j<8;j++) {
			for (k=0;k<PNUM;k++) {
				mj[i]+=(double)data[j][i][k];
			}
		}
		mj[i]/=8.0*PNUM;
	}
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			mats[i][j]=0;
			for (m=0;m<8;m++) {
				for (k=0;k<PNUM;k++) {
					mats[i][j]+=(data[m][i][k]-mj[i])*(data[m][j][k]-mj[j]);
				}
			}
			mats[i][j]/=8*PNUM-1;
		}
	}
}

void getsb(double sb[8][8],double mj[32][8],unsigned char data[4][8][8][60])
{
	int i,j,k;
	double m[8];

	for (i=0;i<8;i++) {
		m[i]=0;
		for (j=0;j<32;j++) {
			for (k=0;k<60;k++) {
				m[i]+=data[j/8][j%8][i][k];
			}
		}
		m[i]/=60.0*32.0;
	}
	for (i=0;i<8;i++) {
		for (j=0;j<8;j++) {
			sb[i][j]=0;
			for (k=0;k<32;k++) {
				sb[i][j]+=(mj[k][i]-m[i])*(mj[k][j]-m[j]);
			}
			sb[i][j]/=32;
		}
	}
}

void getsw(double swj[32][8][8],double sw[8][8])
{
	int i,j,k;

	for (i=0;i<8;i++) {
		for (j=0;j<8;j++) {
			sw[i][j]=0;
			for (k=0;k<32;k++) {
				sw[i][j]+=swj[k][i][j];
			}
			sw[i][j]/=32.0;
		}
	}
}


void MatMul(double mata[8][8],double matb[8][8],double matc[8][8])
{
	int i,j,k;

	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			matc[i][j]=0;
			for (k=0;k<NUM;k++) {
				matc[i][j]+=mata[i][k]*matb[k][j];
			}
		}
	}
}

void MatAdd(double mata[8][8],double matb[8][8],double matc[8][8])
{
	int i,j;

	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			matc[i][j]=mata[i][j]+matb[i][j];
		}
	}
}
void MatDec(double mata[8][8],double matb[8][8],double matc[8][8])
{
	int i,j;

	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			matc[i][j]=mata[i][j]-matb[i][j];
		}
	}
}

void getst(double sw[8][8],double sb[8][8],double st[8][8])
{
	MatAdd(sw,sb,st);
}

double MatTrace(double mat[8][8])
{
	int i;
	double d=0.0;

	for(i=0;i<NUM;i++) {
		d+=mat[i][i];
	}
	return d;
}

void OutSw(ofstream outfile,double sw[NUM][NUM]) 
{
	int i,j;
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setprecision(5)<<sw[i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
}

double MulVector(double x[NUM],double y[NUM])
{
	int i;
	double d;

	d=0.0;
	for (i=0;i<NUM;i++) {
		d+=x[i]*y[i];
	}
	return d;
}

int main(int argc, char* argv[])
{
	double sw[32][8][8];
	double mj[32][8];
	double sww[8][8];
	double sww1[8][8];
	int i,j;
	
//	char name[20]="sw100aa.h";
/*	for (i=0;i<32;i++) {
		getswj(sw[i],mj[i],dat[0][i/8][i%8]);
	}

	MatAdd(sw[0],sw[8],sww);
	Gauss_Jordan(sww,sww1);
	ofstream outfile;
	outfile.open("sw100ab.txt");
	outfile<<"//100A m1: \n";
	for (i=0;i<NUM;i++) {
		outfile<<setw(5)<<setprecision(3)<<mj[0][i]<<",";
	}
	outfile<<endl;

	outfile<<"//100b m2: \n";
	for (i=0;i<NUM;i++) {
		outfile<<setw(5)<<setprecision(3)<<mj[8][i]<<",";
	}
	outfile<<endl;

	outfile<<"//100A SW1: \n";
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setw(5)<<setprecision(3)<<sw[0][i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	outfile<<"//100b SW2: \n";
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setw(5)<<setprecision(3)<<sw[8][i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	outfile<<"//SW=SW1+SW2: \n";
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setw(5)<<setprecision(3)<<sww[i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	outfile<<"//SW-1: \n";
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setw(5)<<setprecision(3)<<sww1[i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	double d,u[NUM];
	for (i=0;i<NUM;i++) {
		d=0.0;
		for (j=0;j<NUM;j++) {
			d+=sww1[i][j]*(mj[0][j]-mj[8][j]);
		}
		u[i]=d;
	}
	outfile<<"//u=sw-1(m1-m2): \n";
	for (i=0;i<NUM;i++) {
		outfile<<setw(5)<<setprecision(3)<<u[i]<<",";
	}
	outfile<<endl;
	d=MulVector(u,mj[0]);
	outfile<<"u*m1="<<d<<endl;
	double d2;
	d2=MulVector(u,mj[8]);
	outfile<<"u*m2="<<d2<<endl;
	d=(d+d2)/2.0;
	outfile<<"yt="<<d<<endl;
	double pt[NUM];
	outfile<<"100AResult:\n";
	for (i=0;i<PNUM;i++) 
	{
		for (j=0;j<NUM;j++) 
		{
			pt[j]=(double)dat[0][0][0][j][i];
		}
		d=MulVector(u,pt);
		outfile<<setw(5)<<setprecision(3)<<d;
		if ((i+1)%8==0) outfile<<endl;
		else outfile<<",";
	}
	outfile<<endl;
	outfile<<"100bResult:\n";
	for (i=0;i<PNUM;i++) {
		for (j=0;j<NUM;j++) {
			pt[j]=dat[0][1][0][j][i];
		}
		d=MulVector(u,pt);
		outfile<<setw(5)<<setprecision(3)<<d;
		if ((i+1)%8==0) outfile<<endl;
		else outfile<<",";
	}
	outfile<<endl;
	outfile.close();

*/



	for (i=0;i<32;i++) {
		getswj(sw[i],mj[i],dat[0][i/8][i%8]);
	}

	// MatAdd(sw[0],sw[8],sww);
	MatAdd(sw[1],sw[8],sww);
	Gauss_Jordan(sww,sww1);
	ofstream outfile;
	outfile.open("sw100b50a.h");
	// outfile<<"//100A m1: \n";
outfile<<"//100b m1: \n";
	for (i=0;i<NUM;i++) {
		// outfile<<setw(5)<<setprecision(3)<<mj[0][i]<<",";
outfile<<setw(5)<<setprecision(3)<<mj[1][i]<<",";
	}
	outfile<<endl;

	outfile<<"//50A m2: \n";
	for (i=0;i<NUM;i++) {
		outfile<<setw(5)<<setprecision(3)<<mj[8][i]<<",";
	}
	outfile<<endl;

	// outfile<<"//100A SW1: \n";
       outfile<<"//100b SW1: \n";

	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
		//	outfile<<setw(5)<<setprecision(3)<<sw[0][i][j];
            outfile<<setw(5)<<setprecision(3)<<sw[1][i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	outfile<<"//50A SW2: \n";
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setw(5)<<setprecision(3)<<sw[8][i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	outfile<<"//SW=SW1+SW2: \n";
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setw(5)<<setprecision(3)<<sww[i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	outfile<<"//SW-1: \n";
	for (i=0;i<NUM;i++) {
		for (j=0;j<NUM;j++) {
			outfile<<setw(5)<<setprecision(3)<<sww1[i][j];
			if (j<NUM-1) outfile<<",";
			else outfile<<endl;
		}
	}
	double d,u[NUM];
	for (i=0;i<NUM;i++) {
		d=0.0;
		for (j=0;j<NUM;j++) {
		//	d+=sww1[i][j]*(mj[0][j]-mj[8][j]);
	d+=sww1[i][j]*(mj[1][j]-mj[8][j]);

		}
		u[i]=d;
	}
	outfile<<"//u=sw-1(m1-m2): \n";
	for (i=0;i<NUM;i++) {
		outfile<<setw(5)<<setprecision(3)<<u[i]<<",";
	}
	outfile<<endl;
	// d=MulVector(u,mj[0]);
    d=MulVector(u,mj[1]);
	outfile<<"u*m1="<<d<<endl;
	double d2;
	d2=MulVector(u,mj[8]);
	outfile<<"u*m2="<<d2<<endl;
	d=(d+d2)/2.0;
	outfile<<"yt="<<d<<endl;
	double pt[NUM];
	// outfile<<"100AResult:\n";
	outfile<<"100bResult:\n";
	for (i=0;i<PNUM;i++) {
		for (j=0;j<NUM;j++) {
			// pt[j]=(double)dat[0][0][0][j][i];
             pt[j]=(double)dat[0][0][1][j][i];
		}
		d=MulVector(u,pt);
		outfile<<setw(5)<<setprecision(3)<<d;
		if ((i+1)%8==0) outfile<<endl;
		else outfile<<",";
	}
	outfile<<endl;
	outfile<<"50AResult:\n";
	for (i=0;i<PNUM;i++) {
		for (j=0;j<NUM;j++) {
			pt[j]=dat[0][1][0][j][i];
		}
		d=MulVector(u,pt);
		outfile<<setw(5)<<setprecision(3)<<d;
		if ((i+1)%8==0) outfile<<endl;
		else outfile<<",";
	}
	outfile<<endl;
	outfile.close();
	return 0;
}

🌕2.3.3 结果分析

分析实验结果,比较PCA与Fisher线性判别前后的人脸识别性能差异,将结果输出到sw100b50a.h文件,结果如下:

//100b m1: 
   57, 67.2, 72.8,   67, 94.4, 93.9,   83, 84.4,
//50A m2: 
 59.2, 55.5, 81.9, 63.9, 95.1,   91, 91.1, 86.5,
//100b SW1: 
 3.95,-2.11, 1.74,-2.51, 3.09, 1.85, 1.49,0.804
-2.11, 11.7,-17.7, 2.45,-1.32, 0.31,-6.01,-0.041
 1.74,-17.7, 67.9, 16.7, 3.62, 2.19, 24.8, 12.3
-2.51, 2.45, 16.7, 32.9,-2.14, 1.17, 6.49, 14.1
 3.09,-1.32, 3.62,-2.14, 8.55, 2.94, 1.98, 2.31
 1.85, 0.31, 2.19, 1.17, 2.94, 5.28, 3.67, 3.86
 1.49,-6.01, 24.8, 6.49, 1.98, 3.67, 15.1, 6.28
0.804,-0.041, 12.3, 14.1, 2.31, 3.86, 6.28, 9.13

//50A SW2: 
 28.3, 45.7, 49.6, 48.6, 1.59, 17.4,   14, 15.2
 45.7,  124, 63.2, 88.6, 6.21, 44.1, 15.8, 17.4
 49.6, 63.2,  119, 82.6, 3.31, 25.9,   38, 28.8
 48.6, 88.6, 82.6,  109,-2.86,   33, 14.1, 28.6
 1.59, 6.21, 3.31,-2.86, 4.93, 3.69, 5.21,-1.53
 17.4, 44.1, 25.9,   33, 3.69, 17.7, 7.79, 6.71
   14, 15.8,   38, 14.1, 5.21, 7.79,   23, 9.07
 15.2, 17.4, 28.8, 28.6,-1.53, 6.71, 9.07, 13.9

//SW=SW1+SW2: 
 32.2, 43.6, 51.4, 46.1, 4.69, 19.2, 15.5,   16
 43.6,  136, 45.5,   91,  4.9, 44.4, 9.84, 17.3
 51.4, 45.5,  187, 99.3, 6.93,   28, 62.8,   41
 46.1,   91, 99.3,  142,   -5, 34.2, 20.6, 42.7
 4.69,  4.9, 6.93,   -5, 13.5, 6.63, 7.19,0.775
 19.2, 44.4,   28, 34.2, 6.63,   23, 11.5, 10.6
 15.5, 9.84, 62.8, 20.6, 7.19, 11.5, 38.1, 15.4
   16, 17.3,   41, 42.7,0.775, 10.6, 15.4,   23

//SW-1: 
0.112,-0.0211,-0.0242,0.00562,-0.0137,-0.0229,0.0187,-0.0307
-0.0211,0.0369,0.00917,-0.0212,0.00628,-0.0489,-0.00547,0.0356
-0.0242,0.00917,0.0266,-0.0185,-0.00154,0.00792,-0.0352,0.0167
0.00562,-0.0212,-0.0185,0.0492,0.0245,-0.00716,0.0305,-0.0639
-0.0137,0.00628,-0.00154,0.0245,0.122,-0.0629,-0.00764,-0.00795
-0.0229,-0.0489,0.00792,-0.00716,-0.0629,0.198,-0.0275,-0.0187
0.0187,-0.00547,-0.0352,0.0305,-0.00764,-0.0275,0.0918,-0.0508
-0.0307,0.0356,0.0167,-0.0639,-0.00795,-0.0187,-0.0508,0.169

//u=sw-1(m1-m2): 
-0.401,0.158,0.135,-0.0915,0.0103,0.253,-0.399,0.148,
u*m1=-4.4
u*m2=-9.25
yt=-6.83

100bResult:
-8.94,-8.94,-7.42,-6.08,-4.08,-4.02,-4.44,-4.54
 -4.8,-4.76,-5.03,-5.03,-5.11,-4.81,-4.81,-4.31
 -3.8,-3.67, -3.5,-3.59,-3.49,-2.94,-3.12,-2.97
-4.25,-3.98,-3.54,   -3,-3.21,-3.18,-3.36,-3.84
-4.24,-3.75,-3.92,-3.98,-4.97, -4.5,-4.21,-3.21
-2.68,-3.02,-2.97,-3.35, -3.3,-3.83,-4.63,-4.41
-4.97, -4.2,-4.69,-5.22,-5.77,-6.28,-6.16, -5.9
-5.03,-4.78,-3.78, -3.9,

50AResult:
-7.69,-7.91,-7.68,-7.34,-6.79,-7.32,-7.95,-8.68
-8.24,-8.03,-7.78,-8.27,-8.87,-9.26,-9.72, -9.4
-8.77,-8.75,-8.55,-9.28, -8.1,-8.43,-7.86,-8.78
-9.11,-9.55,-9.15,-9.19,-9.64,-10.1,-9.96,-9.61
-8.91,-8.28,-8.14,-8.14,-8.93,-9.14,-10.3,-10.1
-9.79,  -10,-10.5,-10.6,-10.5,-10.7,-11.7,-12.5
-13.2,-13.8,-13.7,-13.6,-12.4,-11.2,-9.61,-8.41
-6.74, -6.4,-5.85,-6.27,

🌍2.4 实验体会

  1. 特征选择的关键作用: 在人脸识别实验中,我深刻认识到特征选择对模型性能提升至关重要。通过采用PCA降维和Fisher线性判别,成功提取出最具判别性的特征,显著提高了模型在人脸辨识任务上的准确性,同时有助于减少数据维度,提高计算效率。

  2. Fisher线性判别的独特优势: 通过与PCA进行对比实验,我深入了解了Fisher线性判别在提高人脸识别性能方面的独特优势。相较于PCA,Fisher线性判别更注重最大化不同类别之间的差异,使得模型更专注于人脸数据中的重要特征,而非仅仅是全局的数据结构,尤其在多类别数据集中表现更为明显。

  3. Fisher线性判别的解释性提升: 通过实验,我领悟了Fisher线性判别如何通过最大化类间差异和最小化类内差异来提高模型的解释性。这种优化使得模型更具可解释性,能够更清晰地揭示人脸数据中的类别差异,为实际应用提供更为直观的判别依据,对理解模型决策背后的原因具有指导意义。

  4. 特征选择与降维方法的深入认识: 通过实际应用,我对特征选择和降维方法有了更加深入的认识。通过实验经验,我能有针对性地选择合适的特征提取和降维方法,使得Fisher线性判别在实际人脸识别系统中更为有效地应用。

  5. 实践经验的积累与未来展望: 通过本次实验,我不仅拓宽了对Fisher线性判别的理解,还提升了实验技能。这为将理论知识应用于实际问题提供了有力的支持,为未来进一步优化人脸识别算法奠定了坚实的基础。


📝总结

模式匹配领域就像一片未被勘探的信息大海,引领你勇敢踏入数据科学的神秘领域。这是一场独特的学习冒险,从基本概念到算法实现,逐步揭示更深层次的模式分析、匹配算法和智能模式识别的奥秘。渴望挑战模式匹配的学习路径和掌握信息领域的技术?不妨点击下方链接,一同探讨更多数据科学的奇迹吧。我们推出了引领趋势的💻 数据科学专栏:《模式之谜 | 数据奇迹解码》,旨在深度探索模式匹配技术的实际应用和创新。🌐🔍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/264735.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

助力智能人群检测计数,基于DETR(DEtectionTRansformer)开发构建通用场景下人群检测计数识别系统

在一些人流量比较大的场合&#xff0c;或者是一些特殊时刻、时段、节假日等特殊时期下&#xff0c;密切关注当前系统所承载的人流量是十分必要的&#xff0c;对于超出系统负荷容量的情况做到及时预警对于管理团队来说是保障人员安全的重要手段&#xff0c;本文的主要目的是想要…

读算法霸权笔记01_数学杀伤性武器

1. 数学应用助推数据经济&#xff0c;但这些应用的建立是基于不可靠的人类所做的选择 1.1. 房地产危机&#xff0c;大型金融机构倒闭&#xff0c;失业率上升&#xff0c;在幕后运用着神奇公式的数学家们成为这些灾难的帮凶 1.2. 数学逐渐不再关注全球金融市场动态&#xff0c…

Flutter笔记:Web支持原理与实践

Flutter笔记 Web支持原理与实践 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com CSDN&#xff1a;https://blog.csdn.net/qq_28550263/article/details/135037756 华为开发者社区…

任天堂,steam游戏机通过type-c给VR投屏与PD快速充电的方案 三type-c口投屏转接器

游戏手柄这个概念&#xff0c;最早要追溯到二十年前玩FC游戏的时候&#xff0c;那时候超级玛丽成为了许多人童年里难忘的回忆&#xff0c;虽然长大了才知道超级玛丽是翻译错误&#xff0c;应该是任天堂的超级马里奥&#xff0c;不过这并不影响大家对他的喜爱。 当时FC家用机手柄…

【Android】存储读取权限管理理解和api 调研报告

背景 工作和学习需要了解android 权限管理和 对应的api 调用逻辑。 学习 内部路径 不用权限 /data/data/应用包名 相关API Context 类 getCacheDir 缓存路径 getCodeCacheDir 示意路径 getFilesDir 内部文件 文件路径 fileList &#xff08;files 下的所有文件名&…

【Unity基础】9.地形系统Terrain

【Unity基础】9.地形系统Terrain 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;地形编辑器Terrain &#xff08;1&#xff09;创建地形 游戏场景中大多数的山川河流地表地貌都是基…

【单调栈】LeetCode:2818操作使得分最大

作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 涉及知识点 单调栈 题目 给你一个长度为 n 的正整数数组 nums 和一个整数 k 。 一开始&#xff0c;你的分数为 1 。你可以进行以下操作至多 k 次&#xff0c;目标是使你的分数最大&#xff1a; 选择一个之前没有选过的 非…

Pipelined-ADC设计二——结构指标及非理想因素(Part1)

本章将详细介绍电路各个模块的设计思路和设计中需要注意的关键点&#xff0c;给出流水线ADC中的非理想因素&#xff0c;并计算出流水线ADC各个模块具体指标。根据电路中信号的传输方向&#xff0c;依次介绍采样保持电路、Sub_ADC&#xff0c;MDAC 等模块的设计。&#xff08;本…

CSS自适应分辨率 amfe-flexible 和 postcss-pxtorem:Webpack5 升级后相关插件和配置更新说明

前言 项目对应的 webpack5 版本如下&#xff1a; npm i webpack5.89.0 -D npm i webpack-cli5.1.4 -D升级插件 说明一下&#xff0c;我更喜欢固定版本号&#xff0c;这样随机bug会少很多&#xff0c;更可控~ npm i postcss-loader6.1.1 -D npm i postcss-pxtorem6.0.0 -D配…

Hive-high Avaliabl

hive—high Avaliable ​ hive的搭建方式有三种&#xff0c;分别是 ​ 1、Local/Embedded Metastore Database (Derby) ​ 2、Remote Metastore Database ​ 3、Remote Metastore Server ​ 一般情况下&#xff0c;我们在学习的时候直接使用hive –service metastore的方式…

基于SpringBoot简洁优雅的个人博客系统

源代码下载地址&#xff1a; 点击这里下载 项目备注 1、该资源内项目代码都经过测试运行成功&#xff0c;功能ok的情况下才上传的&#xff0c;请放心下载使用&#xff01; 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或…

arduino+pir传感器练习和lcd屏幕库练习

// C code // #include <Adafruit_LiquidCrystal.h>//lcd屏幕库 库根据屏幕下载Adafruit_LiquidCrystal lcd_1(0);//定义lcd屏幕对象void setup() {pinMode(5, INPUT);//定义pir针脚lcd_1.begin(16, 2);/* begin(16, 2)&#xff1a;是 lcd_1 对象的一个方法调用&#xff…

微软的word文档中内置背景音乐步骤(打开自动播放)

目录 一、前言 二、操作步骤 一、前言 有时候需要在word文档里面打开的时候就自动播放音乐或者音频&#xff0c;那么可以用微软的word来按照操作步骤去这样完成。 如果没有微软office的&#xff0c;可以下载这个是2021专业版的。因为office只能免费使用一段时间&#xff0c…

thinkphp+vue+mysql酒店客房管理系统 b1g8z

本系统包括前台界面、用户界面和管理员界面、员工界面。在前台界面里游客和用户可以浏览客房信息、公告信息等&#xff0c;用户可以预定客房&#xff0c;在用户中心界面里&#xff0c;用户可以管理预定信息&#xff0c;管理员负责用户预定的审核以及客房的发布、用户的入住等。…

Java之HashMap核心源码解读

HashMap核心源码解读 HashMap 简介 HashMap 主要用来存放键值对&#xff0c;它基于哈希表的 Map 接口实现&#xff0c;是常用的 Java 集合之一&#xff0c;是非线程安全的。 HashMap 可以存储 null 的 key 和 value&#xff0c;但 null 作为键只能有一个&#xff0c;null 作…

DshanMCU-R128s2启动与资源划分

启动与资源划分 下面简单介绍一下 R128 方案的资源划分与启动流程。 资源划分 CPU 资源划分 这只是默认配置方案&#xff0c;CPU 资源划分可以按照需求任意修改 CPU功能说明M33控制核。运行 WI-FI/BT 固件、协议栈、驱动、休眠唤醒、安全启动、安全控制C906应用核。运行大…

Linux内核模块文件组成介绍

Linux驱动开发主要的工作就是编写模块&#xff0c;一个典型的Linux内核模块文件.ko 主要由以下几个部分组成。 模块加载函数(必须) 当通过insmod或modprobe命令加载内核模块时&#xff0c;模块的加载函数会自动被内核执行&#xff0c;完成本模块的相关初始化工作。 Linux内核模…

深度解析LinkedList

LinkedList是Java集合框架中List接口的实现之一&#xff0c;它以双向链表的形式存储元素。与传统的数组相比&#xff0c;链表具有更高的灵活性&#xff0c;特别适用于频繁的插入和删除操作。让我们从底层实现开始深入了解这个强大的数据结构。 底层数据结构 LinkedList的底层数…

python画图【00】Anaconda和Pycharm和jupyter的使用

①Anaconda ②Pycharm 一、Anaconda安装步骤 1、双击安装包&#xff0c;点击next。 2、点我同意I agree 3、 4、选择需要安装的位置&#xff0c;位置可根据自己情况安装到具体位置&#xff0c;但要记住安装到了哪里。然后点击next 5、可选择加入到环境变量&#xff0c;…

Linux内核编码规范

学习linux内核或者linux驱动的人应该先掌握内核编码规范&#xff0c;这样才能更好的驾驭linux内核、驱动。 下面就从这几个方面讲解一下linux内核编码规范。 注释风格、排版风格、头文件风格、变量定义、宏定义、函数 1 注释风格 1.1 注释的原则是有助于对程序的阅读和理解&…