hama_duのブログ

ノンジャンル記事置き場

CentOS5.5 に libsvm-ruby を導入する方法まとめ

題の通りです。libsvm-ruby + rmagick で画像処理やりたかった。
導入が色々と面倒だったのでまとめ。

ruby、その他開発ツール(gcc, g++とか) は既に入ってるものとします

ホントは良くないけど全部rootで作業しました。

まず、大元のライブラリ libsvm をインストールする。

yum install libsvm libsvm-devel

「そんなパッケージ無いよ」と言われる。そこで、EPELリポジトリを追加してやる。(既に追加してる人はこの操作を飛ばしてください。)

wget http://download.fedora.redhat.com/pub/epel/RPM-GPG-KEY-EPEL
rpm --import RPM-GPG-KEY-EPEL
vim /etc/yum.repos.d/epel.repo
[epel]
name=EPEL RPM Repository for Red Hat Enterprise Linux
baseurl=http://download.fedora.redhat.com/pub/epel/$releasever/$basearch/
gpgcheck=1
enabled=0
yum --enablerepo=epel install libsvm libsvm-devel

これでlibsvmがインストールできた。

次に、libsvmrubyラッパーである libsvm-ruby をインストールする。

ダウンロード

現時点(2011/9)での最新バージョンは2.8.5

wget http://debian.cilibrar.com/debian/pool/main/libs/libsvm-ruby/libsvm-ruby_2.8.5.orig.tar.gz
tar xvzf libsvm-ruby_2.8.5.orig.tar.gz
cd libsvm-ruby_2.8.5
configure

別途、libsvmのソース(svm.cpp)が必要なので公式からダウンロードする。また、svm.hにもパスが通っている必要がある。

wget http://www.csie.ntu.edu.tw/~cjlin/cgi-bin/libsvm.cgi?+http://www.csie.ntu.edu.tw/~cjlin/libsvm+tar.gz
tar xvzf libsvm-3.1.tar.gz
cd libsvm-3.1
cp svm.cpp ~/libsvm-ruby_2.8.5/
cp svm.h /usr/include/
cd ~/libsvm-ruby_2.8.5/
./configure

makeする

make

なんと、このままではコンパイルが通らない。エラーが二つ出るので、それらを修正する。

redefinition of ‘struct svm_model’

main.cpp:585: error: redefinition of ‘struct svm_model’
みたいな感じのエラーが出たはず。
そこで、main.cpp を編集してエラーを回避する。

vim main.cpp
585行目に、

/* To be removed in next version */
struct svm_model
{
        svm_parameter param;    // parameter
        int nr_class;           // number of classes, = 2 in regression/one class svm
        int l;                  // total #SV
        svm_node **SV;          // SVs (SV[l])
        double **sv_coef;       // coefficients for SVs in decision functions (sv_coef[n-1][l])
        double *rho;            // constants in decision functions (rho[n*(n-1)/2])

        // for classification only

        int *label;             // label of each class (label[n])
        int *nSV;               // number of SVs for each class (nSV[n])
                                // nSV[0] + nSV[1] + ... + nSV[n-1] = l
        // XXX
        int free_sv;            // 1 if svm_model is created by svm_load_model
                                // 0 if svm_model is created by svm_train
};

という記述があるが、これは既に svm.h に書いてあるため、コメントアウトする。

svm_destroy_model’ was not declared in this scope

次に、main.cpp:374: error: ‘svm_destroy_model’ was not declared in this scope
というエラー。

svm_destroy_model(rp->m);

という箇所で文句を言われているみたいだ。svm.h を見ると、確かにこのような関数はない。しかし、よく見ると

void svm_free_and_destroy_model(struct svm_model **model_ptr_ptr);

のような関数が。ひょっとしてこれを呼び出せばいいのかな?

そこで、この関数を

static void svmpm_free(void *ptr)
{
  struct RSVM_Model *rp = (struct RSVM_Model *) ptr;
  svm_destroy_model(rp->m);
  free(rp);
}

このように変更。

static void svmpm_free(void *ptr)
{
  struct RSVM_Model *rp = (struct RSVM_Model *) ptr;
  svm_free_and_destroy_model(&(rp->m));
}

以上の作業を行えば、make & make install は成功する。

make
make install

付属の test.rb が動くかどうかテストする。

ruby test.rb
/usr/local/lib/ruby/site_ruby/1.8/i686-linux/SVM.so: /usr/local/lib/ruby/site_ruby/1.8/i686-linux/SVM.so: undefined symbol: __cxa_pure_virtual - /usr/local/lib/ruby/site_ruby/1.8/i686-linux/SVM.so (LoadError)

と怒られる。調べると、configureしたときにできた Makefile を編集する必要があるとのこと。めんどくせー

vim Makefile

真ん中の方に、

LIBS =   -lrt -ldl -lcrypt -lm   -lc

とあるが、これを

LIBS =   -lrt -ldl -lcrypt -lm   -lc -lstdc++ 

に変更する。(-lstdc++ を追加)


もう一度チャレンジ!

make clean
make
make install

ruby test.rb

OK、動いた!めでたしめでたし。