原文:http://blog.csdn.net/u014691453/article/details/40393137

软件版本:

Visual Studio版本:VS2012

(注:使用方法在 VS2010 上面亲测同样可用,只是可能会出现的问题是: VS2010 和 VS2012 之间有些函数写法不同,需在编译前做改动,譬如 VS2010 的 scanf 对比 VS2012 的 scanf_s )

libsvm版本:libsvm-3.18

声明:

如果你找到了我这篇标题的文章,那很大程度上意味着你一定是在 VS 里或者 MFC 里使用 libsvm 工具箱出现了问题。那你也一定知道了,libsvm 在VS工程里的使用与它在 matlab 或者是 python 里面的使用,是多么的不同。

致谢:

如果没有 gg 百分之百的帮助,就凭我在 VS 里编程的菜鸟能力,是绝对不可能1天就搞好的,我绝对会弄半年不止所以非常感谢非常感谢,今后我一定认真学习编程。

正文:

分三部分:第一部分:先把 VS 工程的框架建好

第二部分:工程里包含主函数的 cpp 文件要怎么写

第三部分:把 libsvm 工具箱移植到 MFC 中进行使用

第四部分:在本文代码中能够正确运行的数据格式

资源地址:如何在Visual Studio(VS)里使用libsvm工具箱(与博文相关的代码包)

第一部分:先把 VS 工程的框架建好

之前一直都是在 matlab 里面使用这个 libsvm 工具箱,也曾经有一段时间在 python 里面使用过,刚接触的时候还在 cmd 控制台上面使用过,libsvm 的编写者真的很赞,打开此工具箱我们看到的情景是这样的:
 

对于java、matlab、python、windows 都有相对应的文件夹,文件夹里面的内容和上图中的这个 readme 就可以帮助你在以上四种情况下使用了。

那在 VS 里该怎么使用呢?

首先,我们先建立一个Win32控制台项目,起名为 MM ,如下步骤:

然后,把 libsvm 文件夹里的这几个文件(如下图),都拷贝到 MM 项目的文件夹(如下下图)里去,以备后续使用。

然后,在 MM 项目里,我们把 svm.h 和 svm.cpp 分别添加到头文件和源文件里面去,如下图:

然后,在源文件里,右键——新建项:MM.cpp

接下来是第二部分

第二部分:工程里包含主函数的 cpp 文件要怎么写

MM.cpp也就是上面说的包含主函数的 cpp 文件,我们最终要执行的就是它。
首先,我们先给 MM.cpp 里写好需要用到的头文件,如下:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <list>
  5. #include <fstream>
  6. #include <iostream>
  7. #include "svm.h"
  8. using namespace std;

接下来的内容大致分五部分:

第一:读入训练数据和测试数据
第二:构建参数 param 的结构体(主要目的就是让VS知道你要用的参数都是什么)
第三:构建分类问题 prob 的结构体(主要就是把第一步读入的数据传递给 svm_train 和 svm_predict)
第四:主函数如下
第五:结果展示
 

第一:读入训练数据和测试数据

首先,在读数据之前,先定义一些变量(整个程序还是主要参考的 libsvm/svm_toy/qt/svm_toy.cpp 这个代码,由于目前我编程能力实在是差,所以一些冗余的代码我都没有删改,仅仅只实现了能够使用libsvm的目的。)
  1. #define XLEN 10  //生产测试数据,这个感觉就是无用的地方
  2. #define YLEN 10
  3. ofstream outdata;  //需要准备的所有数据的标签label和特征feature都是分开的,而且特征feature前面不需要加序号冒号这种东西,只需用空格隔开就好
  4. ifstream indata;   //所以这里indata只包含特征,indata_label只包含label,每一行是一个样本的。
  5. ofstream outdata_lable;
  6. ifstream indata_lable;
  7. int NUM = 1440;   //由于我的样本特征是 1440 维,所以读数据的时候,我定义了个数,你可以根据自己特征的维度对 NUM 进行更改。
  8. //char default_param[] = "-t 2 -c 100";  // 这个是 svm_toy.cpp 里对参数的选择
  9. char default_param[] = "-t 2 -c 4 -g 32";  // 这个是匹配我数据的参数
  10. struct point {                           //这个是后面 svm_train 拿来数据做训练时候的数据传入方式
  11. double *feature;
  12. //signed char value;
  13. int value;
  14. };
  15. list<point> point_list;        // 通过 indata 读进来的数据就放在 point_list 里面
  16. int current_value = 1;          // 路人甲变量
  17. void clear_all()         // 清空链表
  18. {
  19. point_list.clear();
  20. }

