⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fisher.cpp

📁 模式识别中有关分类的
💻 CPP
字号:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

#include "fisher.h"

ofstream out("out.txt");


fisher::fisher()
{
	string s, t;
	cout<<"请输入每个样本的维数d:";
	cin>>d;

	error_train = 0;
	error_test = 0;

	//动态创建测试集和训练集中的样本数组
	for(int i =0; i < 2; i++)
	{
		for(int j = 0; j < 50; j++)
		{
			train[i][j].Sample = new float[d];
			test[i][j].Sample = new float[d];
			train_y[i][j] = 0.0;
			test_y[i][j] = 0.0;
		}
		m[i].Sample = new float[d];
		Matrix_S[i] = new float*[d];
		Matrix_Sw   = new float*[d];

		for(j = 0; j < d; j++)
		{
			Matrix_S[i][j] = new float[d];
			Matrix_Sw[j] = new float[d];
		}

		//初始化矩阵
		for(j = 0; j < d; j++)
		{
			for(int k = 0; k < d; k++)
			{
				Matrix_S[i][j][k] = 0.0;
				Matrix_Sw[j][k] = 0.0;
			}
		}
	}

	W.Sample = new float[d];

	for(i = 0; i < d; i++)
		W.Sample[i] = 0.0;

	//读取文件名称
	cout<<"请输入训练集样本存放的文件名:";
	cin>>train_file;
	cout<<"请输入测试集样本存放的文件名:";
	cin>>test_file;

	//从文件中读取数据初始化变量
	ifstream train_in(train_file);
	ifstream test_in(test_file);

	out<<endl;
	out<<"各类样本的向量均值如下:"<<endl;
	for(i = 0; i < 2; i++)
	{
		for(int k = 0; k < d; k++)
			m[i].Sample[k] = 0;

		for(int j = 0; j< 50; j++)
		{
			string temp1, temp2;

			//开始读取文件每一行的内容
			getline(train_in, s);
			getline(test_in, t);
			istringstream sin(s);
			istringstream tin(t);
			
			//过滤掉文件中每一行前两段无用的信息
			sin>>temp1;
			sin>>temp2;

			tin>>temp1;
			tin>>temp2;

			//开始正式读取升高与体重数据
			for(k = 0; k < d; k++)
			{
				sin>>train[i][j].Sample[k];
				tin>>test[i][j].Sample[k];
				m[i].Sample[k] += train[i][j].Sample[k];
				//cout<<train[i][j].Sample[k]<<" "; 
			}
			//cout<<endl;		
		}
		getline(train_in, s);

		//cout<<endl;

		//求解各类样本的向量均值
		for(k = 0; k < d; k++)
		{
			m[i].Sample[k] /=50;
			out<<m[i].Sample[k]<<" ";
		}
		out<<endl<<endl;
	}
}


//矩阵求逆
void fisher::Inverse() 
{
	float **temp_matrix, t;
	int i, j, k, l;
	temp_matrix = new float*[d];
	Matrix_Sw_1 = new float*[d];
	for(i = 0; i < d; i++)
	{
		temp_matrix[i] = new float[2*d];
		Matrix_Sw_1[i] = new float[d];
	}

	/////////////////////////////开始对矩阵求逆///////////////////////////////

	//对temp_matrix矩阵进行扩展,temp_matrix矩阵添加单位阵,由d*d变成d*2d矩阵
	for(j = 0; j < d; j++)
	{
		for(k = 0; k < 2*d; k++)
		{
			if (k < d)  temp_matrix[j][k] = Matrix_Sw[j][k]; 
			else if (k == d+j)  temp_matrix[j][k] = 1; 
			     else temp_matrix[j][k] = 0; 
		}
	}

	//对temp_matrix矩阵进行变换,使得前半部分矩阵成为单位阵,则
    //后半部分矩阵即为所求矩阵逆阵
	for(i = 0; i < d; i++) 
	{ 
		//对第i行进行归一化 
		for (j = 0 ; j < 2*d; j++) 
			for(k = i+1; k < d; k++) 
				temp_matrix[i][j] = temp_matrix[i][j] + temp_matrix[k][j]; 
		t = temp_matrix[i][i]; 
		for(j = i;j < 2*d; j++) 
			temp_matrix[i][j] = temp_matrix[i][j] / t; 

	
		//对矩阵进行行变换,使得第i列只有一个元素不为零,且为1
		for(k = 0; k < d; k++) 
			if(k != i) 
			{ 
				t = temp_matrix[k][i]; 
				for (l = i; l < 2*d; l++) 
					temp_matrix[k][l] = temp_matrix[k][l] - temp_matrix[i][l] * t; 
			} 
	}

	//将后半部分矩阵即所求矩阵逆阵存入Matrix_Sw_1矩阵。
  for(i = 0; i < d; i++) 
   { 
    for(j = 0; j < d; j++) 
      Matrix_Sw_1[i][j] = temp_matrix[i][j+d]; 
   }

  //所求逆矩阵
  for(i = 0; i < d; i++)
	{
		for(j = 0; j < d; j++)
			out<<Matrix_Sw_1[i][j]<<"  ";
		out<<endl;
	}
}

