/* 第一步:从文档中读取训练样本集 ;假设一个有5用类型 文件中格式: 1 A00,A01...A0(n-1); 2 . 3 . 1 . 5 A(m-1)0,A(m-1)1...A(m-1)(n-1);T(m-1)() 当在程序中定义数组时,定义为trainingspeciemens[n][m+1] 每个样本的倒数第一个数为改数据所属的类型, 第二步:输入K,和待分类样本 R 第三步:计算R与一个训练样本的欧几里得距离 第四步:选出与 样本 R 的K个最小样本 第五步:选出包含 K个最邻近样本中最多样本的类别 第六步:把样本R归于k个样本最大类别 */ #include<iostream> #include<cmath> #include<fstream> using namespace std; #define k 4//选出k个样本 #define n 5//文档中样本数 #define m 4//样本维数 #define maxclass 5//规定最大类别数 int classnumber[maxclass]; struct TrainSet{ int tab; double distancetov; double classlabel; double samples[m]; }; TrainSet trainset[n];//从文档中读取的样本放在这里 TrainSet v;//用户输入的样本 struct Ksample{ double classlabel; }K[k];//选出来的k个最近样本放在这里 //第一步: 从文件中读取数据 void read(){ ifstream fin("D:\训练样本集文件.txt"); for(int i=0;i<n;i++){ fin>>trainset[i].classlabel; for(int j=0;j<m;j++) fin>>trainset[i].samples[j]; } fin.close(); //cin.get(); } //第二步:输入K,和待分类样本 v void Input(struct TrainSet v){ //struct TrainSet v; cout<<"please input the "<<m<<" specimen of v:"; for(int i=0;i<m;i++) cin>>v.samples[i]; /* for(int i=0;i<m;i++) cout<<v.samples[i]<<" ";*/ } //第三步:计算样本v与训练集中每个样本的欧几里得距离 void DistanceALL(struct TrainSet v){ double squaresum=0.0,temp=0.0; for(int j=0;j<n;j++){ for(int i=0;i<m;i++){ temp=v.samples[i]-trainset[j].samples[i]; temp=temp*temp; squaresum+=temp; } trainset[j].distancetov=sqrt(squaresum); } for(int i=0;i<n;i++) cout<<trainset[i].distancetov<<" "; } //第四步:选出与样本 v 的K个最小样本 void ChooseK(){ int min; for(int i=0;i<n;i++) trainset[i].tab=0; for(int i=0;i<n;i++){ min=i; for(int j=i+1;j<n;j++){ if(trainset[i].tab==0&&trainset[min].distancetov<trainset[j].distancetov) min=j; } K[i].classlabel=trainset[min].classlabel; trainset[min].tab=1; } } //第五步:选出包含 K个最邻近样本中最多样本的类别作为代分类类别 int ChooseMax(){ for(int i=0;i<k;i++){ for(int j=0;j<maxclass;j++) if(K[i].classlabel==j) classnumber[j]++; } int max=0; for(int j=1;j<maxclass;j++) if(classnumber[max]<classnumber[j]) max=j; return max; } //第六步:更新训练样本集 int main(){ for(int i=0;i<maxclass;i++) classnumber[i]=0; read(); Input(v); for(int i=0;i<n;i++){ cout<<trainset[i].classlabel<<endl; for(int j=0;j<m;j++){ cout<<trainset[i].samples[j]<<" "; } cout<<endl; } DistanceALL(v); /* for(int i=0;i<n;i++) cout<<trainset[i].distance<<" ";*/ ChooseK(); cout<<"The sample v belong to "<<ChooseMax()<<endl; return 0; }
为什么read()之后输出不了距离,其他也有问题,我调试不过
你好,我帮你找到一个错误,把 ifstream fin("D:\训练样本集文件.txt");这行代码改成 ifstream fin("D:\\训练样本集文件.txt");
希望能帮助你
另外,我看了这一整篇代码,我想如果想要这篇代码执行成功的话,还有两个地方要改,就是把void Input(structTrainSet v)和void DistanceALL(struct TrainSet v)这两个函数的参数去掉改成void Input()和void DistanceALL()就行了,
希望能帮助你
@kevinGao: 你好,参数去和不去都一样喔,读文件路径更对后可以输出距离了,但是分类那里错了,无论输入什么数据都是输出待分类的样本类型为0
@爱嘉牛LA: 我想这是因为你的参数是按值传递的,导致参数作用域出问题了,既然你用的是全局的V和trainset[n],所以我建议你去掉参数列表试试看,
希望能帮助你
@kevinGao: 真的麻烦你了,我按照你的做法发程序改了。自己还发觉了void DistanceALL的错误,并改进了。通过调试,发觉void ChooseK()函数错了!你改后的代码如下,请帮我改下,麻烦了
/*
第一步:从文档中读取训练样本集 ;假设一个有5用类型
                            文件中格式:                        
                                      1 A00,A01...A0(n-1);           
           2 .                                        
           3 .                                        
           1 .                                        
                          5 A(m-1)0,A(m-1)1...A(m-1)(n-1);T(m-1)()  
                          当在程序中定义数组时,定义为trainingspeciemens[n][m+1]
        每个样本的倒数第一个数为改数据所属的类型,
        
         
第二步:输入K,和待分类样本 R
第三步:计算R与一个训练样本的欧几里得距离
第四步:选出与 样本 R 的K个最小样本
第五步:选出包含 K个最邻近样本中最多样本的类别
第六步:把样本R归于k个样本最大类别   
*/
#include<iostream>
#include<cmath>
#include<fstream>
using namespace std;
#define k 4//选出k个样本 
#define n 5//文档中样本数 
#define m 4//样本维数
#define maxclass 5//规定最大类别数 
int classnumber[maxclass];
struct TrainSet{
 int tab; 
 double distancetov;
 double classlabel;
 double samples[m];
};
TrainSet trainset[n];//从文档中读取的样本放在这里 
TrainSet v;//用户输入的样本
struct Ksample{
 double distance;
 double classlabel;
};//选出来的k个最近样本放在这里
Ksample K[k];
//第一步: 从文件中读取数据
void read(){
    ifstream fin("D:\\训练样本集文件.txt");
 for(int i=0;i<n;i++){
  fin>>trainset[i].classlabel;
  for(int j=0;j<m;j++)
    fin>>trainset[i].samples[j];
 } 
 fin.close();
    
 //cin.get();
}
//第二步:输入K,和待分类样本 v 
void Input(){
 //struct TrainSet v;
 cout<<"please input the "<<m<<" specimen of v:";
 for(int i=0;i<m;i++)
    cin>>v.samples[i]; 
  /*
  for(int i=0;i<m;i++)
       cout<<v.samples[i]<<" ";*/
}
//第三步:计算样本v与训练集中每个样本的欧几里得距离如果类型数都相等
 
