| 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://hi.baidu.com/xuqingyang/blog/item/ea593c3b4a14fbee14cecb0c.html
|