shogunをpython modular付きでインストールする(OS X Yosemite)

忘備録も兼ねて、様々な言語での機械学習をサポートしているライブラリであるshogunをpythonで扱う際に大変な思いをしたので解決法を書いておきます。

#####参考
[shogunの公式サイト](http://www.shogun-toolbox.org/)
[shogunのGithubページ](https://github.com/shogun-toolbox/shogun)

公式サイトはかなり見づらい&過去バージョンの情報も混じってて色々とわけがわからないので、Githubページのwikiとか見ながらの方がいいと思います。

##0.下準備
shogunのインストールの前に、必要なものをインストールします。
ここで注意が必要なのは、SWIGのバージョンです。
[SWIG](https://github.com/swig/swig)

2015/06/05時点で最新版は3.0.5ですが、どうやらこれを使ってshogunをインストールすると、使用する際にSegmentation Faultが発生する([ここらへん](https://github.com/shogun-toolbox/shogun/issues/2313)とか[ここらへん](https://github.com/swig/swig/issues/256)に解決したような表記もありますが、僕の環境ではSegfault出ました)ため、あらかじめSWIGのバージョンを2.x系をインストールし、ダウングレードしておく。

・Homebrewを使用している場合

まずは過去バージョンのSWIGをインストールできるように

```
$brew tap homebrew/versions
```

を実行する。これによって、brew searchを実行した際に、過去バージョンのフォーミュラが表示されるようになる。

```
$brew search
homebrew/versions/swig2	    homebrew/versions/swig304	swig
$brew install homebrew/versions/swig2

... #色々表示されます

$brew link swig2 
#すでにswigを使用している場合は、brew link --overwrite swig2で上書きする

```

これでSWIGまわりの準備は完了です。

##1.shogunのダウンロード
HomebrewやMacPortsでもできるらしいですが、Homebrewだとpythonのサンプルがインストールされない&Segmentation Faultが発生して、使い物にならなかったため、Gitから直接持ってきます。
公式ではMacPortsでの例がありますが、試していないので、誰か試した方教えてください。

```
$git clone https://github.com/shogun-toolbox/shogun.git 
$cd shogun
$mkdir build
```

公式に従ってbuildというディレクトリをshognの中に作成しておきます。
##2.shogunのインストール
ここからcmakeを行うんですが、オプションが大量にあり、しかも特に記述しているページが見つからなかったので、CMakeのGUIツールを使った方がいいです。
[CMake](http://www.cmake.org/)をダウンロードしておいてください。

CMakeを起動し、Where is the source codeと、Where to build the binariesの部分を画像の通りにします。(以下はデスクトップにshogunをcloneした例)
![スクリーンショット 2015-06-05 15.18.52.png](https://qiita-image-store.s3.amazonaws.com/0/41446/101d9dcf-fa9a-d238-f941-a1f38e0fdd19.png)

こうすると色々なオプションが表示されるので、必要なものにチェックし、CMakeを実行します。

そしてターミナルを起動し、

```
$cd /Users/YOUR_NAME/Desktop/shogun/build
$make && make install
```

を実行します。

```
$sudo find /usr -name "shogun" -type d

/usr/local/include/shogun
/usr/local/lib/python2.7/site-packages/shogun
/usr/local/share/shogun
```
となっていれば、インストールは成功です。あとは、公式サイトに従って

```
$ export LD_LIBRARY_PATH=SHOGUN_INSTALL_DIR/lib
$ export PYTHONPATH=SHOGUN_INSTALL_DIR/lib/pythonX.Y/dist-packages/
```
と入力してください。インストールした場所やOSによって変わるかと思いますが、僕の場合は(そしてこの手順でインストールした人の多くは)

```
$ export LD_LIBRARY_PATH=/usr/local/lib
$ export PYTHONPATH=/usr/local/lib/python2.7/site-packages/
```
となります。

##3._modshogun.soの依存しているライブラリのパスを変更する
この状態では、まだpythonからshogunを読み込もうとすると、Segmentation Faultが発生してしまうため、_modshogun.soの参照するライブラリのパスを変更します。

```
$sudo find /usr -name "*modshogun*"
/usr/local/lib/python2.7/site-packages/_modshogun.so
/usr/local/lib/python2.7/site-packages/modshogun.py
/usr/local/lib/python2.7/site-packages/modshogun.pyc
```
の一番上のやつですね。modshogunは、 shogunのインストールの際にSWIGによって生成されるもので、詳細はよくわからないのですが、modular shogunの略な感じがします。動的に色々なクラスを読み込んで呼び出せるようにしているみたいです。詳しくはわかりませんが。

この_modshogunの依存しているライブラリを見てみます。

```
$cd /usr/local/lib/python2.7/site-packages/
$otool -L _modshogun.so
_modshogun.so:
	libshogun.17.dylib (compatibility version 17.0.0, current version 17.1.0)
	/System/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.6)
	/System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate (compatibility version 1.0.0, current version 4.0.0)
	/usr/local/lib/libglpk.35.dylib (compatibility version 37.0.0, current version 37.0.0)
	/usr/local/opt/arpack/libexec/lib/libarpack.2.dylib (compatibility version 3.0.0, current version 3.0.0)
	/usr/local/lib/libopencv_videostab.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libtbb.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/local/lib/libopencv_superres.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_stitching.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_contrib.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_nonfree.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_ocl.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_gpu.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_photo.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_objdetect.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_legacy.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_video.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_ml.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_calib3d.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_features2d.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_highgui.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_imgproc.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_flann.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.11)
	/usr/local/lib/libnlopt_cxx.0.dylib (compatibility version 9.0.0, current version 9.2.0)
	/usr/local/lib/libColPack.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/local/lib/libjson-c.2.dylib (compatibility version 3.0.0, current version 3.1.0)
	/usr/local/opt/libxml2/lib/libxml2.2.dylib (compatibility version 12.0.0, current version 12.2.0)
	/usr/local/lib/libhdf5.9.dylib (compatibility version 10.0.0, current version 10.0.0)
	/usr/local/lib/libsz.2.dylib (compatibility version 3.0.0, current version 3.0.0)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
	/usr/lib/libcurl.4.dylib (compatibility version 7.0.0, current version 8.0.0)
	/usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.5)
	/usr/local/lib/liblzma.5.dylib (compatibility version 8.0.0, current version 8.1.0)
	/usr/local/lib/libsnappy.1.dylib (compatibility version 4.0.0, current version 4.1.0)
	/usr/local/lib/liblzo2.2.dylib (compatibility version 3.0.0, current version 3.0.0)
	/usr/local/lib/libprotobuf.9.dylib (compatibility version 10.0.0, current version 10.1.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
```

こんな感じでずらっと出てきます。僕の場合、python-modularと、OpenCVのオプションをつけてインストールしたので、こんな感じになりました。人によってこの部分は変わると思います。

これの上のほうにある

```
 /System/Library/Frameworks/Python.framework/Versions/2.7/Python
```
は、OSXに最初からインストールされているpythonらしく、理由は色々あるみたいなんですが、これを使ってることがSegmentation Faultの原因とのことなので、これを変更します。

install_name_toolというものを使用して_modshogun.soの依存するライブラリのパスを変更することができます。

```
$install_name_tool -change 変更したいパス 変更先のパス ライブラリ名
```

という感じで

```
$install_name_tool -change /System/Library/Frameworks/Python.framework/Versions/2.7/Python /usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib _modshogun.so
```

僕はこのように書きました。変更先のパスなのですが、shogunをインストールした時に出ていたバージョンのpythonの共有ライブラリに通したらできました。このあたり正しいかどうかわからないので、詳しい人教えてください。

##4.サンプルを動かしてみる
これで一回pythonを起動してみます。

```
$python
Python 2.7.10 (default, Jun  3 2015, 16:47:53) 
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import modshogun
>>> import shogun
>>> 
```

Segmentation Faultは消えました。長かった...

ついでにサンプルも動かしてみます。Gitからcloneしたshogunのディレクトリまで移動して

```
$python examples/undocumented/python_modular/graphical/svm.py
```

![スクリーンショット 2015-06-05 15.54.37.png](https://qiita-image-store.s3.amazonaws.com/0/41446/eac8a6b3-9d64-71ab-8eb2-b177d28b5d6e.png)

ってなれば問題無し...のはず...(まださっきできたばかりだから本当にこれで大丈夫なのかはわからないです...)

ちなみに、exampleの中に色々なサンプルが入ってますので、一度見てみるといいかもしれません。公式サイトにも一応リファレンスはありますが、かなり大雑把なので、サンプルのコード読んで理解するほうが手っ取り早かったりします。

##ちなみに
ここまでやってSegmentation Faultが出た場合、そしてエラーログに「_wrap_delete_{何かクラス名}」みたいなのが表示されており、PyArg_UnpackTupleのタイミングでSegmentation Faultが起きている場合は、SWIGのバージョンが原因の可能性が高いです。バージョンを確認して、3.x系の場合は、一度2.x系にして再びインストールしてみると動くようになるかもしれません。