stMind

about Arsenal, Arsene Wenger, Tech, Computer vision and Machine learning

golangの機械学習ライブラリgolearnをインストール

Machine Learning in Go using GoLearn | Stephen Whitworth

インストールはInstallation · sjwhitworth/golearn Wiki · GitHubに書いてある通りなんだけど、Issuesにも挙がってるエラーで追加の手順が必要だったのでメモ。 環境はOSX10.9.4とGo1.2.2。

1. Installing a BLAS implementation

インストールはbrewで簡単に出来るけど、brew updateしておかないとエラーが出た。a1c3b9aのコミットをマージした状態であれば問題なし。

$ brew update
$ brew install liblas

2. Completing the installation of Gonum's BLAS wrapper

ここは特に問題なかった。

$ go get github.com/gonum/blas
$ cd $GOPATH/src/github.com/gonum/blas
$ go install ./...

3. Installing GoLearn's internal dependencies

ここも特に問題なかったかな。

$ go get -t -u -v github.com/sjwhitworth/golearn
$ cd $GOPATH/src/github.com/sjwhitworth/golearn/ext
$ go run make.go

環境変数の設定も書いてある通りに実施する。インストールだけならばbash上で直接実行してもいいし、後々も考えてbashrcに記述してsourceで読み込み直してもいいし、どちらでも可。

$ export DYLD_LIBRARY_PATH=$GOPATH/src/github.com/sjwhitworth/golearn/ext/lib:$DYLD_LIBRARY_PATH

4. Completing the installation

$ cd $GOPATH/src/github.com/sjwhitworth/golearn
$ go get ./...

ここで追加の手順が必要になる。

追加1. liblinearのインストール

go getするとlinear.hが見つからないというエラーが出る。

$ go get ./...
# github.com/sjwhitworth/golearn/linear_models
linear_models/liblinear.go:6:10: fatal error: 'linear.h' file not found
#include <linear.h>
         ^
1 error generated.

Issue #55によると、よくわからないけれどliblinear1.94をbrewでインストールしないと動かなかった、というコメントがあってまだ解決していない様子。brewでインストールすれば良いらしいので実行。

$ brew install liblinear
追加2. liblinear.goの修正

再度go getをすると、また別のエラーが出る。

$ go get ./...
# github.com/sjwhitworth/golearn/linear_models
linear_models/liblinear.go:55: cannot use &c_y[0] (type *_Ctype_int) as type *_Ctype_double in assignment

Issue #47を見ると、liblinear1.94の場合、以前のコミットで変更された箇所をdoubleに戻さないといけない様子。Ubuntuのシステムのliblinearのバージョンが古くて、そういう変更が行われていた?らしい。doubleにrevertするPull Requestが送られているので、それがマージされるまでは手動で修正する必要あり。修正場所は51行目と53行目。

$ git diff
diff --git a/linear_models/liblinear.go b/linear_models/liblinear.go
index 82c6133..e5d0682 100644
--- a/linear_models/liblinear.go
+++ b/linear_models/liblinear.go
@@ -48,9 +48,9 @@ func NewProblem(X [][]float64, y []float64, bias float64) *Problem {
        prob.c_prob.n = C.int(len(X[0]) + 1)
 
        prob.c_prob.x = convert_features(X, bias)
-       c_y := make([]C.int, len(y))
+       c_y := make([]C.double, len(y))
        for i := 0; i < len(y); i++ {
-               c_y[i] = C.int(y[i])
+               c_y[i] = C.double(y[i])
        }
        prob.c_prob.y = &c_y[0]
        prob.c_prob.bias = C.double(-1)

確認

これでgo getが出来るようになった! 例えば、examples/knnclassifier/knnclassifier_iris.goを実行して見ると、

 ...
55 row(s) undisplayed
Iris-versicolor 26 3  54 0.8966    0.9286    0.9123
Iris-virginica  26 2  54 0.9286    0.8966    0.9123
Iris-setosa 28 0  57 1.0000    1.0000    1.0000
Overall accuracy: 0.9412

こんな結果が得られる。めでたしめでたし。