📄 fisher.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 + -