一、下载libsvm
LIBSVM是台湾大学林智仁(Lin Chih-Jen)教授等开发设计的一个简单、易于使用和快速有效的SVM模式识别与回归的软件包,在http://www.csie.ntu.edu.tw/~cjlin/libsvm/可以下载,目前版本是libsvm-3.20,推荐把下载的libsvm-3.20.zip解压之后的libsvm-3.20文件夹放置在D:\MATLAB\R2013a\toolbox中(为方便区分我直接把libsvm-3.20文件夹放到D:\MATLAB下面),然后将其添加到matlab的搜索路径中:matlab里Set Path然后Add with Subfolders,选择libsvm-3.20文件夹,Save,Close。
二、编译libsvm
虽然libsvm-3.20\matlab中的README说libsvm-3.20\windows里有编译好的文件可以直接用,但是由于各人的matlab、VS版本不一样,有些文件在新版本中没有了,或者放在另一个文件夹下了,会导致有些文件找不到,总之,最好是自己编译一下吧。编译的目的呢,就是把libsvm-3.20\matlab中的svmtrain.c这样的C++源文件编译成svmtrain.mexw64这样的matlab文件,才能在matlab的命令行里直接调用。
编译步骤:
1、把matlab切换到libsvm-3.20\matlab目录下,以我的为例,在matlab命令行输入以下命令
2、如果你的编译器配置好了,直接输入以下命令CD D:\MATLAB\libsvm-3.20\matlab
如果不能编译,那么你需要配置一下编译器,在matlab命令行输入以下命令make
mex -setup
他会问你是否使用matlab自带的Lcc-win32C编译器,Would you like mex to locate installed compilers [y]/n?
由于libsvm原始版本是C++实现的,我们选择n使用C++编译器来编译这些源文件
然后会列出许多编译器:
Would you like mex to locate installed compilers [y]/n? n Select a compiler: [1] Intel C++ 13.0 (with Microsoft Software Development Kit (SDK) linker) [2] Intel C++ 13.0 (with Microsoft Visual C++ 2010 linker) [3] Intel C++ 13.0 (with Microsoft Visual C++ 2012 linker) [4] Intel C++ 12.0 (with Microsoft Software Development Kit (SDK) linker) [5] Intel C++ 12.0 (with Microsoft Visual C++ 2008 SP1 linker) [6] Intel C++ 12.0 (with Microsoft Visual C++ 2010 linker) [7] Intel C++ 11.1 (with Microsoft Visual C++ 2008 SP1 linker) [8] Intel Visual Fortran 13 (with Microsoft Software Development Kit (SDK) linker) [9] Intel Visual Fortran 13.0 (with Microsoft Visual C++ 2010 linker) [10] Intel Visual Fortran 13.0 (with Microsoft Visual C++ 2012 linker) [11] Intel Visual Fortran 12 (with Microsoft Software Development Kit (SDK) linker) [12] Intel Visual Fortran 12.0 (with Microsoft Visual C++ 2008 SP1 linker) [13] Intel Visual Fortran 12.0 (with Microsoft Visual C++ 2008 Shell linker) [14] Intel Visual Fortran 12.0 (with Microsoft Visual C++ 2010 linker) [15] Intel Visual Fortran 11.1 (with Microsoft Visual C++ 2008 SP1 linker) [16] Intel Visual Fortran 11.1 (with Microsoft Visual C++ 2008 Shell linker) [17] Microsoft Software Development Kit (SDK) 7.1 [18] Microsoft Visual C++ 2005 SP1 [19] Microsoft Visual C++ 2008 SP1 [20] Microsoft Visual C++ 2010 [21] Microsoft Visual C++ 2012 [0] None Compiler:
我装的是VS2013列表里没有显示,我先选择21
接下来让你确认编译器位置:
由于matlab还不支持VS2013,我的编译器应该是Microsoft Visual Studio 12.0,而且我的VS2013不是默认安装到C盘的(我装在了D:\Microsoft Visual Studio 12.0),所以接下来我要手动输入编译器路径,我先选择nWarning: The default location for Microsoft Visual C++ 2012 compiler is: "C:\Program Files (x86)\Microsoft Visual Studio 11.0" but either that directory does not exist or the configuration is invalid. Use C:\Program Files (x86)\Microsoft Visual Studio 11.0 anyway [y]/n?
在这行后面输入VS安装时候的路径,我的是D:\Microsoft Visual Studio 12.0故输入如下Use C:\Program Files (x86)\Microsoft Visual Studio 11.0 anyway [y]/n? n Please enter the location of your compiler: [C:\Program Files (x86)\Microsoft Visual Studio 11.0]
然后再次让你确认路径Use C:\Program Files (x86)\Microsoft Visual Studio 11.0 anyway [y]/n? n Please enter the location of your compiler: [C:\Program Files (x86)\Microsoft Visual Studio 11.0] D:\Microsoft Visual Studio 12.0
选择yPlease verify your choices: Compiler: Microsoft Visual C++ 2012 Location: D:\Microsoft Visual Studio 12.0 Are these correct [y]/n?
Are these correct [y]/n? y *************************************************************************** Warning: MEX-files generated using Microsoft Visual C++ 2012 require that Microsoft Visual Studio 2012 run-time libraries be available on the computer they are run on. If you plan to redistribute your MEX-files to other MATLAB users, be sure that they have the run-time libraries. *************************************************************************** Trying to update options file: C:\Users\张京林\AppData\Roaming\MathWorks\MATLAB\R2013a\mexopts.bat From template: D:\MATLAB\R2013a\bin\win64\mexopts\msvc110opts.bat Done . . . ************************************************************************** Warning: The MATLAB C and Fortran API has changed to support MATLAB variables with more than 2^32-1 elements. In the near future you will be required to update your code to utilize the new API. You can find more information about this at: http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html Building with the -largeArrayDims option enables the new API. ************************************************************************** >>
这样就设置好了编译器
由于前面说过的matlab2013a还不支持VS2013,在WIN8、VS2013下某些lib(比如gdi32.lib)不需要了,因此文件夹中没有这些文件,但是matlab还是会根据老版本VS的路径去找这些文件,所以会报错,说找不到某些lib文件,比如:
LINK : fatal error LNK1181: cannot open input file 'gdi32.lib'
网上找到的解决办法是mexopts.bat文件:
在C:\Users\张京林\AppData\Roaming\MathWorks\MATLAB\R2013a路径下找到mexopts.bat文件,右键编辑,找到如下行
把kernel32.lib user32.lib后面的gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib都删掉,如下set LINKFLAGS=/dll /export:%ENTRYPOINT% /LIBPATH:"%LIBLOC%" libmx.lib libmex.lib libmat.lib /MACHINE:X64 kernel32.lib user32.lib gdi32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /manifest /incremental:NO /implib:"%LIB_NAME%.x" /MAP:"%OUTDIR%%MEX_NAME%%MEX_EXT%.map"
set LINKFLAGS=/dll /export:%ENTRYPOINT% /LIBPATH:"%LIBLOC%" libmx.lib libmex.lib libmat.lib /MACHINE:X64 kernel32.lib user32.lib /nologo /manifest /incremental:NO /implib:"%LIB_NAME%.x" /MAP:"%OUTDIR%%MEX_NAME%%MEX_EXT%.map"
保存,关闭mexopts.bat文件
这个时候回到matlab,注意matlab的当前目录还是切换到D:\MATLAB\libsvm-3.20\matlab下,在matlab命令行输入编译命令:
make
这个时候编译就能成功了,在D:\MATLAB\libsvm-3.20\matlab目录下就会生成libsvmread.mexw64、libsvmwrite.mexw64、svmpredict.mexw64、svmtrain.mexw64等matlab文件
参考:matlab与vs2013 mex无法找到编译器问题
三、测试libsvm
在README里面有示例代码,可以用来验证libsvm是否正常工作。 假设matlab当前目录仍为D:\MATLAB\libsvm-3.20\matlab,运行如下代码即可得到SVM的测试结果,用来训练的数据在上一层目录的heart_scale文件里[label_vector, instance_matrix] = libsvmread('data.txt'); Libsvmread函数可以 读入训练数据data.txt,注意data.txt里的数据必须按照libsvm约定的格式来组织 。两个输出分别是标签labels 和样本集 instances,它们可以作为svmtrain 或者 svmpredict的输入。>> [heart_scale_label, heart_scale_inst] = libsvmread('../heart_scale'); >> model = svmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 0.07'); >> [predict_label, accuracy, dec_values] = svmpredict(heart_scale_label, heart_scale_inst, model); % test the training data
model = svmtrain(training_label_vector, training_instance_matrix [, 'libsvm_options']);
输入参数如下:
-training_label_vector:训练样本的标签,m*1向量。注意必须是double类型。
-training_instance_matrix:训练样本,m*n矩阵。每个样本为n维。它必须是稀疏的,而且必须是double类型。
-libsvm_options:字符串格式的训练选项,格式和LIBSVM 一样。
[predicted_label, accuracy, decision_values/prob_estimates] = svmpredict(testing_label_vector, testing_instance_matrix, model [, 'libsvm_options']);
输入参数如下:
-testing_label_vector:测试样本的标签,mx1向量。如果未知,那么就简单使用随机值。注意必须是double类型。
-testing_instance_matrix:训练样本,mxn矩阵。每个样本为n维。它必须是稀疏的,而且必须是double类型。
-model:前面训练得到的模型。
-libsvm_options:字符串格式的测试选项,格式和LIBSVM 一样。
输出参数如下:
-predicted_label:预测样本的标签向量。
-accuracy:一个向量,包含分类精度、均方误差、相关系数的平方(线性回归)
-decision_values/prob_estimates:用来评判分类置信度的值
libsvmwrite('data.txt', label_vector, instance_matrix)
libsvmwrite可以将参数以LIBSVM的格式写到文件中。instance_matrix必须是个稀疏矩阵。类型必须是double型。
以上示例代码运行结果如下:
实际应用中我们往往会有测试集和样本集,假设我有一个样本集TrainA.txt和一个测试集TestA.txt,数据格式都符合LIBSVM格式,我要进行测试得到精度的示例如下:optimization finished, #iter = 134 nu = 0.433785 obj = -101.855060, rho = 0.426412 nSV = 130, nBSV = 107 Total nSV = 130 Accuracy = 86.6667% (234/270) (classification) >>
结果如下:clc; clear all; %训练过程 [heart_scale_label, heart_scale_inst] = libsvmread('F:\work\SVMdata\TrainA.txt'); model = svmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 0.07'); %测试过程 [p_heart_scale_label, p_heart_scale_inst] = libsvmread('F:\work\SVMdata\TestA.txt'); [predict_label, accuracy, dec_values] = svmpredict(p_heart_scale_label, p_heart_scale_inst, model);
* optimization finished, #iter = 595 nu = 0.442940 obj = -533.171471, rho = -0.772225 nSV = 561, nBSV = 540 Total nSV = 561 Accuracy = 50% (2/4) (classification) >>