void DistanceALL(){
 double squaresum,temp=0.0;
 for(int j=0;j<n;j++){
  squaresum=0.0;
  for(int i=0;i<m;i++){
  temp=v.samples[i]-trainset[j].samples[i];
  temp=temp*temp;
  squaresum+=temp;
   }
   trainset[j].distancetov=sqrt(squaresum);
 }
 cout<<"The all distance:"<<endl;
}
//第四步:选出与样本 v 的K个最小样本
void ChooseK(){
 int min;
 for(int i=0;i<n;i++)
    trainset[i].tab=0;
 for(int i=0;i<k;i++){
  for(int t=0;t<n;t++)
   if(trainset[t].tab==0){
    min=t;
    break;
      }
  for(int j=0;j<n;j++){
   if((trainset[i].tab==0)&&(trainset[min].distancetov<trainset[j].distancetov))
        min=j;
  }
  trainset[min].tab=1;
  K[i].classlabel=trainset[min].classlabel;
     K[i].distance=trainset[min].distancetov;
  cout<<K[i].distance<<"  \t"<<K[i].classlabel<<endl;
        
 }
 cout<<"The "<<k<<"is:"<<endl;
 /*
for(int i=0;i<k;i++)
     cout<<"Distance:"<<K[i].distance<"  "<<"Class:"<<K[i].classlabel<<endl;
 */
}
//第五步:选出包含 K个最邻近样本中最多样本的类别作为代分类类别 ,那么选择最近的那个作为他的类型
int ChooseMax(){
 
    for(int i=0;i<k;i++){
     for(int j=0;j<maxclass;j++)
       if(K[i].classlabel==j)
       classnumber[j]++;
    } 
    int max=0;
    for(int j=1;j<maxclass;j++)
        if(classnumber[max]<classnumber[j])
          max=j;
          
    return max;
}
//第六步:更新训练样本集        
int main(){
 for(int i=0;i<maxclass;i++)
     classnumber[i]=0;
    
 read();
 
 Input();
  for(int i=0;i<n;i++){
  cout<<trainset[i].classlabel<<endl;
  for(int j=0;j<m;j++){
   cout<<trainset[i].samples[j]<<" ";
  }
  cout<<endl;
 }
 DistanceALL();
  for(int i=0;i<n;i++)
   cout<<"Distance:"<<trainset[i].distancetov<<"  "<<"\tClass:"<<trainset[i].classlabel<<endl;
/*
 for(int i=0;i<n;i++)
     cout<<trainset[i].distance<<"  ";*/
 ChooseK();
/*
 for(int i=0;i<k;i++)
     cout<<"distance:"<<K[i].distance<"  "<<"Class:"<<K[i].classlabel<<endl;*/
 cout<<"The sample v belong to "<<ChooseMax()<<endl; 
 return 0;
 
}
@爱嘉牛LA:
1 int ChooseMax() 2 { 3 for(int i=0;i<k;i++) 4 { 5 for(int j=0;j<maxclass;j++) 6 if(K[i].classlabel==j) 7 classnumber[j]++; 8 } 9 int max=0; 10 for(int j=0;j<maxclass;j++) 11 if(classnumber[max]<classnumber[j]) 12 max=j; 13 return max+1; 14 }
试试这样可以么