xgboost安装在visual studio的c++环境下或者eclipse的java环境下

最近搞毕设要找个机器学习的库来用跑多分类问题,之前师兄推荐xgboost这个库,于是我这几天一直在尝试这个库。然后发现一个比较蛋疼的问题是xgboost比较缺乏在windows下C++环境开发的文档,本来很简单的一个第三方库导致我花了很长的时间去摸索。现在我把具体步骤写出来,节约大家时间。

第1步、首先去:https://github.com/dmlc/xgboost下载一份源码或者git clone一份源码。

第2步、我本地环境是win7+VS2012,别的VS版本应该是一样的,这里进入xgboost-master/windows目录打开xgboost.sln解决方案,这里我们使用C++来写xgboost所以有用的只有rabit和xgboost两个项目,下面的xgboost_wrapper和xgboost4j项目不用管。

第3步、解决方案默认是X64位的,这里我自己项目是32位的,所以我改成了W32的。然后Debug版本和Release版本都编译成功了。它在xgboost-master/windows/Debug(或者Release)下生成了rabit.lib(没有对应的dll)以及xgboost.exe,没有别的了,是不是觉得很简单?

但是问题是不知道怎么用啊,ok,去看xgboost-master/demo里面的例子吧,然后发现里面不是python就是R语言的例子。在这里我又忍不住地图炮python(或者说脚本语言)了,这里我们不说性能啥的了,脚本语言缺乏类型真的很难读懂也不好debug,而且python在语言、库和平台的兼容性做得很差,总之这里就看一下几个例子。

发现xgboost-master/java里面有java的例子,里面的例子倒是可以读懂,于是就去跑java环境下的xgboost呗(对java环境不感兴趣的跳过这一步)。xgboost对java的绑定是xgboost4j这个项目,也就是上面第2步里面打开sln解决方案里面有这个项目,但是第2步却没有办法成功打开这个项目。啥原因呢?打开xgboost-master/windows/xgboost.sln里面发现它把xgboost4j这个项目的path写错了(估计是老的配置它没来得及测试,毕竟是master嘛,我提了这个issue估计很快就没这个问题了吧),这里在sln里面把path修改正确,然后就可以打开xgboost4j了,然后编译就可以生成xgboost4j.dll了(如果vs告诉你Visual Studio 2010 (Platform Toolset = ‘v100’)之类的,这个项目本来是vs2010生成的,这里我用的VS2012,所以我只需要在项目——》属性——》配置属性——》常规——》平台工具集里修改成Visual Studio 2012 (v110)就可以了,注意要X64版本的Release哦),然后在xgboost-master/java目录下点create_wrap.bat,它就复制了一下那个dll,然后环境就OK了。xgboost-master/java下xgboost4j(xgboost的java绑定)和xgboost4j-demo(java的例子)里面的是maven的,现在打开eclipse里面用maven打开其中一个项目(另一个自动打开了),然后在xgboost4j-demo里有7、8个demo,用eclipse的debug一步一步调试就可以比较清楚的摸清xgboost怎么跑的了。

接下来继续回到C++环境,官方repo里面也讲了怎么调参数,但是问题还是缺乏C++的demo来,没办法那就只有自己摸索了。摸索了很久之后就来说结论吧,首先在xgboost-master/windows/xgboost.sln这个项目里,xgboost项目就生成了一个命令行应用xgboost.exe,而他唯一的依赖就是rabit项目(2个项目都没有生成任何dll,也就是说想要在C++项目里集成xgboost库很简单,除了包含rabit和xgboost的头文件之外,只需要像xgboost这个命令行项目一样把dmlc_simple.cpp, gbm.cpp, io.cpp, updater.cpp包含进来就ok了)。那么来调试xgboost这个命令行项目,在xgboost_main.cpp可以看到main函数入口,打上断点之后Debug发现说找不到xgboost.exe,这是因为工作目录和生成xgboost.exe目录不一致导致了,在xgboost的属性——》配置属性——》调试——》工作目录里改成$(SolutionDir)$(Configuration)\就OK了。然后Debug触发断点就可以慢慢调试了,经过慢慢摸索终于搞清楚了怎么回事。首先它对参数的需要是你传给它一个配置文件,它去配置文件里面读。这里我用一个objective=multi:softmax的多分类问题来举个例子,首先在xgboost-master/windows/Debug目录下建立一个param.txt,里面写上此次训练的所有参数,为了用VS的单步调试的同时加上cmd参数需要在xgboost项目属性——》配置属性——》调试——》命令参数那里填上param.txt就可以开始调试了。参数具体看https://github.com/dmlc/xgboost/blob/master/doc/parameter.md,我这里举个param.txt的例子:

objective=multi:softmax eta=0.1 max_depth=6 silent=0 nthread=4 num_class=7 num_round=4 data=train_new.txt test:data=test_new.txt task=train

这里大data和test:data就是拿来训练和测试的数据,这个数据格式是有讲究的,我只试过libSVM格式的(经过调试发现*.txt的数据会用libSVM的parser来读数据),这个格式具体请看:http://stats.stackexchange.com/questions/61328/libsvm-data-format,那么在xgboost-master/demo/multiclass_classification下发现它去下载这个数据集:https://archive.ics.uci.edu/ml/machine-learning-databases/dermatology/dermatology.data,于是我也用这个数据集,这个数据集不是libSVM的,它python版本demo程序自己做过处理来训练的,这里我用c++就只有写了一个脚本语言把这个数据集转化成了libSVM的格式,类似这样:

3 1:2 2:1 3:2 4:3 5:1 6:3 7:0 8:3 9:0 10:0 11:0 12:1 13:0 14:0 15:0 16:1 17:2 18:0 19:2 20:0 21:0 22:0 23:0 24:0 25:2 26:0 27:2 28:3 29:2 30:0 31:0 32:2 33:3 34:26
1 1:2 2:2 3:2 4:0 5:0 6:0 7:0 8:0 9:3 10:2 11:0 12:0 13:0 14:3 15:0 16:0 17:2 18:0 19:3 20:2 21:2 22:2 23:2 24:0 25:0 26:3 27:0 28:0 29:0 30:0 31:0 32:3 33:0 34:40
3 1:2 2:3 3:2 4:2 5:2 6:2 7:0 8:2 9:0 10:0 11:0 12:1 13:0 14:0 15:0 16:1 17:2 18:0 19:0 20:0 21:0 22:0 23:0 24:0 25:2 26:2 27:3 28:2 29:3 30:0 31:0 32:2 33:3 34:45
2 1:2 2:3 3:2 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:2 14:1 15:0 16:2 17:2 18:0 19:2 20:0 21:0 22:0 23:1 24:0 25:0 26:0 27:0 28:2 29:0 30:0 31:0 32:1 33:0 34:41
5 1:2 2:1 3:0 4:2 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:0 15:3 16:1 17:3 18:0 19:0 20:0 21:2 22:0 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:2 33:0 34:18
3 1:2 2:2 3:3 4:3 5:3 6:3 7:0 8:2 9:0 10:0 11:0 12:2 13:0 14:0 15:0 16:2 17:3 18:0 19:0 20:0 21:0 22:0 23:0 24:0 25:0 26:2 27:2 28:3 29:2 30:0 31:0 32:3 33:3 34:57

格式转化随便写个脚本就ok了,我用的是PHP,如果你懒得自己写又恰好有php环境的话可以直接用这个:

    	$fn="dermatology.data";
    	$str=file_get_contents($fn);
    	$arr=explode("\n", $str);
    	$str_new='';
    	for($i=0;$i<count($arr);$i++)
    	{
    		$arrTmp=explode(",",$arr[$i]);
    		$arrTmpNew=[];
    		$arrTmpNew[]=array_pop($arrTmp);
    		for($j=0;$j<count($arrTmp);$j++)
    		{
    			$arrTmpNew[]=strval($j+1).':'.$arrTmp[$j];
    		}
    		$str_new .= implode(' ', $arrTmpNew)."\r\n";
    	}
    	$fn_new="train_new.txt";
    	file_put_contents($fn_new, $str_new);

我们把这个libSVM数据train_new.txt集分出1份test_new.txt,这样就得到了数据集了。然后Debug调试就可以看到这个训练任务跑了4趟之后训练完毕,训练模型保存成0004.model了。然后把task改成pred就可以查看用test_new.txt来分类的结果在pred.txt里了,具体的方法或者错误Debug单步调试就一目了然了,感谢Visual Studio世界上最好的IDE。

那么现在另外一个问题就是怎么在自己的C++项目里面集成xgboost呢?现在拿一个简单的命令行c++程序来说明:把xgboost-master下的src(xgboost)和subtree(里面是rabit源码)copy到项目的源码目录下,src(xgboost)里面用相对路径引用了rabit,所以你可能需要在src里xgboost的头文件修改相对路径来找到rabit的头文件。然后在你控制台项目里添加dmlc_simple.cpp, gbm.cpp, io.cpp和updater.cpp这4个在src(xgboost)里面的cpp文件进来,然后因为VS的stdafx属性可能告诉你给要给那4个cpp文件加上stafx头文件,这里去项目属性里忽略stdafx头文件吧。然后在项目属性的链接器里加上rabit.lib(注意debug和Release版本是分开的),OK,终于可以在自己的C++项目里使用xgboost了。

以上

xgboost安装在visual studio的c++环境下或者eclipse的java环境下》有4个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注