Posts tagged ‘svm’

svm是一种常用的分类方法,libsvm一个开源库,提供了c、java、python的接口。

而我需要用到的是php来使用svm方法,所以找了php-svm作为php的扩展。

按照php-svm的README中介绍的方法开始安装。在安装过程中,先是报 Unable to find svm.h 。即使指定了configure的with-svm也不行。之后,查看config.m4,发现以下代码:

AC_MSG_CHECKING([for svm.h header])
for i in $PHP_SVM /usr/local /usr;
do
test -r $i/include/libsvm-2.0/libsvm/svm.h && SVM_PREFIX=$i && SVM_INC_DIR=$i/include/libsvm-2.0/ && SVM_OK=1
done
if test “$SVM_OK” != “1”; then
for i in $PHP_SVM /usr/local /usr;
do
test -r $i/include/libsvm/svm.h && SVM_PREFIX=$i && SVM_INC_DIR=$i/include/ && SVM_OK=1
done
fi

这显然不对啊!它会在/usr/local和/usr的include/libsvm下去找svm.h文件!

解决方法两种:一是在/usr/local下建立符合其要求的目录,并且把svm.h复制过去;另一种,就是修改config.m4,添加上你的svm.h路径。

继而configure、make完毕。但是在make test的时候,报如下错误:

PHP Warning:  PHP Startup: Unable to load dynamic library 'modules/svm.so' - modules/svm.so: undefined symbol: svm_print_string in Unknown on line 0

但是在php-svm和libsvm的源码里grep,发现都没有svm_print_string 的定义:

svm.c:  extern void (*svm_print_string) (const char *);
svm.c:  svm_print_string = &print_null;
svm.c:  extern void (*svm_print_string) (const char *);
svm.c:  svm_print_string = &print_null;

所以,修改libsvm:

在svm.cpp中注释掉以下代码:

/* cy delete, move to svm.h */
  /*
  static void print_string_stdout(const char *s)
  {
      fputs(s,stdout);
      fflush(stdout);
  }
  static void (*svm_print_string) (const char *) = &print_string_stdout;
  */


在svm.h中新增:

 /* cy add, from svm.cpp */
  static void print_string_stdout(const char *s)
  {
      fputs(s,stdout);
      fflush(stdout);
  }
  static void (*svm_print_string) (const char *) = &print_string_stdout;


然后,重新在libsvm中make lib,再安装php-svm就可以了。

测试代码如下:

$data = array(
          array(-1, 1 => 0.43, 3 => 0.12, 9284 => 0.2),
          array(+1, 1 => 0.75, 3 => 0.35, 9284 => 0.9),
          );

  $svm = new SVM();
  $model = $svm->train($data);
  #$model->save('train.model');
  #var_dump($model);
  unset($model);

  $data = array(1 => 0.73, 3 => 0.32, 9284 => 0.8);
  $model = new SVMModel();
  $model->load('train.model');
  $result = $model->predict($data);
  var_dump($result);