String Kernel目前最快的算法是基于Suffix Tree或Suffix Array的方法。目前网上能够找到的源码实现除了SVMSequel(现在源码好象无法下载得到,而且是基于OCaml语言)外,能够找到的并且可用的非常少。SASK(
http://users.rsise.anu.edu.au/~chteo/SASK.html)
是最新的基于Suffix Array的实现,它基于#此前在首页部分显示#Linux下的C++实现,但仅提供String Kernel的计算功能,如何与SVM结合起来直接使用并没有给出说明。自己在和它的作者进行了第14次通信后终于弄懂了利用它进行SVM分类的详尽过程,现在写在这里留给将来备忘:
首先下载http://users.rsise.anu.edu.au/~chteo/SASK.html上的两个压缩包sask-1.1( http://users.rsise.anu.edu.au/~chteo/src/sask-1.1.tgz )和SASK experiments( http://users.rsise.anu.edu.au/~chteo/src/sask_icml06_expt.tgz )。然后分别将它们解压缩并且执行make命令。假设解压缩后的根目录分别为sask-1.1和sask_icml06_expt。
再到libsvm网站上下载最新的libsvm,要求是2.84版本之后的,这样它具有利用Precomputed Kernel Matrix的输入数据格式的功能。
运行sask-1.1/src目录下面生成的line-libsvmkm可执行文件,将提供的文本训练集转化成libsvm可以接受的Kernel Matrix格式。
将生成的基于Kernel Matrix格式的libsvm训练文件交给libsvm里的svm-train可执行文件,得到对应的svm-model文件。这个文件里有rho值和各个Support Vector的序号和它们的alpha值。
利用这些Support Vector及对应的alpha值构建一个与训练集对应的StringKernel对象,具体代码参见sask_icml06_expt/Code里面的 ltp-sa-sl.cpp文件,大致过程如下:
将各个Support Vector每个后面加一个'n'的SENTINAL字符后串接一起,形成一个Master String,假设这个字符串保存在data这个std::string里,然后:
//swf和swfParam是调节weight的参数
StringKernel sk(data.size(), (SYMBOL*)data.c_str(), swf, swfParam);
//alphas保存各个Support Vector的alpha值的数组,data_len保存各个Support Vector的长度, n是Support Vector的数目
sk.Set_Lvs(&alphas[0], &data_len[0], n);
sk.PrecomputeVal();
至此,一个分类器已经创建成功,如果对一个字符串pattern进行分类,通过如下语句计算它对应的svm值(保存在kval这个变量里),减去rho后的符号即为它的label:
sk.Compute_K((SYMBOL*)pattern.c_str(), pattern.length(), kval);
使用起来其实真的很简单。如果训练数目巨大,还可以考虑用SVM-light取代libsvm以得到Support Vector及它们的alpha值。
首先下载http://users.rsise.anu.edu.au/~chteo/SASK.html上的两个压缩包sask-1.1( http://users.rsise.anu.edu.au/~chteo/src/sask-1.1.tgz )和SASK experiments( http://users.rsise.anu.edu.au/~chteo/src/sask_icml06_expt.tgz )。然后分别将它们解压缩并且执行make命令。假设解压缩后的根目录分别为sask-1.1和sask_icml06_expt。
再到libsvm网站上下载最新的libsvm,要求是2.84版本之后的,这样它具有利用Precomputed Kernel Matrix的输入数据格式的功能。
运行sask-1.1/src目录下面生成的line-libsvmkm可执行文件,将提供的文本训练集转化成libsvm可以接受的Kernel Matrix格式。
将生成的基于Kernel Matrix格式的libsvm训练文件交给libsvm里的svm-train可执行文件,得到对应的svm-model文件。这个文件里有rho值和各个Support Vector的序号和它们的alpha值。
利用这些Support Vector及对应的alpha值构建一个与训练集对应的StringKernel对象,具体代码参见sask_icml06_expt/Code里面的 ltp-sa-sl.cpp文件,大致过程如下:
将各个Support Vector每个后面加一个'n'的SENTINAL字符后串接一起,形成一个Master String,假设这个字符串保存在data这个std::string里,然后:
//swf和swfParam是调节weight的参数
StringKernel sk(data.size(), (SYMBOL*)data.c_str(), swf, swfParam);
//alphas保存各个Support Vector的alpha值的数组,data_len保存各个Support Vector的长度, n是Support Vector的数目
sk.Set_Lvs(&alphas[0], &data_len[0], n);
sk.PrecomputeVal();
至此,一个分类器已经创建成功,如果对一个字符串pattern进行分类,通过如下语句计算它对应的svm值(保存在kval这个变量里),减去rho后的符号即为它的label:
sk.Compute_K((SYMBOL*)pattern.c_str(), pattern.length(), kval);
使用起来其实真的很简单。如果训练数目巨大,还可以考虑用SVM-light取代libsvm以得到Support Vector及它们的alpha值。