OpenCV 机器学习之 支持向量机的用法实例


用支持向量机进行文理科生的分类,依据的特征主要是 数学成绩与语文成绩,这两个特征都服从高斯分布

程序代码如下:

#include 
   
   
    
    
#include 
    
    
     
     

using namespace std;
using namespace cv;

 
//生成具有一个特征的指定类别的训练数据集
void GenerateTrainData_two_feature(int sample_counts,double miu1,double sigma1,double miu2,double sigma2,Mat& train_data);
//把属于两个类的训练数据集混和起来,并记录对应的类别标签
void MixTrainDataFromTwoClasses(Mat& train_data1,Mat& train_data2,Mat& total_train_data,Mat& total_train_data_response);

int main(int argc, char* argv[])
{
 
	int features_count = 2;  //每个样本包含两个特征: 数学成绩 与 语文成绩
	
	//生成类别一的训练数据集: 若干文科生的 数学成绩 和 语文成绩,假定这两个特征都服从高斯分布
	int SampleCount1 = 200;  //训练数据集1 的 样本个数
	Mat TrainData1(SampleCount1,features_count,CV_32FC1); 	//训练数据集1 的 样本特征向量
	//假定文科生的数学成绩的概率密度分布参数:均值 40,和 标准差 10
	double sigma11 = 10;double miu11 = 40;  
	//假定文科生的语文成绩的概率密度分布参数:均值 80,和 标准差 10
	double sigma12 = 10;double miu12 = 80;  
	//调用该函数生成文科生特征训练集
	GenerateTrainData_two_feature(SampleCount1,miu11,sigma11,miu12,sigma12,TrainData1); 
	cout<
     
     
      
      <<"文科生的成绩分布规律"<
      
      
       
       (i)[0] = response;
	}
	cout<<"数学语文联合特征分类结果:"<
       
       
         < 
        
          (i*101+j,0) = i; //第一个特征是数学成绩,0到100 TestSamples.at 
         
           (i*101+j,1) = j; //第二个特征是语文成绩, 0到100 } } //调用分类器对测试样本进行分类 for(int i=0;i<101*101;i++) { Mat sample = TestSamples.rowRange(i,i+1); float response = svm.predict(sample,false); TestSamplesResult.ptr 
          
            (i)[0] = response; } //绘制分类结果 Mat result_map(101,101,CV_8UC3); for(int i=0;i<101;i++) { for(int j=0;j<101;j++) { int label = (int)TestSamplesResult.at 
           
             (i*101+j,0); Vec3b v = label==1? Vec3b(255,0,0) : Vec3b(0,0,255); //蓝色代表第1类,红色代表第二类 result_map.at 
            
              (i,j) = v; //判决面中从左往右的顺序是语文成绩依次增加,从上往下的顺序是数学成绩依次增加 } } //把训练数据点画出来 for(int t=0;t 
             
               (t,0); pt.x = TotalSamplesData.at 
              
                (t,1); int label = SamplesResponse.ptr 
               
                 (t)[0]; //白色的点是第二类的训练点集合,黑色的点是第一类的训练点集合 circle(result_map,pt,1,label==1? CV_RGB(0,0,0):CV_RGB(255,255,255)); } namedWindow("分类器判决面",0); imshow("分类器判决面",result_map); cout< 
                
                  <<"判决面中 蓝色代表第1类:文科生,红色代表第二类:理科生"< 
                  
                  
                    (k),train_data1.ptr 
                   
                     (i),sz1.width*(sizeof(float))); total_train_data_response.at 
                    
                      (k) = 1; k++; memcpy(total_train_data.ptr 
                     
                       (k),train_data2.ptr 
                      
                        (i),sz2.width*(sizeof(float))); total_train_data_response.at 
                       
                         (k) = 2; k++; } //如果两类样本的数目不一样,则把多余的样本追加到末尾 if(sz1.height > sz2.height) { for(int i = sz2.height;i 
                        
                          (k),train_data1.ptr 
                         
                           (i),sz1.width*(sizeof(float))); total_train_data_response.at 
                          
                            (k) = 1; k++; } } if(sz2.height > sz1.height) { for(int i = sz1.height;i 
                           
                             (k),train_data2.ptr 
                            
                              (i),sz2.width*(sizeof(float))); total_train_data_response.at 
                             
                               (k) = 2; k++; } } } //生成具有两个特征的指定类别的训练数据集 void GenerateTrainData_two_feature(int sample_counts,double miu1,double sigma1,double miu2,double sigma2,Mat& train_data) { int64 seed =/*100*/ getTickCount();//随机数种子,每次生成不一样的随机数 RNG rng1(seed); //创建一个随机数发生器对象 RNG rng2(seed*2); //创建一个随机数发生器对象 double MinFeatureValue = 0; // 特征的最小值 double MaxFeatureValue = 100;// 特征的最大值 //训练数据集矩阵初始化,样本按行存储,每一行是一个样本的2维特征向量, train_data = Mat::zeros(sample_counts,2,CV_32FC1); //循环生成样本特征集合 for(int i=0;i 
                              
                                =MinFeatureValue && a<=MaxFeatureValue) { //如果返回的随机数在指定的特征范围区间内部,则把它加入样本集 train_data.at 
                               
                                 (i,0) = a ; } else { //如果返回的随机数超出了指定的特征范围的边界,为简单起见,直接把均值加入样本集 train_data.at 
                                
                                  (i,0) = miu1 ; } if(b>=MinFeatureValue && b<=MaxFeatureValue) { //如果返回的随机数在指定的特征范围区间内部,则把它加入样本集 train_data.at 
                                 
                                   (i,1) = b ; } else { //如果返回的随机数超出了指定的特征范围的边界,为简单起见,直接把均值加入样本集 train_data.at 
                                  
                                    (i,1) = miu2 ; } } } 
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

分类结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值