然后,我们先读入训练数据,用来训练模型

  1. void readFile1(char *file,char *file_lable)  //定义读入训练数据的函数叫做 readFile1
  2. {
  3. indata.open(file,ios::in);               //读入特征
  4. indata_lable.open(file_lable,ios::in);    // 读入标签
  5. cout <<"read data begin"<<endl;          // 屏显
  6. clear_all();
  7. while(!indata.eof())              // 如果没有读到文件结束,就继续读,知道读完整个 traindata 文件
  8. {
  9. double *line = new double[NUM];
  10. for(int i =0;i<NUM;i++)
  11. {
  12. indata >> line[i];       //把特征存起来
  13. }
  14. point p;
  15. indata_lable >>p.value;          //把label存起来
  16. p.feature = line;
  17. point_list.push_back(p);
  18. }
  19. point_list.pop_back();        //如果你的 traindata.txt 文件数据的最后有一个空格的话,需要加上这句话,否则预测会有错如果没有空格,这句话就不需要了
  20. indata.close();
  21. indata_lable.close();
  22. cout <<"read data end"<<endl;
  23. }
 
接下来,读入测试数据:
  1. void readFile2(char *file,char *file_lable)  // 读入测试文件的函数叫做 readFile2
  2. {
  3. indata.open(file,ios::in);      //接下来代码和上面读训练数据是一个样子的
  4. indata_lable.open(file_lable,ios::in); // <span style="font-family: Arial, Helvetica, sans-serif;">由于读训练数据之后就会建立model,然后才会读测试数据,所以不用担心会有数据覆盖的问题</span>
  5. cout <<"read test data begin"<<endl;
  6. clear_all();
  7. while(!indata.eof())
  8. {
  9. double *line = new double[NUM];
  10. for(int i =0;i<NUM;i++)
  11. {
  12. indata >> line[i];
  13. }
  14. point p;
  15. indata_lable >>p.value;
  16. p.feature = line;
  17. point_list.push_back(p);
  18. }
  19. point_list.pop_back();
  20. cout <<"read test data end size = "<<point_list.size()<<endl;
  21. indata.close();
  22. indata_lable.close();
  23. }
 

第二:构建参数 param 的结构体

然后,训练模型!:包括了构建参数param结构和构建 prob结构。
由于太长了,我上传到 CSDN 下载页面吧,免积分下载。这段代码主要就是参考的 svm_toy.cpp 文件,同学们好好研读。
 

第三:构建分类问题 prob 的结构体

 
同第二,代码是一起的,我会把整体代码,包括以上写的读入feature和label的代码,发到下载页面
 

第四:主函数如下

  1. int main()
  2. {
  3. int choice;
  4. cout<<"1 train model\n2 test1\n3 test2\n"<<endl;
  5. cin >>choice;
  6. switch(choice)
  7. {
  8. case 1:
  9. {
  10. readFile1("traindata.txt","trainlabel.txt"); //选择1 是训练模型,模型会保存为“model.txt”
  11. run();
  12. break;
  13. }
  14. case 2:
  15. {
  16. readFile2("1.txt","1_label.txt");   // 选择2 是用第一份测试数据进行测试
  17. testData();
  18. break;
  19. }
  20. case 3:
  21. {
  22. readFile2("11.txt","11_label.txt");  // 选择3 是用第二份测试数据进行测试
  23. testData();
  24. break;
  25. }
  26. }
  27. system("pause");
  28. return 0;
  29. }
 

第五:结果展示

等啊等~ 训练结束啦~
接下来就是测试了:
 

第三部分:把 libsvm 工具箱移植到 MFC 中进行使用

 
其实在 MFC 中的使用,和libsvm在普通VS 项目中的使用是一样的。
如果你不想在MFC 里训练 model,那么完全可以把在第二部分中训练出来的 model 拷贝到 MFC 的这个项目里面,然后在 测试数据之前,把 model load进去就好了,具体load方式参照我的代码里test()函数里写的内容。
那么在 MFC 的代码里,你就可以把第二部分代码中的 void run() ,即训练模型部分去掉了
 
注:我就是在 MFC 里使用 libsvm 的时候,发现了 VS2010 和 VS2012 的不同,svm.cpp 和 svm.h 这两个文件里的一些函数,可以在 VS2010 的 MFC 工程里跑的很好,可是到了 VS2012 里就会提示说 “你把 XX 换成 XX_s 会更安全”,是错误而不是警告,所以如果在 VS2012 里面用libsvm的话,需要在svm.cpp 和 svm.h 这两个文件里修改部分函数的表达形式,这个在网上都有解答,可以自行查询。
 

第四部分:在本文代码中能够正确运行的数据格式

在第二部分给出的资源链接里,我上传的资料里包括我的测试数据,1.txt和1_label.txt 就是test1测试的内容,11.txt 和 11_label.txt 就是test2 测试的内容,如果你要测试你自己的数据,记得在test()代码里更改成你自己数据的名称。
 
可以使用的数据格式: 大家可以参照我上传的 1.txt,大致如以下:
 
0.564 0.436 0.675 0.453 0.000 0.345 
0.354 0.345 0.456 0.000 0.346 0.645 
0.678 0.678 0.866 0.757 0.575 0.867 
0.866 0.865 0.856 0.867 0.557 0.754 
 
我的1_label.txt,大致如以下:
 
1
1
2
2
 