fisher::~fisher()
{
	for(int i =0; i < 2; i++)
	{
		for(int j = 0; j < 50; j++)
		{
			  delete[] train[i][j].Sample;
			  delete[] test[i][j].Sample;
		}
		delete[] m[i].Sample;
	}
	delete[] W.Sample;
}

void fisher::put_Matrix_S()
{
	int i, j, k, l;
	for(i = 0; i < 2; i++)
	{
		for(j = 0; j < 50; j++)
		{
			float temp = 0;
			for(k = 0; k < d; k++)
				for(l = 0; l < d; l++)
				{
					temp = (train[i][j].Sample[k] - m[i].Sample[k]) * (train[i][j].Sample[l]-m[i].Sample[l]);
					Matrix_S[i][k][l] += temp;
				}
		}

		for(j = 0; j < d; j++)
		{
			for(int k = 0; k < d; k++)
				out<<Matrix_S[i][j][k]<<" ";
			out<<endl;
		}
		out<<endl;
	}
}

void fisher::put_Matrix_Sw()
{
	int i, j, k;

	for(i = 0; i < 2; i++)
		for(j = 0; j < d; j++)
			for(k = 0; k < d; k++)
				Matrix_Sw[j][k] += Matrix_S[i][j][k];

	for(j = 0; j < d; j++)
		{
			for(k = 0; k < d; k++)
				out<<Matrix_Sw[j][k]<<" ";
			out<<endl;
		}
}

void fisher::put_W()
{
	int i, j;
	for(i = 0; i < d; i++)
	{
		for(j = 0; j < d; j++)
			W.Sample[i] += Matrix_Sw_1[i][j]*(m[0].Sample[j]-m[1].Sample[j]);
	}

	cout<<endl;
	for(i = 0; i < d; i++)
		out<<W.Sample[i]<<"  ";
	out<<endl;
}

float fisher::min()
{
 	float min_y; 
	int j;
	min_y = train_y[0][0];
	for(j = 1; j < 50; j++)
		if(train_y[0][j] < min_y) min_y = train_y[0][j];
	return min_y;
}

float fisher::max()
{
 	float max_y; 
	int j;
	max_y = train_y[1][0];
	for(j = 1; j < 50; j++)
		if(max_y < train_y[1][j]) max_y = train_y[1][j];
	return max_y;
}

void fisher::put_y()
{
	int i, j, k;
	for(i = 0; i < 2; i++)
	{
		for(j = 0; j < 50; j++)
		{
			for(k = 0; k < d; k++)
			{
				train_y[i][j] += W.Sample[k] * train[i][j].Sample[k];
				test_y[i][j] += W.Sample[k] * test[i][j].Sample[k];
			}
		}
	}

	float temp1 = min();
	float temp2 = max();
	d0 = (temp1 + temp2) / 2;

	out<<endl;
	out<<"经过一系列计算后训练集对应的影射结果如下:"<<endl;
	for(i = 0; i < 2; i++)
	{
		k = 0;
		for(j = 0; j < 50; j++)
		{
			out<<train_y[i][j]<<"   ";
			k++;
			if(k % 10 == 0) out<<endl;
		}
		out<<endl;
	}

	out<<endl;
	out<<"经过一系列计算后测试集对应的影射结果如下:"<<endl;
	for(i = 0; i < 2; i++)
	{
		k = 0;
		for(j = 0; j < 50; j++)
		{
			out<<test_y[i][j]<<"   ";
			k++;
			if(k % 10 == 0) out<<endl;
		}
		out<<endl;
	}

	out<<endl;
	out<<temp1<<"   "<<temp2<<endl;
	out<<"阈值为:"<<d0<<endl;
}

void fisher::Analysis()
{
	int i, j;
	for(i = 0; i < 2; i++)
	{
		for(j = 0; j < 50; j++)
		{
			if(i == 0 && train_y[i][j] < d0) error_train++;
			else if(i == 1 && train_y[i][j] > d0) error_train++;
		}

		for(j = 0; j < 50; j++)
		{
			if(i == 0 && test_y[i][j] < d0) error_test++;
			else if(i == 1 && test_y[i][j] > d0) error_test++;
		}
	}

	out<<endl;
	out<<"经过一系列分析后的结果如下:"<<endl;
	out<<"训练集中两类样本以阈值"<<d0<<"为标准所发生的失效百分比为:"<<error_train<<"%"<<endl;
	out<<"测试集中两类样本以阈值"<<d0<<"为标准所发生的失效百分比为:"<<error_test<<"%"<<endl;
}

void main(void)
{
	out<<"程序每步运行情况如下:"<<endl;

	fisher fisher_test;

	out<<endl;
	out<<"样本类内离散度矩阵如下:"<<endl;
	fisher_test.put_Matrix_S();

	out<<endl;
	out<<"总类内离散度矩阵如下:"<<endl;
	fisher_test.put_Matrix_Sw();

	out<<endl;
	out<<"总类内离散度矩阵逆矩阵如下:"<<endl;
	fisher_test.Inverse();

	out<<endl;
	out<<"向量W*如下:"<<endl;
	fisher_test.put_W();

	fisher_test.put_y();

	fisher_test.Analysis();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -