├── phpdocs
├── svn
├── entities.svmmodel.xml
├── entities.svm.xml
├── configure.xml
├── book.xml
├── svm
│ ├── construct.xml
│ ├── getoptions.xml
│ ├── setoptions.xml
│ ├── train.xml
│ └── crossvalidate.xml
├── setup.xml
├── svmmodel.xml
├── versions.xml
├── svmmodel
│ ├── save.xml
│ ├── load.xml
│ ├── construct.xml
│ └── predict.xml
├── svmexception.xml
├── examples.xml
└── svm.xml
├── CREDITS
├── tests
├── 008_cross_validate.phpt
├── 009_badfile.phpt
├── 011_inttodouble.phpt
├── 001_train.phpt
├── 006_train_array.phpt
├── 004_setoptions.phpt
├── 003_getparms.phpt
├── 002_predict.phpt
├── 010_weights.phpt
├── 005_regression.phpt
├── 007_kernels.phpt
└── australian.scale
├── LICENSE
├── config.m4
├── package.xml
├── php_svm.h
├── README
└── svm.c
/phpdocs/svn:
--------------------------------------------------------------------------------
1 | svn
--------------------------------------------------------------------------------
/CREDITS:
--------------------------------------------------------------------------------
1 | svm
2 | Ian Barber, Mikko Koppanen
--------------------------------------------------------------------------------
/phpdocs/entities.svmmodel.xml:
--------------------------------------------------------------------------------
1 | &reference.svm.svmmodel.construct;
2 | &reference.svm.svmmodel.load;
3 | &reference.svm.svmmodel.predict;
4 | &reference.svm.svmmodel.save;
5 |
--------------------------------------------------------------------------------
/phpdocs/entities.svm.xml:
--------------------------------------------------------------------------------
1 | &reference.svm.svm.construct;
2 | &reference.svm.svm.crossvalidate;
3 | &reference.svm.svm.getoptions;
4 | &reference.svm.svm.setoptions;
5 | &reference.svm.svm.train;
6 |
--------------------------------------------------------------------------------
/tests/008_cross_validate.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test 5 fold cross validation
3 | --SKIPIF--
4 |
7 | --FILE--
8 | crossvalidate(dirname(__FILE__) . '/australian.scale', 5);
11 | if($result > 0) {
12 | echo "ok";
13 | }
14 | ?>
15 | --EXPECT--
16 | ok
17 |
--------------------------------------------------------------------------------
/tests/009_badfile.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test handling a bad filename
3 | --SKIPIF--
4 |
7 | --FILE--
8 | train('bad.file'); // shutup op to stop the warning which has current path in it
12 | } catch(SVMException $e) {
13 | echo "got exception";
14 | }
15 | ?>
16 | --EXPECT--
17 | got exception
18 |
--------------------------------------------------------------------------------
/tests/011_inttodouble.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Train from an array, testing conversion of ints to doubles
3 | --SKIPIF--
4 |
7 | --FILE--
8 | train(array(array(1, 1 => 1), array(-1, 1 => -1)));
11 | echo $result->predict(array(0, 1 => -1)), PHP_EOL;
12 | echo $result->predict(array(0, 1 => 1));
13 |
14 |
15 | ?>
16 | --EXPECTF--
17 | -1
18 | 1
--------------------------------------------------------------------------------
/tests/001_train.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Load training data from a file.
3 | --SKIPIF--
4 |
7 | --FILE--
8 | train(dirname(__FILE__) . '/australian.scale');
11 |
12 | try {
13 | $result->save(dirname(__FILE__) . '/australian.model');
14 | echo "ok";
15 | } catch (SvmException $e) {
16 | echo $e->getMessage();
17 | }
18 |
19 | ?>
20 | --EXPECT--
21 | ok
22 |
--------------------------------------------------------------------------------
/tests/006_train_array.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Train from an array
3 | --SKIPIF--
4 |
7 | --FILE--
8 | train(array(array(1, -13 => 1.33)));
11 | var_dump($result);
12 |
13 | try {
14 | $svm->train(array(array(1)));
15 |
16 | } catch (SvmException $e) {
17 | echo "got exception";
18 | }
19 |
20 | ?>
21 | --EXPECTF--
22 | object(svmmodel)#%d (%d) {
23 | }
24 | got exception
25 |
--------------------------------------------------------------------------------
/tests/004_setoptions.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test setOptions
3 | --SKIPIF--
4 |
7 | --FILE--
8 | SVM::NU_SVR, Svm::OPT_COEF_ZERO => 1.2);
12 |
13 | $svm->setOptions($options);
14 |
15 | var_dump($options[Svm::OPT_TYPE] == SVM::NU_SVR);
16 |
17 | echo "ok\n";
18 |
19 | $options = array(Svm::OPT_TYPE => 31337);
20 | try {
21 | $svm->setOptions($options);
22 | } catch (SVMException $e) {
23 | echo "got exception";
24 | }
25 | ?>
26 | --EXPECT--
27 | bool(true)
28 | ok
29 | got exception
--------------------------------------------------------------------------------
/tests/003_getparms.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test retrieving the SVM training parameters.
3 | --SKIPIF--
4 |
7 | --FILE--
8 | getOptions();
11 | if(count($params) > 2) {
12 | echo "ok 1\n";
13 | } else {
14 | echo "retrieving params failed";
15 | }
16 |
17 | if(isset($params[SVM::OPT_CACHE_SIZE])) {
18 | echo "ok 2\n";
19 | } else {
20 | echo "missing cache size";
21 | }
22 |
23 | if($params[SVM::OPT_CACHE_SIZE] == 100) {
24 | echo "ok 3\n";
25 | } else {
26 | echo "invalid cache size";
27 | }
28 | ?>
29 | --EXPECT--
30 | ok 1
31 | ok 2
32 | ok 3
33 |
34 |
--------------------------------------------------------------------------------
/tests/002_predict.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Make a prediction based on the model
3 | --SKIPIF--
4 |
7 | --FILE--
8 | load(dirname(__FILE__) . '/australian.model');
11 |
12 | if($result) {
13 | $data = array(
14 | "1" => 1,
15 | 2 => -0.731729,
16 | 3 => -0.886786,
17 | 4 => -1,
18 | 5 => 0.230769,
19 | "6" => -0.25,
20 | 7 => -0.783509,
21 | 8 => 1,
22 | 9 => 1,
23 | 10 => "-0.820896",
24 | 11 => -1,
25 | 13 => -0.92,
26 | "14" => "-1"
27 | );
28 | $result = $svm->predict($data);
29 | if($result > 0) {
30 | echo "ok";
31 | } else {
32 | echo "predict failed: $result";
33 | }
34 | } else {
35 | echo "loading failed";
36 | }
37 | ?>
38 | --EXPECT--
39 | ok
40 |
--------------------------------------------------------------------------------
/phpdocs/configure.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.install;
6 |
7 |
8 | &pecl.info;
9 | &url.pecl.package;svm
10 |
11 |
12 |
13 | The latest PECL/svm Win32 DLL is available here:
14 | php_svm.dll
15 |
16 |
17 |
18 |
19 |
20 |
40 |
--------------------------------------------------------------------------------
/tests/010_weights.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test training with some unbalanced weighting
3 | --SKIPIF--
4 |
7 | --FILE--
8 | setOptions(array(SVM::OPT_TYPE => SVM::NU_SVC));
11 | try {
12 | $model = $svm->train(dirname(__FILE__) . '/australian.scale', array(1 => 1, -1 => 0.5));
13 | } catch(SVMException $e) {
14 | echo "got exception\n";
15 | }
16 |
17 | $svm->setOptions(array(SVM::OPT_TYPE => SVM::C_SVC));
18 | $model = $svm->train(dirname(__FILE__) . '/australian.scale', array(1 => 1, -1 => 0.5));
19 |
20 | try {
21 | $data = array(
22 | "1" => 1,
23 | 2 => -0.731729,
24 | 3 => -0.886786,
25 | 4 => -1,
26 | 5 => 0.230769,
27 | "6" => -0.25,
28 | 7 => -0.783509,
29 | 8 => 1,
30 | 9 => 1,
31 | 10 => "-0.820896",
32 | 11 => -1,
33 | 13 => -0.92,
34 | "14" => "-1"
35 | );
36 | $result = $model->predict($data);
37 | if($result > 0) {
38 | echo "ok";
39 | }
40 | } catch (SvmException $e) {
41 | echo $e->getMessage();
42 | }
43 |
44 | ?>
45 | --EXPECT--
46 | got exception
47 | ok
--------------------------------------------------------------------------------
/phpdocs/book.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SVM
6 | SVM
7 |
8 |
9 | &reftitle.intro;
10 |
11 | LibSVM is an efficient solver for SVM classification and regression problems. The svm extension wraps this in a PHP interface for easy use in PHP scripts.
12 |
13 |
14 |
15 | &reference.svm.setup;
16 | &reference.svm.examples;
17 |
18 | &reference.svm.svm;
19 | &reference.svm.svmmodel;
20 |
21 |
22 |
23 |
43 |
--------------------------------------------------------------------------------
/tests/005_regression.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Load a larger amount of training data from a file and test regressions
3 | --SKIPIF--
4 |
7 | --FILE--
8 | array(1 => -1 ,2 => 0.418919 ,3 => 0.411765 ,4 => -0.637168 ,5 => -0.168408 ,6 => -0.294553 ,7 => -0.24424 ,8 => -0.389138 ),
11 | "10" => array(2 => 0.486486 ,3 => 0.445378 ,4 => -0.734513 ,5 => -0.226138 ,6 => -0.287155 ,7 => -0.314022 ,8 => -0.413054 ),
12 | "12" => array(1 => -1 ,2 => 0.716216 ,3 => 0.680672 ,4 => -0.654867 ,5 => 0.378785 ,6 => 0.270343 ,7 => -0.00987492 ,8 => -0.0164425),
13 | );
14 |
15 | sleep(1);
16 | $svm = new svm();
17 |
18 | $svm->setOptions(array(
19 | SVM::OPT_TYPE => SVM::C_SVC,
20 | SVM::OPT_KERNEL_TYPE => SVM::KERNEL_LINEAR,
21 | SVM::OPT_P => 0.1, // epsilon 0.1
22 | ));
23 | $model = $svm->train(dirname(__FILE__) . '/abalone.scale');
24 | if($model) {
25 | echo "ok train\n";
26 | foreach($data as $class => $d) {
27 | $result = $model->predict($d);
28 | if($result > 0) {
29 | echo "ok\n";
30 | } else {
31 | echo "regression failed: " . $result . "\n";
32 | }
33 | }
34 | } else {
35 | echo "training failed";
36 | }
37 | ?>
38 | --EXPECT--
39 | ok train
40 | ok
41 | ok
42 | ok
43 |
--------------------------------------------------------------------------------
/phpdocs/svm/construct.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVM::__construct
7 | Construct a new SVM object
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | SVM::__construct
14 |
15 |
16 |
17 | Constructs a new SVM object ready to accept training data.
18 |
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 | &no.function.parameters;
25 |
26 |
27 |
28 | &reftitle.returnvalues;
29 |
30 | Thows SVMException if the libsvm library could not be loaded
31 |
32 |
33 |
34 |
35 |
36 |
37 |
57 |
--------------------------------------------------------------------------------
/tests/007_kernels.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test for various kernels
3 | --SKIPIF--
4 |
7 | --FILE--
8 | 1,
11 | 2 => -0.731729,
12 | 3 => -0.886786,
13 | 4 => -1,
14 | 5 => 0.230769,
15 | "6" => -0.25,
16 | 7 => -0.783509,
17 | 8 => 1,
18 | 9 => 1,
19 | 10 => "-0.820896",
20 | 11 => -1,
21 | 13 => -0.92,
22 | "14" => "-1"
23 | );
24 |
25 | $kernels = array(
26 | array(
27 | SVM::OPT_TYPE => SVM::C_SVC,
28 | SVM::OPT_KERNEL_TYPE => SVM::KERNEL_POLY,
29 | ),
30 | array(
31 | SVM::OPT_TYPE => SVM::ONE_CLASS,
32 | SVM::OPT_KERNEL_TYPE => SVM::KERNEL_RBF,
33 | ),
34 | array(
35 | SVM::OPT_TYPE => SVM::EPSILON_SVR,
36 | SVM::OPT_KERNEL_TYPE => SVM::KERNEL_SIGMOID,
37 | ),
38 | array(
39 | SVM::OPT_TYPE => SVM::NU_SVR,
40 | SVM::OPT_KERNEL_TYPE => SVM::KERNEL_PRECOMPUTED,
41 | ),
42 | );
43 |
44 | $svm = new svm();
45 |
46 | foreach($kernels as $kernel) {
47 | $svm->setOptions($kernel);
48 | $model = $svm->train(dirname(__FILE__) . '/australian.scale');
49 |
50 | if($model) {
51 | echo "ok train " . $kernel[SVM::OPT_TYPE] . "\n";
52 |
53 | $result = $model->predict($data);
54 | if($result != false) {
55 | echo "ok " . $kernel[SVM::OPT_TYPE] . "\n";
56 | } else {
57 | echo "failed: " . $result . "\n";
58 | }
59 | } else {
60 | echo "training failed";
61 | }
62 | }
63 | ?>
64 | --EXPECT--
65 | ok train 0
66 | ok 0
67 | ok train 2
68 | ok 2
69 | ok train 3
70 | ok 3
71 | ok train 4
72 | ok 4
--------------------------------------------------------------------------------
/phpdocs/svm/getoptions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVM::getOptions
7 | Return the current training parameters
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public arraySVM::getOptions
14 |
15 |
16 |
17 | Retrieve an array containing the training parameters. The parameters will be keyed on the predefined SVM constants.
18 |
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 | &no.function.parameters;
25 |
26 |
27 |
28 | &reftitle.returnvalues;
29 |
30 | Returns an array of configuration settings.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
57 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | LibSVM extension for PHP
2 | Copyright (c) 2011, Ian Barber
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of the copyright holder nor the
13 | names of its contributors may be used to endorse or promote products
14 | derived from this software without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL IAN BARBER BE LIABLE FOR ANY
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/phpdocs/svm/setoptions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVM::setOptions
7 | Set training parameters
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public booleanSVM::setOptions
14 | arrayparams
15 |
16 |
17 | Set one or more training parameters.
18 |
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 |
25 |
26 |
27 | params
28 |
29 |
30 | An array of training parameters, keyed on the SVM constants.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | &reftitle.returnvalues;
40 |
41 | Return true on success, throws SVMException on error.
42 |
43 |
44 |
45 |
46 |
66 |
--------------------------------------------------------------------------------
/phpdocs/setup.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.setup;
6 |
7 |
8 | &reftitle.required;
9 |
10 | Libsvm itself is required, and is available through some package management, or direct from the website. If installing from the website: http://www.csie.ntu.edu.tw/~cjlin/libsvm then some steps will need to be taken as the package does not install automatically:
11 |
12 | wget http://www.csie.ntu.edu.tw/~cjlin/cgi-bin/libsvm.cgi?+http://www.csie.ntu.edu.tw/~cjlin/libsvm+tar.gz
13 | tar xvzf libsvm-2.9.tar.gz
14 | cd libsvm-2.9
15 | make lib
16 | cp libsvm.so.1 /usr/lib
17 | ln -s libsvm.so.1 libsvm.so
18 | ldconfig
19 | ldconfig --print | grep libsvm
20 |
21 | This last step should show libsvm is installed.
22 |
23 |
24 |
25 |
26 | &reftitle.install;
27 | &no.install;
28 |
29 |
30 |
31 | &reftitle.runtime;
32 | &no.config;
33 |
34 |
35 |
36 | &reftitle.resources;
37 | &no.resource;
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
65 |
--------------------------------------------------------------------------------
/config.m4:
--------------------------------------------------------------------------------
1 | PHP_ARG_WITH(svm, whether to enable svm support,
2 | [ --with-svm[=DIR] Enable svn support. DIR is the prefix to libsvm installation directory.], yes)
3 |
4 | if test "$PHP_SVM" != "no"; then
5 |
6 |
7 | dnl Get PHP version depending on shared/static build
8 |
9 | AC_MSG_CHECKING([PHP version is at least 5.2.0])
10 |
11 | if test -z "${PHP_VERSION_ID}"; then
12 | if test -z "${PHP_CONFIG}"; then
13 | AC_MSG_ERROR([php-config not found])
14 | fi
15 | PHP_SVM_FOUND_VERNUM=`${PHP_CONFIG} --vernum`;
16 | PHP_SVM_FOUND_VERSION=`${PHP_CONFIG} --version`
17 | else
18 | PHP_SVM_FOUND_VERNUM="${PHP_VERSION_ID}"
19 | PHP_SVM_FOUND_VERSION="${PHP_VERSION}"
20 | fi
21 |
22 | if test "$PHP_SVM_FOUND_VERNUM" -ge "50200"; then
23 | AC_MSG_RESULT(yes. found $PHP_SVM_FOUND_VERSION)
24 | else
25 | AC_MSG_ERROR(no. found $PHP_SVM_FOUND_VERSION)
26 | fi
27 |
28 | AC_MSG_CHECKING([for svm.h header])
29 | for i in $PHP_SVM /usr/local /usr;
30 | do
31 | test -r $i/include/libsvm-2.0/libsvm/svm.h && SVM_PREFIX=$i && SVM_INC_DIR=$i/include/libsvm-2.0/ && SVM_OK=1
32 | done
33 |
34 | if test "$SVM_OK" != "1"; then
35 | for i in $PHP_SVM /usr/local /usr;
36 | do
37 | test -r $i/include/libsvm/svm.h && SVM_PREFIX=$i && SVM_INC_DIR=$i/include/ && SVM_OK=1
38 | done
39 | fi
40 |
41 | if test "$SVM_OK" != "1"; then
42 | AC_MSG_ERROR([Unable to find svm.h])
43 | fi
44 |
45 | AC_MSG_RESULT([found in $SVM_INC_DIR])
46 |
47 | AC_MSG_CHECKING([for libsvm shared libraries])
48 | PHP_CHECK_LIBRARY(svm, svm_train, [
49 | PHP_ADD_LIBRARY_WITH_PATH(svm, $SVM_PREFIX/lib, SVM_SHARED_LIBADD)
50 | PHP_ADD_INCLUDE($SVM_INC_DIR)
51 | ],[
52 | AC_MSG_ERROR([not found. Make sure that libsvm is installed])
53 | ],[
54 | SVM_SHARED_LIBADD -lsvm
55 | ])
56 |
57 | PHP_NEW_EXTENSION(svm, svm.c, $ext_shared)
58 | AC_DEFINE(HAVE_SVM,1,[ ])
59 |
60 | PHP_SUBST(SVM_SHARED_LIBADD)
61 | fi
62 |
63 |
--------------------------------------------------------------------------------
/phpdocs/svmmodel.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The SVMModel class
7 | SVMModel
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 | The SVMModel is the end result of the training process. It can be used to classify previously unseen data.
16 |
17 |
18 |
19 |
20 |
21 | &reftitle.classsynopsis;
22 |
23 |
24 |
25 | SVMModel
26 |
27 |
28 |
29 |
30 | SVMModel
31 |
32 |
33 |
34 |
35 | Methods
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | &reference.svm.entities.svmmodel;
45 |
46 |
47 |
48 |
68 |
--------------------------------------------------------------------------------
/phpdocs/versions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
49 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | svm
7 | pecl.php.net
8 | Support Vector Machine Library
9 | LibSVM is an efficient solver for SVM classification and regression problems. The svm extension wraps this in a PHP interface for easy use in PHP scripts.
10 |
11 |
12 | Ian Barber
13 | ianb
14 | ian.barber@gmail.co,
15 | yes
16 |
17 | 2011-04-26
18 |
19 |
20 | 0.9.0
21 | 0.9.0
22 |
23 |
24 | beta
25 | beta
26 |
27 | PHP
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | 5.2.0
54 |
55 |
56 | 1.4.0
57 |
58 |
59 |
60 | svm
61 |
62 |
63 |
--------------------------------------------------------------------------------
/phpdocs/svmmodel/save.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVMModel::save
7 | Save a model to a file
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public booleanSVMModel::save
14 | stringfilename
15 |
16 |
17 | Save the model data to a file, for later use.
18 |
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 |
25 |
26 |
27 | filename
28 |
29 |
30 | The file to save the model to.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | &reftitle.returnvalues;
40 |
41 | Throws SVMException on error.
42 | Returns true on success.
43 |
44 |
45 |
46 |
47 | &reftitle.seealso;
48 |
49 |
50 | SVMModel::load
51 |
52 |
53 |
54 |
55 |
56 |
57 |
77 |
--------------------------------------------------------------------------------
/phpdocs/svmmodel/load.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVMModel::load
7 | Load a saved SVM Model
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public booleanSVMModel::load
14 | stringfilename
15 |
16 |
17 | Load a model file ready for classification or regression.
18 |
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 |
25 |
26 |
27 | filename
28 |
29 |
30 | The filename of the model.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | &reftitle.returnvalues;
40 |
41 | Throws SVMException on error.
42 | Returns true on success.
43 |
44 |
45 |
46 |
47 | &reftitle.seealso;
48 |
49 |
50 | SVMModel::save
51 |
52 |
53 |
54 |
55 |
56 |
57 |
77 |
--------------------------------------------------------------------------------
/phpdocs/svmmodel/construct.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVMModel::__construct
7 | Construct a new SVMModel
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | SVMModel::__construct
14 | stringfilename
15 |
16 |
17 | Build a new SVMModel. Models will usually be created from the SVM::train function, but then saved models may be restored directly.
18 |
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 |
25 |
26 |
27 | filename
28 |
29 |
30 | The filename for the saved model file this model should load.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | &reftitle.returnvalues;
40 |
41 | Throws SVMException on error
42 |
43 |
44 |
45 |
46 | &reftitle.seealso;
47 |
48 |
49 | SVMModel::load
50 |
51 |
52 |
53 |
54 |
55 |
56 |
76 |
--------------------------------------------------------------------------------
/phpdocs/svmmodel/predict.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVMModel::predict
7 | Predict a value for previously unseen data
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public floatSVMModel::predict
14 | arraydata
15 |
16 |
17 | This function accepts an array of data and attempts to predict the class or regression value based on the model extracted from previously trained data.
18 |
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 |
25 |
26 |
27 | data
28 |
29 |
30 | The array to be classified. This should be a series of key => value pairs in increasing key order, but not necessarily continuous.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | &reftitle.returnvalues;
40 |
41 | Float the predicted value. This will be a class label in the case of classification, a real value in the case of regression.
42 | Throws SVMException on error
43 |
44 |
45 |
46 |
47 | &reftitle.seealso;
48 |
49 |
50 | SVM::train
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
78 |
--------------------------------------------------------------------------------
/php_svm.h:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 / svm |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 2010 Ian Barber |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.0 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_0.txt. |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Authors: Ian Barber |
16 | +----------------------------------------------------------------------+
17 | */
18 | #ifndef _PHP_SVM_H_
19 | # define _PHP_SVM_H_
20 |
21 | #define PHP_SVM_EXTNAME "svm"
22 | #define PHP_SVM_EXTVER "@PACKAGE_VERSION@"
23 |
24 | #ifdef HAVE_CONFIG_H
25 | # include "config.h"
26 | #endif
27 |
28 | #ifdef ZTS
29 | # include "TSRM.h"
30 | #endif
31 |
32 | #include "php.h"
33 | #include
34 |
35 | ZEND_BEGIN_MODULE_GLOBALS(svm)
36 | zend_bool test;
37 | ZEND_END_MODULE_GLOBALS(svm)
38 |
39 | ZEND_EXTERN_MODULE_GLOBALS(svm)
40 |
41 | #ifdef ZTS
42 | # define SVM_G(v) TSRMG(svm_globals_id, zend_svm_globals *, v)
43 | #else
44 | # define SVM_G(v) (svm_globals.v)
45 | #endif
46 |
47 | typedef struct _php_svm_object {
48 | zend_object zo;
49 | /* hold the SVM parameters */
50 | struct svm_parameter param;
51 |
52 | /* Store the last error message here */
53 | char last_error[512];
54 |
55 | } php_svm_object;
56 |
57 | typedef struct _php_svm_model_object {
58 | zend_object zo;
59 |
60 | /* Hold the training data */
61 | struct svm_node *x_space;
62 |
63 | /* hold the model generated by training, or to be used for classifying*/
64 | struct svm_model *model;
65 |
66 | } php_svm_model_object;
67 |
68 | extern zend_module_entry svm_module_entry;
69 | #define phpext_svm_ptr &svm_module_entry
70 |
71 | #endif /* _PHP_SVM_H_ */
72 |
73 |
74 |
--------------------------------------------------------------------------------
/phpdocs/svm/train.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVM::train
7 | Create a SVMModel based on training data
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public SVMModelsvm::train
14 | arrayproblem
15 | arrayweights
16 |
17 |
18 | Train a support vector machine based on the supplied training data.
19 |
20 |
21 |
22 |
23 |
24 | &reftitle.parameters;
25 |
26 |
27 |
28 | problem
29 |
30 |
31 | The problem can be provided in three different ways.
32 | An array, where the data should start with the class label (usually 1 or -1) then followed by a sparse data set of dimension => data pairs.
33 | A URL to a file containing a SVM Light formatted problem, with the each line being a new training example, the start of each line containing the class (1, -1) then a series of tab separated data values shows as key:value.
34 | A opened stream pointing to a data source formatted as in the file above.
35 |
36 |
37 |
38 |
39 | weights
40 |
41 |
42 | Weights are an optional set of weighting parameters for the different classes, to help account for unbalanced training sets. For example, if the classes were 1 and -1, and -1 had significantly more example than one, the weight for -1 could be 0.5. Weights should be in the range 0-1.
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | &reftitle.returnvalues;
52 |
53 | Returns an SVMModel that can be used to classify previously unseen data.
54 | Throws SVMException on error
55 |
56 |
57 |
58 |
59 |
60 |
61 |
81 |
--------------------------------------------------------------------------------
/phpdocs/svm/crossvalidate.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SVM::crossvalidate
7 | Test training params on subsets of the training data.
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public floatsvm::crossvalidate
14 | arrayproblem
15 | intnumber_of_folds
16 |
17 |
18 | Crossvalidate can be used to test the effectiveness of the current parameter set on a subset of the training data. Given a problem set and a n "folds", it separates the problem set into n subsets, and the repeatedly trains on one subset and tests on another. While the accuracy will generally be lower than a SVM trained on the enter data set, the accuracy score returned should be relatively useful, so it can be used to test different training parameters.
19 |
20 |
21 |
22 |
23 |
24 | &reftitle.parameters;
25 |
26 |
27 |
28 | problem
29 |
30 |
31 | The problem data. This can either be in the form of an array, the URL of an SVMLight formatted file, or a stream to an opened SVMLight formatted datasource.
32 |
33 |
34 |
35 |
36 | number_of_folds
37 |
38 |
39 | The number of sets the data should be divided into and cross tested. A higher number means smaller training sets and less reliability. 5 is a good number to start with.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | &reftitle.returnvalues;
49 |
50 | The correct percentage, expressed as a floating point number from 0-1. In the case of NU_SVC or EPSILON_SVR kernels the mean squared error will returned instead.
51 |
52 |
53 |
54 |
55 | &reftitle.seealso;
56 |
57 |
58 | SVM::train
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
87 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | INTRODUCTION
2 |
3 | LibSVM is an efficient solver for SVM classification and regression problems. The svm extension wraps this in a PHP interface for easy use in PHP scripts. The extension requires PHP 5.2 or above.
4 |
5 | Libsvm itself is required, and is available through some package management, or direct from the website.
6 |
7 | On ubuntu and other debian based systems, you may be able to installed the libsvm-dev package:
8 |
9 | apt-get install libsvm-dev
10 |
11 | If installing from the website: http://www.csie.ntu.edu.tw/~cjlin/libsvm then some steps will need to be taken as the package does not install automatically:
12 |
13 | wget http://www.csie.ntu.edu.tw/~cjlin/cgi-bin/libsvm.cgi?+http://www.csie.ntu.edu.tw/~cjlin/libsvm+tar.gz
14 | tar xvzf libsvm-3.1.tar.gz
15 | cd libsvm-3.1
16 | make lib
17 | cp libsvm.so.1 /usr/lib
18 | ln -s libsvm.so.1 libsvm.so
19 | ldconfig
20 | ldconfig --print | grep libsvm
21 |
22 | This last step should show libsvm is installed.
23 |
24 | Once libsvm is installed, the extension can be installed in the usual way.
25 |
26 | USAGE
27 |
28 | The basic process is to define parameters, supply training data to generate a model on, then make predictions based on the model. There are a default set of parameters that should get some results with most any input, so we'll start by looking at the data.
29 |
30 | Data is supplied in either a file, a stream, or as an an array. If supplied in a file or a stream, it must contain one line per training example, which must be formatted as an integer class (usually 1 and -1) followed by a series of feature/value pairs, in increasing feature order. The features are integers, the values floats, usually scaled 0-1. For example:
31 |
32 | -1 1:0.43 3:0.12 9284:0.2
33 |
34 | In a document classification problem, say a spam checker, each line would represent a document. There would be two classes, -1 for spam, 1 for ham. Each feature would represent some word, and the value would represent that importance of that word to the document (perhaps the frequency count, with the total scaled to unit length). Features that were 0 (e.g. the word did not appear in the document at all) would simply not be included.
35 |
36 | In array mode, the data must be passed as an array of arrays. Each sub-array must have the class as the first element, then key => value sets for the feature values pairs. E.g.
37 |
38 | array(
39 | array(-1, 1 => 0.43, 3 => 0.12, 9284 => 0.2),
40 | );
41 |
42 | This data is passed to the SVM class's train function, which will return an SVM model is successful.
43 |
44 | $svm = new SVM();
45 | $model = $svm->train($data);
46 |
47 | or, for example with a filename
48 |
49 | $svm = new SVM();
50 | $model = $svm->train("traindata.txt");
51 |
52 | Once a model has been generated, it can be used to make predictions about previously unseen data. This can be passed as an array to the model's predict function, in the same format as before, but without the label. The response will be the class.
53 |
54 | $data = array(1 => 0.43, 3 => 0.12, 9284 => 0.2);
55 | $result = $model->predict($data);
56 |
57 | In this case, $result would be -1.
58 |
59 | Models can be saved and restored as required, using the save and load functions, which both take a file location.
60 |
61 | $model->save('model.svm');
62 |
63 | And to load:
64 |
65 | $model = new SVMModel();
66 | $model->load('model.svm');
67 |
68 |
--------------------------------------------------------------------------------
/phpdocs/svmexception.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The SVMException class
7 | SVMException
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 | The exception object thrown on errors from the SVM and SVMModel classes.
16 |
17 |
18 |
19 |
20 |
21 | &reftitle.classsynopsis;
22 |
23 |
24 |
25 | SVMException
26 |
27 |
28 |
29 |
30 | SVMException
31 |
32 |
33 |
34 | extends
35 | Exception
36 |
37 |
38 |
39 | Properties
40 |
41 |
42 | Methods
43 |
44 |
45 | Inherited methods
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | &reftitle.properties;
57 |
58 |
59 | message
60 |
61 |
62 |
63 |
64 |
65 | code
66 |
67 |
68 |
69 |
70 |
71 | file
72 |
73 |
74 |
75 |
76 |
77 | line
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | &reference.svm.entities.svmexception;
90 |
91 |
92 |
93 |
113 |
--------------------------------------------------------------------------------
/phpdocs/examples.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.examples;
6 |
7 |
8 | The basic process is to define parameters, supply training data to generate a model on, then make predictions based on the model. There are a default set of parameters that should get some results with most any input, so we'll start by looking at the data.
9 |
10 | Data is supplied in either a file, a stream, or as an an array. If supplied in a file or a stream, it must contain one line per training example, which must be formatted as an integer class (usually 1 and -1) followed by a series of feature/value pairs, in increasing feature order. The features are integers, the values floats, usually scaled 0-1. For example:
11 |
12 | -1 1:0.43 3:0.12 9284:0.2
13 |
14 | In a document classification problem, say a spam checker, each line would represent a document. There would be two classes, -1 for spam, 1 for ham. Each feature would represent some word, and the value would represent that importance of that word to the document (perhaps the frequency count, with the total scaled to unit length). Features that were 0 (e.g. the word did not appear in the document at all) would simply not be included.
15 |
16 | In array mode, the data must be passed as an array of arrays. Each sub-array must have the class as the first element, then key => value sets for the feature values pairs.
17 |
18 | This data is passed to the SVM class's train function, which will return an SVM model is successful.
19 |
20 | Once a model has been generated, it can be used to make predictions about previously unseen data. This can be passed as an array to the model's predict function, in the same format as before, but without the label. The response will be the class.
21 |
22 | Models can be saved and restored as required, using the save and load functions, which both take a file location.
23 |
24 |
25 |
26 | Train from array
27 |
28 | 0.43, 3 => 0.12, 9284 => 0.2),
32 | array(1, 1 => 0.22, 5 => 0.01, 94 => 0.11),
33 | );
34 |
35 | $svm = new SVM();
36 | $model = $svm->train($data);
37 |
38 | $data = array(1 => 0.43, 3 => 0.12, 9284 => 0.2);
39 | $result = $model->predict($data);
40 | var_dump($result);
41 | $model->save('model.svm');
42 | ?>
43 | ]]>
44 |
45 | &example.outputs.similar;
46 |
47 |
51 |
52 |
53 |
54 | Train from a file
55 |
56 | train("traindata.txt");
60 | ?>
61 | ]]>
62 |
63 | &example.outputs.similar;
64 |
65 |
68 |
69 |
70 |
71 |
72 |
92 |
93 |
--------------------------------------------------------------------------------
/phpdocs/svm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The SVM class
7 | SVM
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | &reftitle.classsynopsis;
22 |
23 |
24 |
25 | SVM
26 |
27 |
28 |
29 |
30 | SVM
31 |
32 |
33 |
34 | Constants
35 |
36 | const
37 | integer
38 | SVM::C_SVC
39 | 0
40 |
41 |
42 | const
43 | integer
44 | SVM::NU_SVC
45 | 1
46 |
47 |
48 | const
49 | integer
50 | SVM::ONE_CLASS
51 | 2
52 |
53 |
54 | const
55 | integer
56 | SVM::EPSILON_SVR
57 | 3
58 |
59 |
60 | const
61 | integer
62 | SVM::NU_SVR
63 | 4
64 |
65 |
66 | const
67 | integer
68 | SVM::KERNEL_LINEAR
69 | 0
70 |
71 |
72 | const
73 | integer
74 | SVM::KERNEL_POLY
75 | 1
76 |
77 |
78 | const
79 | integer
80 | SVM::KERNEL_RBF
81 | 2
82 |
83 |
84 | const
85 | integer
86 | SVM::KERNEL_SIGMOID
87 | 3
88 |
89 |
90 | const
91 | integer
92 | SVM::KERNEL_PRECOMPUTED
93 | 4
94 |
95 |
96 | const
97 | integer
98 | SVM::OPT_TYPE
99 | 101
100 |
101 |
102 | const
103 | integer
104 | SVM::OPT_KERNEL_TYPE
105 | 102
106 |
107 |
108 | const
109 | integer
110 | SVM::OPT_DEGREE
111 | 103
112 |
113 |
114 | const
115 | integer
116 | SVM::OPT_SHRINKING
117 | 104
118 |
119 |
120 | const
121 | integer
122 | SVM::OPT_PROPABILITY
123 | 105
124 |
125 |
126 | const
127 | integer
128 | SVM::OPT_GAMMA
129 | 201
130 |
131 |
132 | const
133 | integer
134 | SVM::OPT_NU
135 | 202
136 |
137 |
138 | const
139 | integer
140 | SVM::OPT_EPS
141 | 203
142 |
143 |
144 | const
145 | integer
146 | SVM::OPT_P
147 | 204
148 |
149 |
150 | const
151 | integer
152 | SVM::OPT_COEF_ZERO
153 | 205
154 |
155 |
156 | const
157 | integer
158 | SVM::OPT_C
159 | 206
160 |
161 |
162 | const
163 | integer
164 | SVM::OPT_CACHE_SIZE
165 | 207
166 |
167 |
168 | const
169 | integer
170 | SVM::OPT_WEIGHT
171 | 208
172 |
173 |
174 | Methods
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 | &reftitle.constants;
184 |
185 | svm Node Types
186 |
187 |
188 |
189 | SVM::C_SVC
190 |
191 | The basic C_SVC SVM type. The default, and a good starting point.
192 |
193 |
194 |
195 |
196 | SVM::NU_SVC
197 |
198 | The NU_SVC type uses a different, more flexible, error weighting.
199 |
200 |
201 |
202 |
203 | SVM::ONE_CLASS
204 |
205 | Train just on a single class, using outliers as negative examples.
206 |
207 |
208 |
209 |
210 | SVM::EPSILON_SVR
211 |
212 | A SVM type for regression (predicting a value rather than just a class)
213 |
214 |
215 |
216 |
217 | SVM::NU_SVR
218 |
219 | A NU style SVM regression type
220 |
221 |
222 |
223 |
224 | SVM::KERNEL_LINEAR
225 |
226 | A very simple kernel, can work well on large document classification problems.
227 |
228 |
229 |
230 |
231 | SVM::KERNEL_POLY
232 |
233 | A polynomial kernel.
234 |
235 |
236 |
237 |
238 | SVM::KERNEL_RBF
239 |
240 | The common Gaussian RBD kernel. Handles non-linear problems well and is a good default for classification.
241 |
242 |
243 |
244 |
245 | SVM::KERNEL_SIGMOID
246 |
247 | A kernel bsaed on the sigmoid function. Using this makes the SVM very similar to a two layer sigmoid based neural network.
248 |
249 |
250 |
251 |
252 | SVM::KERNEL_PRECOMPUTED
253 |
254 | A precomputer kernel - currently unsupported.
255 |
256 |
257 |
258 |
259 | SVM::OPT_TYPE
260 |
261 | The options key for the SVM type
262 |
263 |
264 |
265 |
266 | SVM::OPT_KERNEL_TYPE
267 |
268 | The options key for the kernel type
269 |
270 |
271 |
272 |
273 | SVM::OPT_DEGREE
274 |
275 |
276 |
277 |
278 |
279 |
280 | SVM::OPT_SHRINKING
281 |
282 |
283 |
284 |
285 |
286 |
287 | SVM::OPT_PROBABILITY
288 |
289 |
290 |
291 |
292 |
293 |
294 | SVM::OPT_GAMMA
295 |
296 |
297 |
298 |
299 |
300 |
301 | SVM::OPT_NU
302 |
303 | The option key for the nu parameter, only used in the NU_ SVM types
304 |
305 |
306 |
307 |
308 | SVM::OPT_EPS
309 |
310 | The option key for the Epsilon parameter, used in epsilon regression.
311 |
312 |
313 |
314 |
315 | SVM::OPT_P
316 |
317 |
318 |
319 |
320 |
321 |
322 | SVM::OPT_COEF_ZERO
323 |
324 |
325 |
326 |
327 |
328 |
329 | SVM::OPT_C
330 |
331 | The option for the cost parameter that controls tradeoff between errors and generality.
332 |
333 |
334 |
335 |
336 | SVM::OPT_CACHE_SIZE
337 |
338 |
339 |
340 |
341 |
342 |
343 | SVM::OPT_WEIGHT
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 | &reference.svm.entities.svm;
358 |
359 |
360 |
361 |
381 |
--------------------------------------------------------------------------------
/tests/australian.scale:
--------------------------------------------------------------------------------
1 | -1 1:1 2:-0.749474 3:-0.181429 5:-0.538462 6:-0.25 7:-0.888772 8:-1 9:-1 10:-1 11:1 13:-0.9 14:-0.97576
2 | -1 1:-1 2:-0.731729 3:-0.5 5:0.0769231 6:-0.25 7:-0.988421 8:-1 9:-1 10:-1 11:-1 13:-0.84 14:-1
3 | -1 1:-1 2:-0.52391 3:-0.875 4:-1 5:-0.538462 6:-0.25 7:-0.912281 8:-1 9:-1 10:-1 11:1 13:-0.72 14:-1
4 | +1 1:-1 2:-0.761805 3:-0.178571 4:-1 5:-0.384615 6:-0.5 7:-1 8:1 9:1 10:-0.671642 11:1 13:-1 14:-1
5 | +1 1:1 2:-0.806917 3:-0.416429 5:-0.230769 6:-0.25 7:-0.862456 8:1 9:1 10:-0.58209 11:-1 13:-0.94 14:-0.99684
6 | +1 1:-1 2:-0.937444 3:-0.958214 5:0.0769231 6:0.75 7:-0.894737 8:1 9:1 10:-0.940299 11:-1 13:-0.9 14:-1
7 | -1 1:1 2:-0.889624 3:-0.535714 5:-0.692308 6:-0.25 7:-0.991228 8:-1 9:-1 10:-1 11:-1 13:-0.94 14:-0.998
8 | +1 1:-1 2:0.350977 3:-0.681429 5:0.538462 6:0.75 7:-0.786667 8:1 9:1 10:-0.820896 11:-1 13:-0.957 14:-0.9888
9 | -1 1:1 2:-0.576541 3:-0.928571 4:-1 5:-0.846154 6:0.75 7:-0.789474 8:-1 9:-1 10:-1 11:-1 13:-0.824 14:-0.98926
10 | -1 1:-1 2:0.263158 3:-0.494286 5:-0.538462 6:0.75 7:-0.526316 8:1 9:1 10:-0.910448 11:1 13:-0.9 14:-0.999
11 | +1 1:1 2:-0.406015 3:-0.875 5:1 6:0.75 7:-0.684211 8:1 9:1 10:-0.880597 11:1 13:-0.747 14:-0.98286
12 | +1 1:1 2:-0.16782 3:-0.642857 5:0.538462 6:0.75 7:-0.649123 8:1 9:1 10:-0.820896 11:1 13:-0.53 14:-1
13 | -1 1:1 2:-0.79188 3:-0.910714 4:-1 5:0.0769231 6:0.75 7:-0.903509 8:1 9:1 10:-0.910448 11:1 13:-0.86 14:-0.9958
14 | +1 1:1 2:-0.363308 3:-0.642857 5:1 6:0.75 7:-0.473684 8:1 9:1 10:-0.820896 11:1 13:-1 14:-0.98
15 | -1 1:1 2:0.348271 3:-0.806429 5:0.0769231 6:-0.25 7:-0.830526 8:-1 9:-1 10:-1 11:1 13:-0.68 14:-1
16 | +1 1:1 2:0.0324813 3:-0.568571 5:-0.538462 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-1 14:-0.9462
17 | +1 1:1 2:-0.52391 3:-0.678571 5:0.230769 6:-0.25 7:-0.473684 8:1 9:1 10:-0.940299 11:1 13:-0.67 14:-1
18 | +1 1:-1 2:-0.844511 3:-0.357143 5:-0.230769 6:-0.25 7:-0.947368 8:1 9:1 10:-0.940299 11:-1 13:-0.912 14:-0.98818
19 | -1 1:1 2:-0.81203 3:-0.910714 4:-1 5:-0.538462 6:-0.25 7:-0.991228 8:-1 9:-1 10:-1 11:-1 13:-0.86 14:-0.99992
20 | +1 1:-1 2:-0.739248 3:-0.595357 5:0.538462 6:-0.25 7:-0.818596 8:1 9:1 10:-0.791045 11:-1 13:-0.871 14:-0.93486
21 | -1 1:-1 2:-0.566316 3:-0.958214 5:-0.230769 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-0.74 14:-0.97992
22 | -1 1:-1 2:-0.836992 3:-0.958214 4:-1 5:-0.230769 6:-0.25 7:-0.958947 8:1 9:-1 10:-1 11:1 13:-0.84 14:-1
23 | -1 1:1 2:-0.175338 3:-0.904643 5:-0.846154 6:-0.25 7:-0.988421 8:-1 9:-1 10:-1 11:-1 13:-0.832 14:-1
24 | -1 1:1 2:-0.163007 3:-0.875 5:-0.538462 6:-0.25 7:-0.985263 8:1 9:-1 10:-1 11:-1 13:-0.84 14:-1
25 | -1 1:1 2:-0.827068 3:-0.315357 5:-0.230769 6:-0.25 7:-0.944561 8:-1 9:-1 10:-1 11:-1 13:-0.92 14:-0.993
26 | +1 1:1 2:-0.428571 3:-0.892857 5:0.846154 6:0.75 7:-0.614035 8:1 9:1 10:-0.910448 11:1 13:-1 14:-1
27 | -1 1:1 2:-0.736842 3:-0.991071 4:-1 5:-0.538462 6:-0.25 7:-0.991228 8:-1 9:-1 10:-1 11:-1 13:-0.8 14:-0.9986
28 | +1 1:1 2:-0.41594 3:-0.782857 4:-1 5:0.0769231 6:0.75 7:-0.856842 8:1 9:1 10:-0.970149 11:1 13:-0.82 14:-0.63946
29 | +1 1:-1 2:-0.491128 3:-0.142857 5:0.0769231 6:-0.25 7:-0.859649 8:1 9:1 10:-0.970149 11:-1 13:-0.78 14:-0.99962
30 | +1 1:1 2:-0.719398 3:-0.821429 5:0.0769231 6:-0.25 7:-0.92386 8:1 9:1 10:-0.671642 11:1 13:-0.94 14:-0.95632
31 | +1 1:1 2:-0.601504 3:-0.946429 5:0.0769231 6:0.75 7:-0.701754 8:1 9:1 10:-0.910448 11:1 13:-0.688 14:-0.997
32 | -1 1:-1 2:-0.799398 3:-0.25 4:-1 5:1 6:0.75 7:-1 8:-1 9:-1 10:-1 11:1 13:-0.846 14:-0.99936
33 | -1 1:1 2:0.160301 3:-0.901786 4:-1 5:0.0769231 6:0.75 7:-0.33614 8:1 9:-1 10:-1 11:1 13:-0.8 14:-0.998
34 | +1 1:1 2:-0.719398 3:-0.178571 5:0.230769 6:0.75 7:-0.850877 8:1 9:1 10:-0.671642 11:1 13:-0.71 14:-0.99432
35 | -1 1:1 2:-0.125413 3:-0.910714 5:-0.0769231 6:-0.25 7:-0.0263158 8:-1 9:1 10:-0.970149 11:1 13:-0.648 14:-0.99776
36 | -1 1:1 2:0.836993 3:0.357143 4:-1 5:-1 6:-1 7:-0.997193 8:-1 9:1 10:-0.940299 11:-1 13:-1 14:-0.99298
37 | +1 1:1 2:-0.661654 3:-0.107143 5:-0.230769 6:-0.25 7:-0.789474 8:1 9:-1 10:-1 11:1 12:-1 13:-0.98 14:-1
38 | +1 1:1 2:-0.223158 3:-0.00607143 5:0.230769 6:-0.25 7:-0.394737 8:1 9:1 10:-0.820896 11:1 13:-0.93 14:-1
39 | +1 1:-1 2:0.0225564 3:-0.428571 5:0.0769231 6:-0.25 7:-0.447368 8:1 9:1 10:-0.820896 11:1 13:-1 14:-0.9748
40 | +1 1:-1 2:0.0126315 3:-0.785714 5:1 6:-0.25 7:-0.0263158 8:1 9:1 10:-0.940299 11:1 13:-0.481 14:-0.96592
41 | +1 1:1 2:-0.716692 3:-1 5:0.846154 6:-0.25 7:-0.994035 8:1 9:-1 10:-1 11:-1 13:-1 14:-1
42 | -1 1:1 2:-0.734436 3:-0.892857 4:-1 5:-0.230769 6:-0.25 7:-0.962105 8:-1 9:-1 10:-1 11:1 13:-0.88 14:-0.99866
43 | +1 1:1 2:-0.609023 3:-0.919643 5:1 6:0.75 7:-0.912281 8:1 9:-1 10:-1 11:-1 13:-1 14:-0.89404
44 | -1 1:1 2:0.491128 3:-0.961429 5:0.0769231 6:-0.25 7:-0.958947 8:1 9:1 10:-0.910448 11:1 13:-0.82 14:-1
45 | -1 1:1 2:-0.699248 3:-0.970357 4:-1 5:0.0769231 6:-0.25 7:-0.997193 8:-1 9:1 10:-0.940299 11:-1 13:-0.872 14:-0.99988
46 | +1 1:-1 2:-0.789474 3:-0.267857 5:0.538462 6:-0.25 7:-0.950175 8:1 9:1 10:-0.940299 11:1 13:-0.951 14:-1
47 | -1 1:-1 2:-0.676692 3:-0.875 4:-1 5:0.0769231 6:-0.25 7:-0.988421 8:-1 9:-1 10:-1 11:-1 13:-0.868 14:-1
48 | +1 1:1 2:-0.927218 3:-0.997143 5:0.0769231 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-1 14:-1
49 | -1 1:-1 2:-0.526316 3:-0.857143 4:-1 5:0.384615 6:0.75 7:-0.859649 8:-1 9:-1 10:-1 11:-1 13:-0.744 14:-0.99966
50 | +1 1:-1 2:0.175338 3:0.0714286 5:0.0769231 6:-0.25 7:-0.614035 8:1 9:1 10:-0.58209 11:-1 13:-1 14:-0.956
51 | -1 1:1 2:-0.441203 3:-0.75 5:-0.538462 6:-0.25 7:-0.964912 8:-1 9:-1 10:-1 11:1 13:-0.768 14:-1
52 | -1 1:1 2:-0.779549 3:-0.705357 4:-1 5:-0.692308 6:0.75 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-0.86 14:-0.998
53 | -1 1:1 2:-0.566316 3:-0.991071 4:-1 5:-0.538462 6:-0.25 7:-0.994035 8:-1 9:-1 10:-1 11:-1 13:-0.784 14:-0.958
54 | -1 1:1 2:-0.842105 3:-0.875 4:-1 5:0.0769231 6:-0.25 7:-0.83614 8:-1 9:-1 10:-1 11:1 13:-0.888 14:-0.99988
55 | -1 1:1 2:-0.58406 3:-0.767857 4:-1 5:0.538462 6:0.75 7:-0.643158 8:-1 9:1 10:-0.940299 11:1 13:-0.631 14:-0.99998
56 | +1 1:1 2:-0.576541 3:-0.892857 5:0.230769 6:-0.25 7:-0.859649 8:1 9:1 10:-0.671642 11:1 13:-0.566 14:-0.9993
57 | +1 1:1 2:-0.210526 3:-0.535714 5:-0.230769 7:-0.754386 8:1 9:1 10:-0.970149 11:-1 13:-1 14:-0.99
58 | -1 1:-1 2:-0.290827 3:-0.821429 5:-0.692308 6:0.75 7:-0.985263 8:-1 9:-1 10:-1 11:-1 13:-0.74 14:-0.99508
59 | +1 1:1 2:-0.135338 3:-0.648929 4:-1 5:0.230769 6:-0.25 7:-0.777895 8:1 9:-1 10:-1 11:1 13:-0.948 14:-0.97116
60 | +1 1:1 2:0.293233 3:-0.125 5:-0.0769231 6:-0.25 7:-0.912281 8:1 9:1 10:-0.880597 11:1 13:-0.8 14:-1
61 | -1 1:1 2:-0.115188 3:-0.642857 5:-0.692308 7:-0.842105 8:-1 9:-1 10:-1 11:1 13:-0.859 14:-1
62 | -1 1:-1 2:-0.699248 3:-0.949286 5:0.230769 6:-0.25 7:-0.982456 8:-1 9:1 10:-0.970149 11:1 13:-0.76 14:-0.99992
63 | +1 1:1 2:-0.857143 3:-0.857143 5:-0.692308 6:-0.25 7:-0.894737 8:1 9:1 10:-0.940299 11:-1 13:-0.88 14:-0.994
64 | -1 1:-1 2:-0.185564 3:-0.75 5:-0.692308 7:-0.964912 8:-1 9:-1 10:-1 11:-1 12:-1 13:0.16 14:-1
65 | +1 1:-1 2:-0.676692 3:-0.964286 5:0.538462 6:0.75 7:-0.894737 8:1 9:-1 10:-1 11:-1 13:-0.72 14:-0.98352
66 | +1 1:1 2:-0.150376 3:-0.300714 5:1 6:0.75 7:-0.441404 8:1 9:1 10:-0.761194 11:-1 13:-1 14:-1
67 | -1 1:-1 2:-0.827068 3:-0.988214 5:0.538462 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:1 13:-0.62 14:-1
68 | -1 1:1 2:-0.766917 3:-0.178571 5:-0.692308 6:-0.25 7:-0.964912 8:1 9:-1 10:-1 11:1 13:-0.9 14:-0.99864
69 | -1 1:1 2:-0.473684 3:-0.7975 5:-1 6:-1 7:-1 8:-1 9:1 10:-0.850746 11:-1 13:-0.824 14:-0.99708
70 | +1 1:1 2:-0.593985 3:-0.886786 5:0.846154 6:0.75 7:-0.871228 8:1 9:1 10:-0.641791 11:1 13:-0.417 14:-0.98574
71 | -1 1:1 2:0.0526316 3:0.881071 4:-1 5:-1 6:-1 7:-1 8:1 9:-1 10:-1 11:1 13:-1 14:-1
72 | -1 1:-1 2:-0.498647 3:-0.901786 5:0.230769 6:0.75 7:-0.997193 8:-1 9:1 10:-0.910448 11:-1 13:-1 14:-0.99934
73 | -1 1:1 2:-0.528722 3:-0.910714 5:0.230769 6:-0.25 7:-0.877193 8:-1 9:-1 10:-1 11:-1 13:-0.8 14:-1
74 | +1 1:1 2:-0.56391 3:-0.64 4:-1 5:0.0769231 7:-0.894737 8:1 9:1 10:-0.761194 11:1 13:-0.856 14:-0.99986
75 | +1 1:1 2:-0.203008 3:0.535714 5:0.384615 6:1 7:0.403509 8:1 9:1 10:-0.671642 11:-1 13:-1 14:-0.976
76 | -1 1:1 2:-0.315789 3:-0.696429 5:0.538462 6:-0.25 7:-0.754386 8:-1 9:-1 10:-1 11:-1 13:-0.546 14:-0.999
77 | -1 1:1 2:-0.644211 3:-0.976071 5:-0.538462 6:0.75 7:-0.754386 8:-1 9:-1 10:-1 11:1 13:-0.66 14:-1
78 | -1 1:1 2:-0.516391 3:-0.75 5:0.0769231 6:-0.25 7:-0.988421 8:-1 9:-1 10:-1 11:-1 13:-0.784 14:-1
79 | -1 1:1 2:-0.719398 3:-1 5:-0.538462 6:-0.25 7:-0.929825 8:-1 9:1 10:-0.671642 11:-1 12:-1 13:-1 14:-1
80 | +1 1:-1 2:-0.446015 3:-0.895714 5:0.230769 6:-0.25 7:-0.92386 8:1 9:1 10:-0.522388 11:-1 13:-0.88 14:-0.95842
81 | +1 1:1 2:-0.656541 3:-0.75 5:0.846154 6:-0.25 7:-0.95614 8:1 9:1 10:-0.791045 11:-1 13:-1 14:-0.85882
82 | -1 1:-1 2:-0.35579 3:-0.732143 5:-1 6:-1 7:-1 8:-1 9:1 10:-0.820896 11:-1 13:-1 14:-0.996
83 | -1 1:-1 2:-0.854737 3:-0.285714 5:-0.846154 6:-0.25 7:-0.970877 8:-1 9:-1 10:-1 11:-1 13:-0.92 14:-0.99916
84 | -1 1:1 2:-0.212932 3:-0.642857 5:-0.692308 7:-0.985263 8:-1 9:-1 10:-1 11:-1 13:-0.45 14:-1
85 | -1 1:1 2:-0.709173 3:-0.928571 5:0.0769231 6:-0.25 7:-0.964912 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.72 14:-1
86 | +1 1:1 2:-0.283308 3:-1 5:0.0769231 6:-0.25 7:-1 8:-1 9:-1 10:-1 11:-1 12:1 13:-0.816 14:-1
87 | -1 1:-1 2:-0.669173 3:-0.0239286 5:0.538462 6:0.75 7:-0.894737 8:-1 9:-1 10:-1 11:-1 13:-0.72 14:-0.99998
88 | +1 1:-1 3:-0.0714286 5:-0.692308 7:-0.637544 8:1 9:1 10:-0.731343 11:1 13:-1 14:-1
89 | +1 1:1 2:-0.385865 3:-0.625 5:0.230769 6:-0.25 7:-0.994035 8:-1 9:-1 10:-1 11:1 13:-0.71 14:-0.99988
90 | -1 1:1 2:-0.746767 3:-0.958214 4:-1 5:-1 6:-1 7:-1 8:-1 9:-1 10:-1 11:-1 13:-0.9 14:-1
91 | -1 1:1 2:-0.578947 3:-0.907857 5:-0.538462 6:0.75 7:-0.982456 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.86 14:-1
92 | -1 1:1 2:-0.12782 3:-0.708214 5:-0.230769 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-0.892 14:-0.998
93 | -1 1:1 2:-0.551278 3:0.0357143 5:-0.846154 6:-0.25 7:-0.991228 8:-1 9:-1 10:-1 11:-1 13:-1 14:-0.99428
94 | +1 1:1 2:-0.323308 3:-0.642857 5:0.0769231 7:-0.824561 8:1 9:1 10:-0.820896 11:-1 13:-1 14:-0.99266
95 | -1 1:-1 2:-0.867068 3:-0.285714 4:-1 5:0.538462 6:0.75 7:-0.988421 8:-1 9:-1 10:-1 11:-1 13:-0.66 14:-1
96 | +1 1:1 2:-0.774436 3:-0.892857 5:0.230769 6:-0.25 7:-0.894737 8:-1 9:-1 10:-1 11:-1 13:-0.85 14:-0.99984
97 | -1 1:-1 2:-0.243008 3:-0.881071 5:-0.230769 6:-0.25 7:-0.982456 8:-1 9:-1 10:-1 11:-1 13:-1 14:-0.9922
98 | -1 1:1 2:-0.456241 3:-0.997143 4:-1 5:-0.0769231 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-1 14:-1
99 | -1 1:-1 2:-0.892331 3:-0.321429 5:-0.230769 6:-0.25 7:-0.877193 8:-1 9:1 10:-0.701493 11:1 13:-1 14:-0.9998
100 | +1 1:-1 2:-0.799398 3:-0.940357 5:0.538462 6:-0.25 7:-0.888772 8:1 9:1 10:-0.970149 11:-1 13:-1 14:-1
101 | -1 1:-1 2:-0.238195 3:-0.714286 5:0.0769231 6:-0.25 7:-0.789474 8:-1 9:-1 10:-1 11:-1 13:-0.52 14:-1
102 | +1 1:1 2:-0.250526 3:-0.985 5:-0.538462 6:-0.25 7:-0.994035 8:1 9:-1 10:-1 11:1 13:-0.72 14:-1
103 | +1 1:1 2:-0.581353 3:-0.0178571 5:0.230769 6:-0.25 7:-0.596491 8:1 9:-1 10:-1 11:1 13:-0.513 14:-0.99
104 | +1 1:1 2:-0.578947 3:-0.958214 4:-1 5:0.846154 6:-0.25 7:-0.982456 8:1 9:1 10:-0.940299 11:-1 13:-0.74 14:-0.99
105 | -1 1:1 2:-0.842105 3:-1 4:-1 5:-1 6:-1 7:-1 8:-1 9:1 10:-0.880597 11:-1 13:-0.955 14:-0.99998
106 | +1 1:-1 2:-0.661654 3:-0.9375 5:1 6:0.75 7:-0.927018 8:1 9:-1 10:-1 11:1 13:-0.84 14:-0.8828
107 | +1 1:1 2:-0.581353 3:-0.857143 5:1 6:0.75 7:-0.929825 8:1 9:1 10:-0.880597 11:-1 13:-0.86 14:-0.84912
108 | -1 1:1 2:-0.744361 3:-0.357143 5:-0.230769 6:-0.25 7:-0.994035 8:-1 9:-1 10:-1 11:-1 13:-1 14:-1
109 | +1 1:-1 2:0.0851128 3:-0.0296429 5:-0.538462 6:0.75 7:-0.403509 8:1 9:-1 10:-1 11:1 13:-1 14:-1
110 | -1 1:1 2:-0.441203 3:-0.821429 5:0.0769231 6:-0.25 7:-0.912281 8:-1 9:-1 10:-1 11:1 13:-0.72 14:-1
111 | -1 1:1 2:-0.263158 3:-0.276786 4:-1 5:-0.538462 6:-0.25 7:-0.991228 8:-1 9:-1 10:-1 11:-1 13:-0.84 14:-1
112 | -1 1:1 2:0.00992487 3:-0.535714 5:0.0769231 6:-0.25 7:-0.929825 8:-1 9:-1 10:-1 11:1 13:-1 14:-0.99544
113 | -1 1:1 2:-0.576541 3:-0.714286 4:-1 5:-0.692308 6:0.75 7:-0.596491 8:1 9:1 10:-0.940299 11:1 13:-0.925 14:-1
114 | +1 1:-1 2:-0.338346 3:-0.934643 5:-0.230769 6:-0.25 7:-0.947368 8:1 9:1 10:-0.880597 11:-1 13:-1 14:-0.96834
115 | -1 1:1 2:-0.403609 3:-0.982143 5:-0.692308 7:-0.719298 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.58 14:-1
116 | +1 1:1 2:-0.388571 3:-0.994286 4:-1 5:-0.0769231 7:-0.997193 8:1 9:1 10:-0.970149 11:1 13:-0.72 14:-0.96
117 | +1 1:-1 2:-0.789474 3:-0.261786 5:0.846154 6:0.75 7:-0.976491 8:1 9:1 10:-0.970149 11:1 13:-0.92 14:-0.999
118 | +1 1:1 2:-0.41594 3:-0.928571 5:1 6:-0.25 7:-0.947368 8:1 9:1 10:-0.791045 11:1 13:-0.66 14:-0.91858
119 | +1 1:1 2:-0.729323 3:-0.214286 5:0.538462 6:-0.25 7:-0.824561 8:1 9:1 10:-0.791045 11:1 13:-0.9 14:-0.98382
120 | +1 1:1 2:0.0526316 3:-0.392857 5:0.0769231 6:0.75 7:-0.122807 8:1 9:1 10:-0.731343 11:-1 13:-0.819 14:-0.9669
121 | +1 1:1 2:-0.193083 3:-0.642857 5:0.0769231 6:-0.25 7:-0.649123 8:1 9:1 10:-0.791045 11:-1 13:-1 14:-0.9387
122 | -1 1:1 2:-0.79188 3:-0.940357 4:-1 5:0.0769231 6:-0.25 7:-0.859649 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.76 14:-1
123 | -1 1:-1 2:-0.24812 3:-0.892857 5:-1 6:-1 7:-1 8:-1 9:-1 10:-1 11:-1 13:-0.924 14:-1
124 | +1 1:-1 2:0.303158 3:0.392857 5:0.0769231 6:-0.25 7:-0.614035 8:1 9:1 10:-0.791045 11:-1 13:-1 14:-0.94
125 | +1 1:-1 2:-0.473684 3:-0.732143 5:0.846154 6:0.75 7:-0.95614 8:1 9:1 10:-0.731343 11:1 13:-0.819 14:-1
126 | -1 1:1 2:-0.75188 3:-0.943571 5:0.230769 6:-0.25 7:-0.979649 8:-1 9:1 10:-0.970149 11:-1 13:-0.58 14:-0.99434
127 | +1 1:-1 2:0.340752 3:-0.285714 5:0.538462 6:-0.25 7:-0.719298 8:1 9:1 10:-0.58209 11:-1 13:-1 14:-0.96796
128 | -1 1:1 2:-0.543759 3:-0.973214 5:0.0769231 6:-0.25 7:-0.979649 8:-1 9:-1 10:-1 11:-1 13:-0.78 14:-0.9972
129 | +1 1:-1 2:-0.0300752 3:-0.714286 5:-0.384615 6:-0.5 7:-1 8:1 9:-1 10:-1 11:-1 13:-0.9 14:-0.9808
130 | +1 1:1 2:-0.781955 3:-0.785714 4:-1 5:-0.846154 6:-0.25 7:-0.92386 8:1 9:1 10:-0.761194 11:1 13:-0.84 14:-0.99998
131 | +1 1:-1 2:-0.669173 3:-0.107143 5:-0.230769 6:-0.25 7:-0.894737 8:1 9:1 10:-0.641791 11:1 13:-0.88 14:-0.98866
132 | -1 1:-1 2:-0.787068 3:-0.964286 4:-1 5:0.384615 6:-0.75 7:-0.929825 8:-1 9:-1 10:-1 11:-1 13:-0.74 14:-1
133 | -1 1:1 2:-0.674286 3:-0.0357143 4:-1 5:-1 6:-1 7:-1 8:-1 9:-1 10:-1 11:-1 13:-0.816 14:-1
134 | -1 1:-1 2:-0.616541 3:-0.806429 4:-1 5:0.0769231 6:-0.25 7:-0.994035 8:-1 9:-1 10:-1 11:-1 12:-1 13:-0.92 14:-1
135 | -1 1:1 2:-0.182857 3:-0.940357 5:-1 6:-1 7:-1 8:1 9:-1 10:-1 11:-1 13:-0.87 14:-0.99998
136 | -1 1:-1 2:-0.260752 3:-0.684643 5:0.0769231 6:-0.25 7:-0.991228 8:-1 9:-1 10:-1 11:-1 13:-0.84 14:-1
137 | -1 1:1 2:-0.824662 3:-0.958214 5:-1 6:-1 7:-1 8:-1 9:1 10:-0.910448 11:-1 13:-0.65 14:-0.98462
138 | +1 1:1 2:-0.233083 3:-0.321429 5:-0.0769231 6:-0.25 7:-0.54386 8:1 9:1 10:-0.58209 11:-1 13:-0.76 14:-0.90786
139 | +1 1:1 2:-0.639098 3:-0.964286 5:0.0769231 6:-0.25 7:-0.897544 8:1 9:1 10:-0.850746 11:1 13:-0.688 14:-1
140 | +1 1:-1 2:-0.0276691 3:-0.785714 5:0.0769231 6:-0.25 7:-0.833333 8:1 9:1 10:-0.761194 11:1 13:-0.604 14:-0.91682
141 | -1 1:1 2:-0.821955 3:-0.285714 4:-1 5:-0.538462 6:0.75 7:-0.941404 8:1 9:-1 10:-1 11:1 13:-0.86 14:-1
142 | -1 1:-1 2:-0.744361 3:-0.910714 4:-1 5:-1 6:-1 7:-0.77193 8:-1 9:-1 10:-1 11:-1 13:-0.72 14:-1
143 | -1 1:1 2:-0.847218 3:-0.747143 4:-1 5:-1 6:-1 7:-1 8:-1 9:-1 10:-1 11:1 13:-0.82 14:-0.99998
144 | +1 1:1 2:0.513684 3:0.428571 5:1 6:0.75 7:0.22807 8:1 9:1 10:-0.731343 11:1 13:-1 14:-0.98
145 | -1 1:-1 2:-0.917293 3:-0.910714 5:0.538462 6:-0.25 7:-0.982456 8:-1 9:1 10:-0.970149 11:-1 13:-0.892 14:-0.99804
146 | +1 1:-1 2:0.651729 3:0.0714286 5:0.384615 6:1 7:-1 8:1 9:1 10:-0.58209 11:-1 13:-1 14:-0.93248
147 | +1 1:1 2:0.894737 3:0.592143 5:0.384615 6:1 7:-0.105263 8:1 9:1 10:-0.970149 11:1 13:-1 14:-0.99782
148 | -1 1:-1 2:-0.934737 3:-0.794643 5:0.538462 6:-0.25 7:-0.994035 8:-1 9:-1 10:-1 11:-1 13:-0.88 14:-1
149 | -1 1:1 2:-0.366015 3:-0.714286 5:-0.846154 7:-0.122807 8:1 9:-1 10:-1 11:1 13:-0.816 14:-1
150 | +1 1:-1 2:0.0126315 3:-0.428571 5:0.384615 7:-0.54386 8:1 9:1 10:-0.820896 11:-1 13:-0.625 14:0.022
151 | +1 1:1 2:-0.716692 3:-1 5:0.0769231 6:-0.25 7:-1 8:-1 9:-1 10:-1 11:-1 12:1 13:-0.816 14:-1
152 | -1 1:1 2:-0.0550377 3:-0.892857 5:0.0769231 6:-0.25 7:-0.824561 8:1 9:-1 10:-1 11:1 13:-0.86 14:-1
153 | -1 1:1 2:-0.957293 3:-0.5 5:0.384615 6:-0.25 7:-0.929825 8:-1 9:-1 10:-1 11:-1 13:-0.4 14:-1
154 | -1 1:1 2:-0.847218 3:-0.970357 4:-1 5:0.0769231 6:-0.25 7:-0.988421 8:-1 9:1 10:-0.970149 11:-1 13:-0.8 14:-0.99998
155 | +1 1:1 2:0.165414 3:-0.535714 5:-0.538462 6:-0.25 7:-0.558596 8:1 9:1 10:-0.552239 11:-1 13:-1 14:-0.77596
156 | +1 1:1 2:-0.836992 3:-1 4:-1 5:-0.0769231 7:-1 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.5 14:-0.99998
157 | +1 1:1 2:-0.87218 3:-0.988214 5:0.538462 6:0.5 7:-0.985263 8:-1 9:-1 10:-1 11:-1 13:-0.8 14:-0.9992
158 | -1 1:1 2:-0.285714 3:-0.940357 5:0.384615 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-0.88 14:-0.9999
159 | +1 1:1 2:-0.731729 3:-0.886786 4:-1 5:0.230769 6:-0.25 7:-0.783509 8:1 9:1 10:-0.820896 11:-1 13:-0.92 14:-1
160 | -1 1:1 2:0.0249625 3:-0.7025 5:1 7:-0.994035 8:-1 9:-1 10:-1 11:1 13:-0.48 14:-1
161 | -1 1:1 2:-0.388571 3:-0.821429 5:0.0769231 6:-0.25 7:-0.929825 8:-1 9:-1 10:-1 11:-1 13:-0.54 14:-0.99968
162 | -1 1:-1 2:-0.418647 3:-0.883929 5:-0.846154 6:-0.25 7:-0.962105 8:-1 9:-1 10:-1 11:1 13:-1 14:-1
163 | +1 1:1 2:-0.117895 3:-0.973214 4:-1 5:0.0769231 6:-0.25 7:-0.973684 8:1 9:1 10:-0.761194 11:1 13:-0.7 14:-0.99676
164 | +1 1:1 2:-0.37594 3:-0.711429 4:-1 5:-0.692308 7:-0.403509 8:1 9:1 10:-0.791045 11:1 13:-0.805 14:-1
165 | -1 1:1 2:-0.12782 3:-0.785714 5:-0.692308 7:-0.929825 8:1 9:-1 10:-1 11:-1 13:-1 14:-0.996
166 | -1 1:1 2:-0.864662 3:-0.988214 5:-0.846154 6:-0.25 7:-0.982456 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.72 14:-1
167 | -1 1:1 2:-0.719398 3:-0.821429 5:-1 6:-1 7:-0.994035 8:-1 9:-1 10:-1 11:1 13:-0.9 14:-0.91584
168 | +1 1:-1 2:-0.736842 3:-0.395714 4:-1 5:1 6:-0.25 7:-0.827368 8:-1 9:-1 10:-1 11:-1 13:-0.836 14:-1
169 | -1 1:1 2:-0.874586 3:-0.985357 5:-0.230769 6:-0.25 7:-0.997193 8:-1 9:-1 10:-1 11:-1 13:-0.72 14:-0.985
170 | -1 1:1 2:-0.859549 3:-0.256071 4:-1 5:-0.230769 6:-0.25 7:-0.991228 8:1 9:-1 10:-1 11:-1 13:-0.88 14:-0.9925
171 | -1 1:-1 2:-0.581353 3:-0.892857 5:-0.0769231 6:-0.25 7:-0.859649 8:1 9:-1 10:-1 11:-1 12:-1 13:-0.632 14:-1
172 | +1 1:-1 2:-0.844511 3:-0.339286 4:-1 5:0.0769231 6:-0.25 7:-0.929825 8:1 9:1 10:-0.880597 11:1 13:-0.92 14:-0.99
173 | -1 1:1 2:-0.731729 3:-0.946429 5:-0.692308 6:-0.25 7:-0.888772 8:-1 9:1 10:-0.970149 11:1 13:-0.6 14:-0.99982
174 | -1 1:1 2:0.466165 3:-0.0892857 4:-1 5:0.0769231 6:0.75 7:-0.649123 8:1 9:-1 10:-1 11:-1 13:-0.888 14:-1
175 | +1 1:-1 2:-0.706767 3:-0.357143 5:0.538462 6:-0.25 7:-0.403509 8:1 9:1 10:-0.850746 11:1 13:-0.88 14:-1
176 | -1 1:1 2:-0.353383 3:-0.773929 5:1 6:0.75 7:-0.736842 8:1 9:-1 10:-1 11:1 13:-0.32 14:-1
177 | -1 1:-1 2:0.295639 3:-0.696429 4:-1 5:-1 6:-1 7:-0.649123 8:-1 9:-1 10:-1 11:1 13:-1 14:-0.99992
178 | -1 1:-1 2:0.190376 3:-0.988214 5:-1 6:-1 7:-1 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.938 14:-0.99946
179 | +1 1:1 2:-0.175338 3:-0.711429 5:0.846154 6:0.75 7:-0.508772 8:1 9:1 10:-0.761194 11:-1 13:-0.68 14:-1
180 | +1 1:1 2:-0.145263 3:-0.64 5:0.538462 6:0.75 7:-0.105263 8:1 9:-1 10:-1 11:1 13:-0.908 14:-1
181 | -1 1:1 2:-0.175338 3:-0.910714 4:-1 5:0.230769 6:-0.25 7:-0.982456 8:-1 9:-1 10:-1 11:-1 13:-1 14:-0.9961
182 | -1 1:-1 2:-0.398496 3:-0.946429 5:-0.538462 7:-0.929825 8:1 9:1 10:-0.910448 11:1 13:-0.788 14:-1
183 | +1 1:1 2:-0.641504 3:-0.107143 5:0.846154 6:-0.25 7:-0.915088 8:1 9:1 10:1 11:1 13:-0.86 14:-0.99484
184 | +1 1:1 2:-0.681805 3:-0.526786 4:-1 5:-0.846154 6:-0.25 7:-0.614035 8:1 9:-1 10:-1 11:1 12:-1 13:-0.9 14:-1
185 | +1 1:1 2:-0.71188 3:-0.169643 4:-1 5:0.230769 6:-0.25 7:-0.941404 8:1 9:-1 10:-1 11:1 13:-0.84 14:-0.994
186 | -1 1:1 2:-0.491128 3:-0.821429 5:0.846154 6:0.75 7:-0.842105 8:-1 9:-1 10:-1 11:1 12:-1 13:-0.66 14:-1
187 | -1 1:1 2:-0.295639 3:-0.714286 5:0.0769231 7:-0.649123 8:1 9:-1 10:-1 11:1 12:-1 13:-0.72 14:-1
--------------------------------------------------------------------------------
/svm.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 / svm |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 2010 Ian Barber |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.0 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_0.txt. |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Authors: Ian Barber |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | #include "php_svm.h"
20 | #include "php_ini.h" /* needed for 5.2 */
21 | #include "Zend/zend_exceptions.h"
22 | #include "ext/standard/info.h"
23 |
24 | zend_class_entry *php_svm_sc_entry;
25 | zend_class_entry *php_svm_model_sc_entry;
26 | zend_class_entry *php_svm_exception_sc_entry;
27 |
28 | static zend_object_handlers svm_object_handlers;
29 | static zend_object_handlers svm_model_object_handlers;
30 |
31 | #define SVM_MAX_LINE_SIZE 4096
32 | #define SVM_THROW(message, code) \
33 | zend_throw_exception(php_svm_exception_sc_entry, message, (long)code TSRMLS_CC); \
34 | return;
35 |
36 | #define SVM_THROW_LAST_ERROR(fallback, code) \
37 | zend_throw_exception(php_svm_exception_sc_entry, (strlen(intern->last_error) ? intern->last_error : fallback), (long)code TSRMLS_CC); \
38 | memset(intern->last_error, 0, 512); \
39 | return;
40 |
41 | ZEND_DECLARE_MODULE_GLOBALS(svm);
42 |
43 | #define SVM_SET_ERROR_MSG(intern, ...) snprintf(intern->last_error, 512, __VA_ARGS__);
44 |
45 | typedef enum SvmLongAttribute {
46 | SvmLongAttributeMin = 100,
47 | phpsvm_svm_type,
48 | phpsvm_kernel_type,
49 | phpsvm_degree,
50 | phpsvm_shrinking,
51 | phpsvm_probability,
52 | SvmLongAttributeMax /* Always add before this */
53 | } SvmLongAttribute;
54 |
55 | typedef enum SvmDoubleAttribute {
56 | SvmDoubleAttributeMin = 200,
57 | phpsvm_gamma,
58 | phpsvm_nu,
59 | phpsvm_eps,
60 | phpsvm_p,
61 | phpsvm_coef0,
62 | phpsvm_C,
63 | phpsvm_cache_size,
64 | phpsvm_weight,
65 | SvmDoubleAttributeMax /* Always add before this */
66 | } SvmDoubleAttribute;
67 |
68 | /* ---- START HELPER FUNCS ---- */
69 |
70 | void print_null(const char *s) {}
71 |
72 | static zend_bool php_svm_set_double_attribute(php_svm_object *intern, SvmDoubleAttribute name, double value)
73 | {
74 | if (name >= SvmDoubleAttributeMax) {
75 | return 0;
76 | }
77 |
78 | switch (name) {
79 | case phpsvm_gamma:
80 | intern->param.gamma = value;
81 | break;
82 | case phpsvm_nu:
83 | intern->param.nu = value;
84 | break;
85 | case phpsvm_eps:
86 | intern->param.eps = value;
87 | break;
88 | case phpsvm_cache_size:
89 | intern->param.cache_size = value;
90 | break;
91 | case phpsvm_p:
92 | intern->param.p = value;
93 | break;
94 | case phpsvm_coef0:
95 | intern->param.coef0 = value;
96 | break;
97 | case phpsvm_C:
98 | intern->param.C = value;
99 | break;
100 | case phpsvm_weight:
101 | /* Pointer */
102 | intern->param.weight = &value;
103 | break;
104 | default:
105 | return 0;
106 | }
107 |
108 | return 1;
109 | }
110 |
111 | static zend_bool php_svm_set_long_attribute(php_svm_object *intern, SvmLongAttribute name, long value)
112 | {
113 | if (name >= SvmLongAttributeMax) {
114 | return 0;
115 | }
116 |
117 | switch (name) {
118 | case phpsvm_svm_type:
119 | if( value != C_SVC &&
120 | value != NU_SVC &&
121 | value != ONE_CLASS &&
122 | value != EPSILON_SVR &&
123 | value != NU_SVR ) {
124 | return 0;
125 | }
126 | intern->param.svm_type = (int)value;
127 | break;
128 | case phpsvm_kernel_type:
129 | if( value != LINEAR &&
130 | value != POLY &&
131 | value != RBF &&
132 | value != SIGMOID &&
133 | value != PRECOMPUTED ) {
134 | return 0;
135 | }
136 | intern->param.kernel_type = (int)value;
137 | break;
138 | case phpsvm_degree:
139 | intern->param.degree = (int)value;
140 | break;
141 | case phpsvm_shrinking:
142 | intern->param.shrinking = value;
143 | break;
144 | case phpsvm_probability:
145 | intern->param.probability = value;
146 | break;
147 | default:
148 | return 0;
149 | }
150 |
151 | return 1;
152 | }
153 |
154 | /** {{{ zend_bool php_svm_stream_to_array(php_svm_object *intern, php_stream *stream, zval *retval TSRMLS_DC)
155 | Take a stream containing lines of SVMLight format data and convert them into a PHP array for use by the training
156 | function.
157 | */
158 | static zend_bool php_svm_stream_to_array(php_svm_object *intern, php_stream *stream, zval *retval TSRMLS_DC)
159 | {
160 | while (!php_stream_eof(stream)) {
161 | char buf[SVM_MAX_LINE_SIZE];
162 | size_t retlen = 0;
163 | int line = 1;
164 |
165 | /* Read line by line */
166 | if (php_stream_get_line(stream, buf, SVM_MAX_LINE_SIZE, &retlen)) {
167 |
168 | zval *line_array, *pz_label;
169 | char *label, *ptr, *l = NULL;
170 |
171 | ptr = buf;
172 | label = php_strtok_r(ptr, " \t", &l);
173 |
174 | if (!label) {
175 | SVM_SET_ERROR_MSG(intern, "Incorrect data format on line %d", line);
176 | return 0;
177 | }
178 |
179 | /* The line array */
180 | MAKE_STD_ZVAL(line_array);
181 | array_init(line_array);
182 |
183 | /* The label */
184 | MAKE_STD_ZVAL(pz_label);
185 | ZVAL_STRING(pz_label, label, 1);
186 | convert_to_double(pz_label);
187 |
188 | /* Label is the first item in the line array */
189 | add_next_index_zval(line_array, pz_label);
190 |
191 | /* Read rest of the values on the line */
192 | while (1) {
193 | char *idx, *value;
194 | zval *pz_idx, *pz_value;
195 |
196 | /* idx:value format */
197 | idx = php_strtok_r(NULL, ":", &l);
198 | value = php_strtok_r(NULL, " \t", &l);
199 |
200 | if (!value)
201 | break;
202 |
203 | /* Make zvals and convert to correct types */
204 | MAKE_STD_ZVAL(pz_idx);
205 | ZVAL_STRING(pz_idx, idx, 1);
206 | convert_to_long(pz_idx);
207 |
208 | MAKE_STD_ZVAL(pz_value);
209 | ZVAL_STRING(pz_value, value, 1);
210 | convert_to_double(pz_value);
211 |
212 | add_index_zval(line_array, Z_LVAL_P(pz_idx), pz_value);
213 | zval_dtor(pz_idx);
214 | FREE_ZVAL(pz_idx);
215 | }
216 | add_next_index_zval(retval, line_array);
217 | line++;
218 | }
219 | }
220 | return 1;
221 | }
222 | /* }}} */
223 |
224 |
225 | /* {{{ int _php_count_values(zval *array);
226 | For a an array of arrays, count the number of items in all subarrays.
227 | */
228 | static int _php_count_values(zval *array)
229 | {
230 | zval **ppzval;
231 | int values = 0;
232 |
233 | for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(array));
234 | zend_hash_get_current_data(Z_ARRVAL_P(array), (void **) &ppzval) == SUCCESS;
235 | zend_hash_move_forward(Z_ARRVAL_P(array))) {
236 |
237 | if (Z_TYPE_PP(ppzval) == IS_ARRAY)
238 | values += zend_hash_num_elements(Z_ARRVAL_PP(ppzval));
239 | }
240 | return values;
241 | }
242 | /* }}} */
243 |
244 | /* {{{ static void php_svm_free_problem(struct svm_problem *problem) {
245 | Free the generated problem.
246 | */
247 | static void php_svm_free_problem(struct svm_problem *problem) {
248 | if (problem->x)
249 | efree(problem->x);
250 |
251 | if (problem->y)
252 | efree(problem->y);
253 |
254 | if (problem)
255 | efree(problem);
256 | }
257 | /* }}} */
258 |
259 | /* {{{ static zend_bool php_svm_read_array(php_svm_object *intern, php_svm_model_object *intern_model, zval *array TSRMLS_DC)
260 | Take a PHP array, and prepare libSVM problem data for training with.
261 | */
262 | static struct svm_problem* php_svm_read_array(php_svm_object *intern, php_svm_model_object *intern_model, zval *array TSRMLS_DC)
263 | {
264 | zval **ppzval;
265 |
266 | char *err_msg = NULL;
267 | char *key;
268 | char *endptr;
269 | int i, j = 0, num_labels, elements, max_index = 0, inst_max_index = 0, key_len;
270 | long index;
271 | struct svm_problem *problem;
272 | HashPosition pointer;
273 |
274 | /* If reading multiple times make sure that we don't leak */
275 | if (intern_model->x_space) {
276 | efree(intern_model->x_space);
277 | intern_model->x_space = NULL;
278 | }
279 |
280 | if (intern_model->model) {
281 | svm_destroy_model(intern_model->model);
282 | intern_model->model = NULL;
283 | }
284 |
285 | /* Allocate the problem */
286 | problem = emalloc(sizeof(struct svm_problem));
287 |
288 | /* x and y */
289 | num_labels = zend_hash_num_elements(HASH_OF(array));
290 |
291 | /* Allocate space for the labels */
292 | problem->y = emalloc(num_labels * sizeof(double));
293 |
294 | /* allocate space for x */
295 | problem->x = emalloc(num_labels * sizeof(struct svm_node *));
296 |
297 | /* total number of elements */
298 | elements = _php_count_values(array);
299 |
300 | /* Allocate space: because the original array contains labels the alloc
301 | should match as we add additional -1 node in the loop */
302 | intern_model->x_space = emalloc(elements * sizeof(struct svm_node));
303 |
304 | /* How many labels */
305 | problem->l = num_labels;
306 |
307 | /* Fill the problem */
308 | for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(array)), i = 0;
309 | zend_hash_get_current_data(Z_ARRVAL_P(array), (void **) &ppzval) == SUCCESS;
310 | zend_hash_move_forward(Z_ARRVAL_P(array)), i++) {
311 |
312 | zval **ppz_label;
313 |
314 | if (Z_TYPE_PP(ppzval) != IS_ARRAY) {
315 | err_msg = "Data format error";
316 | goto return_error;
317 | }
318 |
319 | if (zend_hash_num_elements(Z_ARRVAL_PP(ppzval)) < 2) {
320 | err_msg = "Wrong amount of nodes in the sub-array";
321 | goto return_error;
322 | }
323 |
324 | problem->x[i] = &(intern_model->x_space[j]);
325 |
326 | zend_hash_internal_pointer_reset(Z_ARRVAL_PP(ppzval));
327 |
328 | if ((zend_hash_get_current_data(Z_ARRVAL_PP(ppzval), (void **) &ppz_label) == SUCCESS)) {
329 |
330 | if (Z_TYPE_PP(ppz_label) != IS_DOUBLE) {
331 | convert_to_double(*ppz_label);
332 | }
333 | problem->y[i] = Z_DVAL_PP(ppz_label);
334 | } else {
335 | err_msg = "The sub-array contains only the label. Missing index-value pairs";
336 | goto return_error;
337 | }
338 |
339 | while (1) {
340 | zval **ppz_value;
341 |
342 | if ((zend_hash_move_forward(Z_ARRVAL_PP(ppzval)) == SUCCESS) &&
343 | (zend_hash_get_current_data(Z_ARRVAL_PP(ppzval), (void **) &ppz_value) == SUCCESS)) {
344 |
345 | if (zend_hash_get_current_key(Z_ARRVAL_PP(ppzval), &key, &index, 0) == HASH_KEY_IS_STRING) {
346 | intern_model->x_space[j].index = (int) strtol(key, &endptr, 10);
347 | } else {
348 | intern_model->x_space[j].index = (int) index;
349 | }
350 |
351 | if (Z_TYPE_PP(ppz_value) != IS_DOUBLE) {
352 | convert_to_double(*ppz_value);
353 | }
354 | intern_model->x_space[j].value = Z_DVAL_PP(ppz_value);
355 |
356 | inst_max_index = intern_model->x_space[j].index;
357 | j++;
358 | } else {
359 | break;
360 | }
361 | }
362 |
363 | intern_model->x_space[j++].index = -1;
364 |
365 | if (inst_max_index > max_index) {
366 | max_index = inst_max_index;
367 | }
368 | }
369 |
370 | if (intern->param.gamma == 0 && max_index > 0) {
371 | intern->param.gamma = 1.0/max_index;
372 | }
373 |
374 | return problem;
375 |
376 | return_error:
377 | php_svm_free_problem(problem);
378 | if (err_msg) {
379 | SVM_SET_ERROR_MSG(intern, err_msg);
380 | }
381 |
382 | return NULL;
383 | }
384 | /* }}} */
385 |
386 | /* {{{ static zend_bool php_svm_train(php_svm_object *intern, php_svm_model_object *intern_model, struct svm_problem *problem)
387 | Train based on a libsvm problem structure
388 | */
389 | static zend_bool php_svm_train(php_svm_object *intern, php_svm_model_object *intern_model, struct svm_problem *problem)
390 | {
391 | char *err_msg = NULL;
392 | err_msg = svm_check_parameter(problem, &(intern->param));
393 | if (err_msg) {
394 | SVM_SET_ERROR_MSG(intern, err_msg);
395 | return 0;
396 | }
397 |
398 | intern_model->model = svm_train(problem, &(intern->param));
399 |
400 | /* Failure ? */
401 | if (!intern_model->model) {
402 | SVM_SET_ERROR_MSG(intern, "Failed to train using the data");
403 | return 0;
404 | }
405 |
406 | return 1;
407 | }
408 | /* }}} */
409 |
410 | /* {{{ static zval* php_svm_get_data_from_param(php_svm_object *intern, zval *zparam)
411 | Take an incoming parameter and convert it into a PHP array of svmlight style data.
412 | */
413 | static zval* php_svm_get_data_from_param(php_svm_object *intern, zval *zparam TSRMLS_DC)
414 | {
415 | zval *data, *return_value;
416 | zend_bool our_stream = 0;
417 | zend_bool need_read = 1;
418 | php_stream *stream = NULL;
419 |
420 | switch (Z_TYPE_P(zparam)) {
421 | case IS_STRING:
422 | stream = php_stream_open_wrapper(Z_STRVAL_P(zparam), "r", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
423 | our_stream = 1;
424 | break;
425 |
426 | case IS_RESOURCE:
427 | php_stream_from_zval(stream, &zparam);
428 | our_stream = 0;
429 | break;
430 |
431 | case IS_ARRAY:
432 | our_stream = 0;
433 | need_read = 0;
434 | break;
435 |
436 | default:
437 | SVM_SET_ERROR_MSG(intern, "Incorrect parameter type, expecting string, stream or an array");
438 | return 0;
439 | break;
440 | }
441 |
442 | /* If we got stream then read it in */
443 | if (need_read) {
444 | if (!stream) {
445 | SVM_SET_ERROR_MSG(intern, "Failed to open the data file");
446 | return 0;
447 | }
448 |
449 | MAKE_STD_ZVAL(data);
450 | array_init(data);
451 |
452 | if (!php_svm_stream_to_array(intern, stream, data TSRMLS_CC)) {
453 | zval_dtor(data);
454 | FREE_ZVAL(data);
455 | if (our_stream) {
456 | php_stream_close(stream);
457 | }
458 | SVM_SET_ERROR_MSG(intern, "Failed to read the data");
459 | return 0;
460 | }
461 | } else {
462 | data = zparam;
463 | }
464 |
465 | if (our_stream) {
466 | php_stream_close(stream);
467 | }
468 |
469 | return data;
470 | }
471 | /* }}} */
472 |
473 | /* ---- END HELPER FUNCS ---- */
474 |
475 |
476 |
477 | /* ---- START SVM ---- */
478 |
479 | /* {{{ SVM SVM::__construct();
480 | The constructor
481 | */
482 | PHP_METHOD(svm, __construct)
483 | {
484 | php_svm_object *intern;
485 |
486 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
487 | return;
488 | }
489 |
490 | intern = (php_svm_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
491 |
492 | /* Setup the default parameters to match those in libsvm's svm_train */
493 | php_svm_set_long_attribute(intern, phpsvm_svm_type, C_SVC);
494 | php_svm_set_long_attribute(intern, phpsvm_kernel_type, RBF);
495 | php_svm_set_long_attribute(intern, phpsvm_degree, 3);
496 | php_svm_set_double_attribute(intern, phpsvm_gamma, 0);
497 | php_svm_set_double_attribute(intern, phpsvm_coef0, 0);
498 | php_svm_set_double_attribute(intern, phpsvm_nu, 0.5);
499 | php_svm_set_double_attribute(intern, phpsvm_cache_size, 100.0);
500 | php_svm_set_double_attribute(intern, phpsvm_C, 1);
501 | php_svm_set_double_attribute(intern, phpsvm_eps, 1e-3);
502 | php_svm_set_double_attribute(intern, phpsvm_p, 0.1);
503 | php_svm_set_long_attribute(intern, phpsvm_shrinking, 1);
504 | php_svm_set_long_attribute(intern, phpsvm_probability, 0);
505 |
506 | return;
507 | }
508 | /* }}} */
509 |
510 | /* {{{ array SVM::getOptions();
511 | Get training parameters, in an array.
512 | */
513 | PHP_METHOD(svm, getOptions)
514 | {
515 | php_svm_object *intern;
516 | intern = zend_object_store_get_object(getThis() TSRMLS_CC);
517 |
518 | array_init(return_value);
519 |
520 | add_index_long(return_value, phpsvm_svm_type, intern->param.svm_type);
521 | add_index_long(return_value, phpsvm_kernel_type, intern->param.kernel_type);
522 | add_index_long(return_value, phpsvm_degree, intern->param.degree);
523 | add_index_long(return_value, phpsvm_coef0, intern->param.shrinking);
524 | add_index_long(return_value, phpsvm_probability, intern->param.probability);
525 |
526 | add_index_long(return_value, phpsvm_gamma, intern->param.gamma);
527 | add_index_long(return_value, phpsvm_coef0, intern->param.coef0);
528 | add_index_long(return_value, phpsvm_nu, intern->param.nu);
529 | add_index_long(return_value, phpsvm_cache_size, intern->param.cache_size);
530 | add_index_long(return_value, phpsvm_C, intern->param.C);
531 | add_index_long(return_value, phpsvm_eps, intern->param.eps);
532 | add_index_long(return_value, phpsvm_p, intern->param.p);
533 | }
534 | /* }}} */
535 |
536 |
537 | /* {{{ int SVM::setOptopms(array params);
538 | Takes an array of parameters and sets the training options to match them.
539 | Only used by the training functions, will not modify an existing model.
540 | */
541 | PHP_METHOD(svm, setOptions)
542 | {
543 | HashTable *params_ht;
544 | php_svm_object *intern;
545 | zval *params, **ppzval;
546 | char *string_key = NULL;
547 | ulong num_key;
548 |
549 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", ¶ms) == FAILURE) {
550 | RETURN_FALSE;
551 | }
552 |
553 | params_ht = HASH_OF(params);
554 |
555 | if (zend_hash_num_elements(params_ht) == 0) {
556 | return;
557 | }
558 |
559 | intern = (php_svm_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
560 |
561 | for (zend_hash_internal_pointer_reset(params_ht);
562 | zend_hash_get_current_data(params_ht, (void **) &ppzval) == SUCCESS;
563 | zend_hash_move_forward(params_ht)) {
564 |
565 | zval tmp_zval, *tmp_pzval;
566 |
567 | if (zend_hash_get_current_key(params_ht, &string_key, &num_key, 1) != HASH_KEY_IS_LONG) {
568 | continue; /* Ignore the arg (TODO: throw exception?) */
569 | }
570 |
571 | /* Make sure we don't modify the original array */
572 | tmp_zval = **ppzval;
573 | zval_copy_ctor(&tmp_zval);
574 | tmp_pzval = &tmp_zval;
575 |
576 | /* Long attribute */
577 | if (num_key > SvmLongAttributeMin && num_key < SvmLongAttributeMax) {
578 |
579 | if (Z_TYPE_P(tmp_pzval) != IS_LONG) {
580 | convert_to_long(tmp_pzval);
581 | }
582 |
583 | if (!php_svm_set_long_attribute(intern, num_key, Z_LVAL_P(tmp_pzval))) {
584 | SVM_THROW("Failed to set the attribute", 999);
585 | }
586 |
587 | /* Double attribute */
588 | } else if (num_key > SvmDoubleAttributeMin && num_key < SvmDoubleAttributeMax) {
589 |
590 | if (Z_TYPE_P(tmp_pzval) != IS_DOUBLE) {
591 | convert_to_double(tmp_pzval);
592 | }
593 |
594 | if (!php_svm_set_double_attribute(intern, num_key, Z_DVAL_P(tmp_pzval))) {
595 | SVM_THROW("Failed to set the attribute", 999);
596 | }
597 |
598 | } else {
599 | continue; /* Ignore the arg (TODO: throw exception?) */
600 | }
601 |
602 | tmp_pzval = NULL;
603 | }
604 |
605 | RETURN_TRUE;
606 | }
607 | /* }}} */
608 |
609 | /* {{{ double SVM::crossvalidate(mixed string|resource|array, long folds);
610 | Cross validate a the SVM parameters on the training data for tuning parameters. Will attempt to train then classify
611 | on different segments of the training data (the total number of segments is the folds parameter). The training data
612 | can be supplied as with the train function. For SVM classification, this will we return the correct percentage,
613 | for regression the mean squared error.
614 | @throws SVMException if the data format is incorrect
615 | */
616 | PHP_METHOD(svm, crossvalidate)
617 | {
618 | int i;
619 | int total_correct = 0;
620 | long nrfolds;
621 | double total_error = 0;
622 | double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
623 | struct svm_problem *problem;
624 | double returnval = 0.0;
625 | double *target;
626 | php_svm_object *intern;
627 | php_svm_model_object *intern_return;
628 | zval *zparam, *data, *zcount, *tempobj;
629 |
630 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &zparam, &nrfolds) == FAILURE) {
631 | return;
632 | }
633 |
634 | intern = (php_svm_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
635 |
636 | ALLOC_INIT_ZVAL(tempobj);
637 | object_init_ex(tempobj, php_svm_model_sc_entry);
638 | intern_return = (php_svm_model_object *)zend_object_store_get_object(tempobj TSRMLS_CC);
639 |
640 | data = php_svm_get_data_from_param(intern, zparam TSRMLS_CC);
641 | if(!data) {
642 | SVM_THROW_LAST_ERROR("Could not load data", 234);
643 | }
644 | problem = php_svm_read_array(intern, intern_return, data TSRMLS_CC);
645 | if(!problem) {
646 | SVM_THROW_LAST_ERROR("Cross validation failed", 1001);
647 | }
648 |
649 | target = emalloc(problem->l * sizeof(double));
650 | svm_cross_validation(problem, &(intern->param), nrfolds, target);
651 | if(intern->param.svm_type == EPSILON_SVR || intern->param.svm_type == NU_SVR) {
652 | for(i=0;il;i++) {
653 | double y = problem->y[i];
654 | double v = target[i];
655 | total_error += (v-y)*(v-y);
656 | sumv += v;
657 | sumy += y;
658 | sumvv += v*v;
659 | sumyy += y*y;
660 | sumvy += v*y;
661 | }
662 | returnval = (total_error/problem->l); // return total_error divded by number of examples
663 | } else {
664 | for(i=0; il; i++) {
665 | if(target[i] == problem->y[i]) {
666 | ++total_correct;
667 | }
668 | }
669 | returnval = 1.0*total_correct/problem->l;
670 | }
671 |
672 | if (data != zparam) {
673 | zval_dtor(data);
674 | FREE_ZVAL(data);
675 | }
676 | zval_dtor(tempobj);
677 | FREE_ZVAL(tempobj);
678 | efree(target);
679 | php_svm_free_problem(problem);
680 |
681 | RETURN_DOUBLE(returnval);
682 | }
683 | /* }}} */
684 |
685 | /* {{{ SVMModel SVM::train(mixed string|resource|array, [array classWeights]);
686 | Train a SVM based on the SVMLight format data either in a file, an array, or in a previously opened stream.
687 | @throws SVMException if the data format is incorrect. Can optionally accept a set of weights that will
688 | be used to multiply C. Only useful for C_SVC kernels. These should be in the form array(class (int) => weight (float))
689 | */
690 | PHP_METHOD(svm, train)
691 | {
692 | php_svm_object *intern;
693 | php_svm_model_object *intern_return;
694 | struct svm_problem *problem;
695 | zval *data, *zparam, *retval, *weights, **ppzval;
696 | HashTable *weights_ht;
697 | int i;
698 | char *key;
699 | long index;
700 |
701 | zend_bool status = 0;
702 | weights = 0;
703 |
704 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a!", &zparam, &weights) == FAILURE) {
705 | return;
706 | }
707 |
708 | intern = (php_svm_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
709 | if(weights && intern->param.svm_type != C_SVC) {
710 | SVM_THROW("Weights can only be supplied for C_SVC training", 424);
711 | }
712 |
713 | data = php_svm_get_data_from_param(intern, zparam TSRMLS_CC);
714 | if(!data) {
715 | SVM_THROW_LAST_ERROR("Could not load data", 234);
716 | }
717 |
718 | if(weights) {
719 | weights_ht = Z_ARRVAL_P(weights);
720 | if(zend_hash_num_elements(weights_ht) > 0) {
721 | intern->param.nr_weight = zend_hash_num_elements(weights_ht);
722 | intern->param.weight_label = emalloc(intern->param.nr_weight * sizeof(int));
723 | intern->param.weight = emalloc(intern->param.nr_weight * sizeof(double));
724 |
725 | for (zend_hash_internal_pointer_reset(weights_ht), i = 0;
726 | zend_hash_get_current_data(weights_ht, (void **) &ppzval) == SUCCESS;
727 | zend_hash_move_forward(weights_ht), i++) {
728 |
729 | zval tmp_zval, *tmp_pzval;
730 |
731 | if (zend_hash_get_current_key(weights_ht, &key, &index, 0) == HASH_KEY_IS_LONG) {
732 | intern->param.weight_label[i] = (int)index;
733 |
734 | /* Make sure we don't modify the original array */
735 | tmp_zval = **ppzval;
736 | zval_copy_ctor(&tmp_zval);
737 | tmp_pzval = &tmp_zval;
738 | convert_to_double(tmp_pzval);
739 | intern->param.weight[i] = Z_DVAL_P(tmp_pzval);
740 | tmp_pzval = NULL;
741 | }
742 | }
743 | }
744 | }
745 |
746 | /* Return an object */
747 | object_init_ex(return_value, php_svm_model_sc_entry);
748 | intern_return = (php_svm_model_object *)zend_object_store_get_object(return_value TSRMLS_CC);
749 |
750 | problem = php_svm_read_array(intern, intern_return, data TSRMLS_CC);
751 | if(problem != NULL) {
752 | if (php_svm_train(intern, intern_return, problem)) {
753 | status = 1;
754 | }
755 | php_svm_free_problem(problem);
756 | }
757 |
758 | if(weights) {
759 | efree(intern->param.weight_label);
760 | efree(intern->param.weight);
761 | }
762 |
763 | if (data != zparam) {
764 | zval_dtor(data);
765 | FREE_ZVAL(data);
766 | }
767 |
768 | if (!status) {
769 | SVM_THROW_LAST_ERROR("Training failed", 1000);
770 | }
771 | return;
772 | }
773 | /* }}} */
774 |
775 | /* ---- END SVM ---- */
776 |
777 | /* ---- START SVMMODEL ---- */
778 |
779 | /** {{{ SvmModel::__construct([string filename])
780 | Constructs an svm model
781 | */
782 | PHP_METHOD(svmmodel, __construct)
783 | {
784 | php_svm_model_object *intern;
785 | char *filename = NULL;
786 | int filename_len;
787 |
788 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &filename, &filename_len) == FAILURE) {
789 | return;
790 | }
791 |
792 | if (!filename)
793 | return;
794 |
795 | intern = (php_svm_model_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
796 | intern->model = svm_load_model(filename);
797 |
798 | if (!intern->model) {
799 | SVM_THROW("Failed to load the model", 1233);
800 | }
801 |
802 | return;
803 | }
804 | /* }}} */
805 |
806 | /** {{{ SvmModel::load(string filename)
807 | Loads the svm model from a file
808 | */
809 | PHP_METHOD(svmmodel, load)
810 | {
811 | php_svm_model_object *intern;
812 | char *filename = NULL;
813 | int filename_len;
814 |
815 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
816 | return;
817 | }
818 |
819 | intern = (php_svm_model_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
820 | intern->model = svm_load_model(filename);
821 |
822 | if (!intern->model) {
823 | SVM_THROW("Failed to load the model", 1233);
824 | }
825 |
826 | RETURN_TRUE;
827 | }
828 | /* }}} */
829 |
830 | /** {{{ SvmModel::save(string filename)
831 | Saves the svm model to a file
832 | */
833 | PHP_METHOD(svmmodel, save)
834 | {
835 | php_svm_model_object *intern;
836 | char *filename;
837 | int filename_len;
838 |
839 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
840 | return;
841 | }
842 |
843 | intern = (php_svm_model_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
844 |
845 | if (!intern->model) {
846 | SVM_THROW("The object does not contain a model", 2321);
847 | }
848 |
849 | if (svm_save_model(filename, intern->model) != 0) {
850 | SVM_THROW("Failed to save the model", 121);
851 | }
852 |
853 | RETURN_TRUE;
854 | }
855 | /* }}} */
856 |
857 | /** {{{ SvmModel::predict(array data)
858 | Predicts based on the model
859 | */
860 | PHP_METHOD(svmmodel, predict)
861 | {
862 | php_svm_model_object *intern;
863 | double predict_label;
864 | struct svm_node *x;
865 | int max_nr_attr = 64;
866 | zval *arr, **data;
867 | HashTable *arr_hash;
868 | HashPosition pointer;
869 | int array_count, i;
870 | char *endptr;
871 |
872 | /* we want an array of data to be passed in */
873 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
874 | return;
875 | }
876 |
877 | arr_hash = Z_ARRVAL_P(arr);
878 | array_count = zend_hash_num_elements(arr_hash);
879 | intern = (php_svm_model_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
880 | if(!intern->model) {
881 | SVM_THROW("No model available to classify with", 106);
882 | }
883 |
884 | /* need 1 extra to indicate the end */
885 | x = emalloc((array_count + 1) *sizeof(struct svm_node));
886 |
887 | i = 0;
888 | zval temp;
889 | char *key;
890 | uint key_len;
891 | ulong index;
892 |
893 | /* Loop over the array in the argument and convert into svm_nodes for the prediction */
894 | for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
895 | zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS;
896 | zend_hash_move_forward_ex(arr_hash, &pointer))
897 | {
898 | if (zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) {
899 | x[i].index = (int) strtol(key, &endptr, 10);
900 | } else {
901 | x[i].index = (int) index;
902 | }
903 | temp = **data;
904 | zval_copy_ctor(&temp);
905 | convert_to_double(&temp);
906 | x[i].value = Z_DVAL(temp);
907 | zval_dtor(&temp);
908 | i++;
909 | }
910 | /* needed so the predictor knows when to end */
911 | x[i].index = -1;
912 |
913 | predict_label = svm_predict(intern->model, x);
914 | efree(x);
915 |
916 | RETURN_DOUBLE(predict_label);
917 | }
918 | /* }}} */
919 |
920 | /* ---- END SVMMODEL ---- */
921 |
922 | static void php_svm_init_globals(zend_svm_globals *svm_globals)
923 | {
924 | /* No globals */
925 | }
926 |
927 | static void php_svm_object_free_storage(void *object TSRMLS_DC)
928 | {
929 | php_svm_object *intern = (php_svm_object *)object;
930 |
931 | if (!intern) {
932 | return;
933 | }
934 |
935 | zend_object_std_dtor(&intern->zo TSRMLS_CC);
936 | efree(intern);
937 | }
938 |
939 | static zend_object_value php_svm_object_new_ex(zend_class_entry *class_type, php_svm_object **ptr TSRMLS_DC)
940 | {
941 | zval *tmp;
942 | zend_object_value retval;
943 | php_svm_object *intern;
944 |
945 | /* Allocate memory for the internal structure */
946 | intern = (php_svm_object *) emalloc(sizeof(php_svm_object));
947 | memset(&intern->zo, 0, sizeof(zend_object));
948 |
949 | if (ptr) {
950 | *ptr = intern;
951 | }
952 |
953 | /* Null model by default */
954 | memset(intern->last_error, 0, 512);
955 |
956 | zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
957 | zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *));
958 |
959 | retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_svm_object_free_storage, NULL TSRMLS_CC);
960 | retval.handlers = (zend_object_handlers *) &svm_object_handlers;
961 | return retval;
962 | }
963 |
964 | static zend_object_value php_svm_object_new(zend_class_entry *class_type TSRMLS_DC)
965 | {
966 | return php_svm_object_new_ex(class_type, NULL TSRMLS_CC);
967 | }
968 |
969 | static void php_svm_model_object_free_storage(void *object TSRMLS_DC)
970 | {
971 | php_svm_model_object *intern = (php_svm_model_object *)object;
972 |
973 | if (!intern) {
974 | return;
975 | }
976 |
977 | if (intern->model) {
978 | svm_destroy_model(intern->model);
979 | intern->model = NULL;
980 | }
981 |
982 | if (intern->x_space) {
983 | efree(intern->x_space);
984 | intern->x_space = NULL;
985 | }
986 |
987 | zend_object_std_dtor(&intern->zo TSRMLS_CC);
988 | efree(intern);
989 | }
990 |
991 | static zend_object_value php_svm_model_object_new_ex(zend_class_entry *class_type, php_svm_model_object **ptr TSRMLS_DC)
992 | {
993 | zval *tmp;
994 | zend_object_value retval;
995 | php_svm_model_object *intern;
996 |
997 | /* Allocate memory for the internal structure */
998 | intern = (php_svm_model_object *) emalloc(sizeof(php_svm_object));
999 | memset(&intern->zo, 0, sizeof(zend_object));
1000 |
1001 | if (ptr) {
1002 | *ptr = intern;
1003 | }
1004 |
1005 | /* Null model by default */
1006 | intern->model = NULL;
1007 | intern->x_space = NULL;
1008 |
1009 | zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
1010 | zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *));
1011 |
1012 | retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_svm_model_object_free_storage, NULL TSRMLS_CC);
1013 | retval.handlers = (zend_object_handlers *) &svm_model_object_handlers;
1014 | return retval;
1015 | }
1016 |
1017 | static zend_object_value php_svm_model_object_new(zend_class_entry *class_type TSRMLS_DC)
1018 | {
1019 | return php_svm_model_object_new_ex(class_type, NULL TSRMLS_CC);
1020 | }
1021 |
1022 | ZEND_BEGIN_ARG_INFO_EX(svm_empty_args, 0, 0, 0)
1023 | ZEND_END_ARG_INFO()
1024 |
1025 | ZEND_BEGIN_ARG_INFO_EX(svm_train_args, 0, 0, 1)
1026 | ZEND_ARG_INFO(0, problem)
1027 | ZEND_ARG_INFO(0, weights)
1028 | ZEND_END_ARG_INFO()
1029 |
1030 | ZEND_BEGIN_ARG_INFO_EX(svm_crossvalidate_args, 0, 0, 2)
1031 | ZEND_ARG_INFO(0, problem)
1032 | ZEND_ARG_INFO(0, number_of_folds)
1033 | ZEND_END_ARG_INFO()
1034 |
1035 | ZEND_BEGIN_ARG_INFO_EX(svm_params_args, 0, 0, 1)
1036 | ZEND_ARG_INFO(0, params)
1037 | ZEND_END_ARG_INFO()
1038 |
1039 | static function_entry php_svm_class_methods[] =
1040 | {
1041 | PHP_ME(svm, __construct, svm_empty_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
1042 | PHP_ME(svm, getOptions, svm_empty_args, ZEND_ACC_PUBLIC)
1043 | PHP_ME(svm, setOptions, svm_params_args, ZEND_ACC_PUBLIC)
1044 | PHP_ME(svm, train, svm_train_args, ZEND_ACC_PUBLIC)
1045 | PHP_ME(svm, crossvalidate, svm_crossvalidate_args, ZEND_ACC_PUBLIC)
1046 | { NULL, NULL, NULL }
1047 | };
1048 |
1049 | ZEND_BEGIN_ARG_INFO_EX(svm_model_construct_args, 0, 0, 0)
1050 | ZEND_ARG_INFO(0, filename)
1051 | ZEND_END_ARG_INFO()
1052 |
1053 | ZEND_BEGIN_ARG_INFO_EX(svm_model_predict_args, 0, 0, 1)
1054 | ZEND_ARG_INFO(0, data)
1055 | ZEND_END_ARG_INFO()
1056 |
1057 | ZEND_BEGIN_ARG_INFO_EX(svm_model_file_args, 0, 0, 1)
1058 | ZEND_ARG_INFO(0, filename)
1059 | ZEND_END_ARG_INFO()
1060 |
1061 | static function_entry php_svm_model_class_methods[] =
1062 | {
1063 | PHP_ME(svmmodel, __construct, svm_model_construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
1064 | PHP_ME(svmmodel, save, svm_model_file_args, ZEND_ACC_PUBLIC)
1065 | PHP_ME(svmmodel, load, svm_model_file_args, ZEND_ACC_PUBLIC)
1066 | PHP_ME(svmmodel, predict, svm_model_predict_args, ZEND_ACC_PUBLIC)
1067 | { NULL, NULL, NULL }
1068 | };
1069 |
1070 | PHP_MINIT_FUNCTION(svm)
1071 | {
1072 | zend_class_entry ce;
1073 | ZEND_INIT_MODULE_GLOBALS(svm, php_svm_init_globals, NULL);
1074 |
1075 | memcpy(&svm_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1076 | memcpy(&svm_model_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1077 |
1078 | INIT_CLASS_ENTRY(ce, "svm", php_svm_class_methods);
1079 | ce.create_object = php_svm_object_new;
1080 | svm_object_handlers.clone_obj = NULL;
1081 | php_svm_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
1082 |
1083 | INIT_CLASS_ENTRY(ce, "svmmodel", php_svm_model_class_methods);
1084 | ce.create_object = php_svm_model_object_new;
1085 | svm_model_object_handlers.clone_obj = NULL;
1086 | php_svm_model_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
1087 |
1088 | INIT_CLASS_ENTRY(ce, "svmexception", NULL);
1089 | php_svm_exception_sc_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
1090 | php_svm_exception_sc_entry->ce_flags |= ZEND_ACC_FINAL;
1091 |
1092 | /* Redirect the lib svm output */
1093 | //extern void (*svm_print_string) (const char *);
1094 | //svm_print_string = &print_null;
1095 | svm_set_print_string_function(&print_null);
1096 |
1097 | #define SVM_REGISTER_CONST_LONG(const_name, value) \
1098 | zend_declare_class_constant_long(php_svm_sc_entry, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
1099 |
1100 | /* SVM types */
1101 | SVM_REGISTER_CONST_LONG("C_SVC", C_SVC);
1102 | SVM_REGISTER_CONST_LONG("NU_SVC", NU_SVC);
1103 | SVM_REGISTER_CONST_LONG("ONE_CLASS", ONE_CLASS);
1104 | SVM_REGISTER_CONST_LONG("EPSILON_SVR", EPSILON_SVR);
1105 | SVM_REGISTER_CONST_LONG("NU_SVR", NU_SVR);
1106 |
1107 | /* Kernel types */
1108 | SVM_REGISTER_CONST_LONG("KERNEL_LINEAR", LINEAR);
1109 | SVM_REGISTER_CONST_LONG("KERNEL_POLY", POLY);
1110 | SVM_REGISTER_CONST_LONG("KERNEL_RBF", RBF);
1111 | SVM_REGISTER_CONST_LONG("KERNEL_SIGMOID", SIGMOID);
1112 | SVM_REGISTER_CONST_LONG("KERNEL_PRECOMPUTED", PRECOMPUTED);
1113 |
1114 | /* Long options (for setOptions) */
1115 | SVM_REGISTER_CONST_LONG("OPT_TYPE", phpsvm_svm_type);
1116 | SVM_REGISTER_CONST_LONG("OPT_KERNEL_TYPE", phpsvm_kernel_type);
1117 | SVM_REGISTER_CONST_LONG("OPT_DEGREE", phpsvm_degree);
1118 | SVM_REGISTER_CONST_LONG("OPT_SHRINKING", phpsvm_shrinking);
1119 | SVM_REGISTER_CONST_LONG("OPT_PROBABILITY", phpsvm_probability);
1120 |
1121 | /* Double options (for setOptions) */
1122 | SVM_REGISTER_CONST_LONG("OPT_GAMMA", phpsvm_gamma);
1123 | SVM_REGISTER_CONST_LONG("OPT_NU", phpsvm_nu);
1124 | SVM_REGISTER_CONST_LONG("OPT_EPS", phpsvm_eps);
1125 | SVM_REGISTER_CONST_LONG("OPT_P", phpsvm_p);
1126 | SVM_REGISTER_CONST_LONG("OPT_COEF_ZERO", phpsvm_coef0);
1127 | SVM_REGISTER_CONST_LONG("OPT_C", phpsvm_C);
1128 | SVM_REGISTER_CONST_LONG("OPT_CACHE_SIZE", phpsvm_cache_size);
1129 | SVM_REGISTER_CONST_LONG("OPT_WEIGHT", phpsvm_weight);
1130 |
1131 | #undef SVM_REGISTER_CONST_LONG
1132 |
1133 | return SUCCESS;
1134 | }
1135 |
1136 | PHP_MSHUTDOWN_FUNCTION(svm)
1137 | {
1138 | UNREGISTER_INI_ENTRIES();
1139 | return SUCCESS;
1140 | }
1141 |
1142 | PHP_MINFO_FUNCTION(svm)
1143 | {
1144 | php_info_print_table_start();
1145 | php_info_print_table_header(2, "svm extension", "enabled");
1146 | php_info_print_table_row(2, "svm extension version", PHP_SVM_EXTVER);
1147 | php_info_print_table_end();
1148 |
1149 | DISPLAY_INI_ENTRIES();
1150 | }
1151 |
1152 | /* No global functions */
1153 | zend_function_entry svm_functions[] = {
1154 | {NULL, NULL, NULL}
1155 | };
1156 |
1157 | zend_module_entry svm_module_entry =
1158 | {
1159 | STANDARD_MODULE_HEADER,
1160 | PHP_SVM_EXTNAME,
1161 | svm_functions, /* Functions */
1162 | PHP_MINIT(svm), /* MINIT */
1163 | PHP_MSHUTDOWN(svm), /* MSHUTDOWN */
1164 | NULL, /* RINIT */
1165 | NULL, /* RSHUTDOWN */
1166 | PHP_MINFO(svm), /* MINFO */
1167 | PHP_SVM_EXTVER, /* version */
1168 | STANDARD_MODULE_PROPERTIES
1169 | };
1170 |
1171 |
1172 | #ifdef COMPILE_DL_SVM
1173 | ZEND_GET_MODULE(svm)
1174 | #endif /* COMPILE_DL_SVM */
1175 |
--------------------------------------------------------------------------------