如以上格式,因为我的数据是之前通过 matlab 处理过的,所以空格位置用的是 ‘\t’ 。
 
如果你的数据格式和我不一样,只有两条路: 1:改成我这样的数据格式  2:更改代码里读数据这部分的程序,保证读进去的数据是对的就好 
或者还有一条路,就是自己按照你的需要重新写代码。
 
利用了宝贵的一个下午来整理这些东西,希望能够真的帮到像之前的我一样有需要的人。
 
感觉该说的应该都说完了,如果有解释不正确或者漏掉的地方,也请大家告知我,我会再修改

如何在Visual Studio(VS)2012里使用libsvm工具箱的更多相关文章

  1. 如何在"Visual Studio Code"中使用" Git" 进行版本控制

    如何在"Visual Studio Code"中使用" Git" 进行版本控制 本来认为此类教程,肯定是满网飞了.今天首次使用VS Code的Git功能,翻遍了 ...

  2. 如何在 Visual Studio 中使用 Git 同步代码到 CodePlex

    开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework.ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐.CodePlex 则是 ...

  3. [转]如何在 Visual Studio 中使用 Git 同步代码到 CodePlex

    本文转自:http://www.cnblogs.com/stg609/p/3673782.html 开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framew ...

  4. 如何在Visual Studio中选择C++和C#的编译器版本

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何在Visual Studio中选择C++和C#的编译器版本.

  5. Microsoft Visual Studio Ultimate 2012 旗舰版 有效注册密钥

    Microsoft Visual Studio Ultimate 2012 旗舰版 有效注册密钥: YKCW6-BPFPF-BT8C9-7DCTH-QXGWC 已经过本人测试 本着分享的精神,希望大家 ...

  6. Microsoft Visual Studio Professional 2012 专业版 下载

    记录(以下内容来自网络收集): 下载地址: https://www.microsoft.com/zh-cn/download/details.aspx?id=30682 直接iso连接下载址: htt ...

  7. 修改VISUAL STUDIO EXPRESS 2012新建C++文件编码

    本站文章除注明转载外,均为本站原创或者翻译. 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商: 本站部分原创和翻译文章提供markdown格式源码,欢迎使 ...

  8. 关于如何在Visual Studio上仿真调试安卓的U3D应用

    正巧最近需要开发一个安卓手机上的Unity3D游戏功能,想着既然要开发么,当然需要调试.本来的话一些基础功能是不需要使用仿真模拟器,直接在U3D的开发编辑器上就能调试,不过有一些安卓上才能执行,比如 ...

  9. [译]如何在visual studio中调试Javascript

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

随机推荐

  1. [hdu4667]Building Fence 计算几何 瞎瘠薄搞

    大致题意: 给出n个圆和m个三角形,求最小的的,能将所有图形覆盖的图形的周长. 正解为求所有三角形顶点与圆的切点以及圆和圆的切点构造凸包,再求路径. 因为要求结果误差<=1e-3 所以 我们可以 ...

  2. Python函数系列-一个简单的生成器的例子

    def consumer(): while True: x = yield print('处理了数据:',x) def producer(): pass c = consumer() #构建一个生成器 ...

  3. Python并发编程-多进程socketserver简易版

    普通版的socketserver #server.py import socket sk = socket.socket() sk.bind(('127.0.0.1',8080))#建立连接 sk.l ...

  4. Python类总结-继承-子类和父类,新式类和经典类

    子类和父类 class Father(object): #子类在使用super调用父类时,Father后面要加object --新式类 def __init__(self): self.Fname = ...

  5. js中箭头函数和普通函数this的区别

    最近在学习angularJs的时候由于里面涉及到了箭头函数,箭头函数除了声明上有点区别以外,和普通函数最主要的区别还是在this的问题上. Js中函数中嵌套的函数this不会 “继承”.比如说以下代码 ...

  6. eclipse的一些部署

    1. Eclipse导入一个项目Package Exporer-------右键------import------General------Existing Project into Workspa ...

  7. centos7 更改时区

    Linux 系统(我特指发行版, 没说内核) 下大部分软件的风格就是不会仔细去考虑向后 的兼容性, 比如你上个版本能用这种程序配置, 没准到了下一个版本, 该程序已经不见了. 比如 sysvinit ...

  8. Hibernate 基于外键的双向一对一关联映射

    之前简单介绍了基于外键的单项一对一的关联映射关系,本文简单介绍基于外键的双向一对一的关联映射. 1.设计表结构 表结构对于双向一对一来说没有多少改变,只是双向都可以获取到对方. 2.创建Person对 ...

  9. 【BZOJ 2039】 2039: [2009国家集训队]employ人员雇佣 (最小割)

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1511  Solved: 728 Descri ...

  10. GeoIP的使用

    GeoIP介绍: 什么是GepIP ? 所谓GeoIP,就是通过来访者的IP, 定位他的经纬度,国家/地区,省市,甚至街道等位置信息.这里面的技术不算难题,关键在于有个精准 的数据库.有了准确的数据源 ...