SHOGUN为Python和Octave支持的模块化接口提供了一个直观和容易的使用shogun功能的方法。与 静态接口( staticinterfaces)相比,模块化接口更加灵活并具有良好的扩展性。
如果这是第一次使用shogun,这就是你首先要看的地方!
在本指南中,我们将演示如使用shogun创建一个基于高斯核函数的SVM分类器。但是, 首先需要启动python或者octave并加载shogun。
要加载shogun的模块,在octave下输入
init_shogun
在python下需要指定我们要使用的函数。 在这个例子中,我们需要feature和label表示数据,一个分类器,一个用于比较feature相似性的核函数 及一些评价方法。
from shogun.Features import * from shogun.Kernel import * from shogun.Classifier import * from shogun.Evaluation import *
(注意这里模块shogun.Features包含类Labels)。
如果想知道shogun中类的一些基本信息或者某一个类的文档,使用上面的Classes标签查看类 列表。所有类都有良好的文档(如果你觉得文档不好,请告诉我们)。注意所有在类列表中类 都有C作前缀,在python和octave模块化接口中使用时需要去掉C前缀。
另外,在python下通过help命令也可以得到相同的文档,你只需要输入
help(<classname>)
例如
from shogun.Kernel import GaussianKernel help(GaussianKernel)
或者
import shogun.Kernel help(shogun.Kernel)
首先,我们先来产生一个小的数据集。在python中,我们需要加载numpy。我们产生 一个基于高斯分布的训练数据集及测试数据集,每个数据集可以分为两块,两块的数据中心之间有一定的距离。 数据保存在一个矩阵中,每一列代表一个个体。另外,我们还需要一个向量保存label(每项的值为1或-1) ,分别说明属于哪一类。
from numpy import * from numpy.random import randn dist=0.5 traindata_real = concatenate((randn(2,100)-dist, randn(2,100)+dist), axis=1) testdata_real = concatenate((randn(2,100)-dist, randn(2,100)+dist), axis=1) train_labels = concatenate((-ones(100), ones(100))) test_labels = concatenate((-ones(100), ones(100)))
在octave下,可以这样
dist=0.5 traindata_real = [randn(2,100)-dist, randn(2,100)+dist]; testdata_real = [randn(2,100)-dist, randn(2,100)+dist]; train_labels = [-ones(1,100), ones(1,100)]; test_labels = [-ones(1,100), ones(1,100)];
本指南的后面部分在python和octave都是一样的(相同的语法,略为不同的是,在octave分号是必需的)。
要在shogun中处理上面的数据集,我们需要新建一个feature对象,这里使用RealFeatures (用于实数矩阵,请参考shogun::CSimpleFeatures)
feats_train = RealFeatures(traindata_real); feats_test = RealFeatures(testdata_real);
使用上面的feature对象我们可以新建一个kernel对象。基于上面的feature,我们创建了 一个高斯kernel,另外还有一个width值(更多信息参考shogun::CGaussianKernel)。
width = 2; kernel = GaussianKernel(feats_train, feats_train, width);
and can now compute the kernel matrix
km = kernel.get_kernel_matrix();
要训练一个SVM,需要为样本提供label,一个值为1或-1的向量,像上面的train_labels变量。基于train_labels 可创建一个label对象。
labels = Labels(train_labels); labels_test = Labels(test_labels);
接下来只需要做的是,指定一个代价参数C(用于评价泛化效果),然后创建一个SVM,调用SVM的train方法来训练。 很简单,是吧?
C = 1.0; svm = LibSVM(C, kernel, labels); svm.train();
想要将SVM应用到测试数据,我们只需要传递一个feature对象给SVM的classify方法,该方法返回一个Label 对象(注意我们还可以在初始化kernel对象时指定训练数据集和测试数据集,然后调用无参数的classify方法, 在其它的一些例子中你可以看到这种情况)。 如果我们想在python/octave分析这些输出,可以通过get_labels()方法获得输出的向量形式。
output = svm.classify(feats_test); output_vector = output.get_labels();
根据这些输出及测试集的label,我们可评价SVM的预测性能。首先需要创建一个PerformanceMeasures对象, 它包含多种衡量性能的方法,如accuracy (acc),ROC曲线,F-score等等:
pm = PerformanceMeasures(labels_test, output); acc = pm.get_accuracy(); roc = pm.get_auROC(); fms = pm.get_fmeasure();
这就是本指南要介绍的例子。要想知道更多高级使用可以看更多下面目录的例子
作为一个完整的例子,下面给出两种接口的代码 For octave:
init_shogun num=1000; dist=1; width=2.1; C=1; traindata_real=[randn(2,num)-dist, randn(2,num)+dist]; testdata_real=[randn(2,num)-dist, randn(2,num)+dist]; trainlab=[-ones(1,num), ones(1,num)]; testlab=[-ones(1,num), ones(1,num)]; feats_train=RealFeatures(traindata_real); feats_test=RealFeatures(testdata_real); feats_test.copy_feature_matrix(testdata_real); kernel=GaussianKernel(feats_train, feats_train, width); labels=Labels(trainlab); svm=LibSVM(C, kernel, labels); svm.parallel.set_num_threads(8); svm.train(); kernel.init(feats_train, feats_test); out=svm.classify().get_labels(); testerr=mean(sign(out)~=testlab)
For python:
from numpy import * from numpy.random import randn from shogun.Features import * from shogun.Classifier import * from shogun.Kernel import * num=1000 dist=1 width=2.1 C=1 traindata_real=concatenate((randn(2,num)-dist, randn(2,num)+dist), axis=1) testdata_real=concatenate((randn(2,num)-dist, randn(2,num)+dist), axis=1); trainlab=concatenate((-ones(num), ones(num))); testlab=concatenate((-ones(num), ones(num))); feats_train=RealFeatures(traindata_real); feats_test=RealFeatures(testdata_real); kernel=GaussianKernel(feats_train, feats_train, width); labels=Labels(trainlab); svm=LibSVM(C, kernel, labels); svm.train(); kernel.init(feats_train, feats_test); out=svm.classify().get_labels(); testerr=mean(sign(out)!=testlab) print testerr