GoLearnについて

初めてのAdvent calendarへの投稿になります。
ライブラリの紹介になってしまいますがよろしくお願いします。

# Go言語の機械学習について
Go Langでもいくつかの機械学習があります。

## 自然言語処理系
- go-porterstemmer - A native Go clean room implementation of the Porter Stemming algorithm
- paicehusk - Golang implementation of the Paice/Husk Stemming Algorithm
- snowball - Snowball Stemmer for Go
- go-ngram - In-memory n-gram index with compression

## 機械学習系
- Go Learn - Machine Learning for Go
- go-pr - Pattern recognition package in Go lang.
- go-ml - Linear / Logistic regression, Neural Networks, Collaborative Filtering and Gaussian Multivariate Distribution
- bayesian - Naive Bayesian Classification for Golang
- go-galib - Genetic Algorithms library written in Go / golang
- Cloudforest - Ensembles of decision trees in go/golang
- gobrain - Neural Networks written in go

## データ分析/可視化系
- go-graph - Graph library for Go/golang language
- SVGo - The Go Language library for SVG generation

# なぜ GoLearn なのか
GoLearnはGitHub上で開発しているライブラリです。
Starの数を比較すると、

- [GoLearn](https://github.com/sjwhitworth/golearn)：2385
- [go-pr](https://github.com/daviddengcn/go-pr)：32
- [go_ml](https://github.com/alonsovidales/go_ml)：63
- [bayesian](https://github.com/jbrukh/bayesian)：270
- [go-galib](https://github.com/thoj/go-galib)：100
- [Cloudforest](https://github.com/ryanbressler/CloudForest)：310
- [gobrain](https://github.com/goml/gobrain)：60

と圧倒的です。
また、[issue#68](https://github.com/sjwhitworth/golearn/issues/68)で他のプロジェクトの方が統合を提案していますし、開発をチームで進めていくので、速い開発が期待されます。
（書き方が少なく、Go fmtでフォーマッティングしてくれるGoは、コード読むときに無駄に詮索しなくて済むので本当に助かりますね。）

# サンプル
### GOROOTやGOPATHの設定がされていることが前提です。[参考](https://golang.org/doc/install)

## GoLearnのインストール
1. `go get` コマンドでGoLearnを取りに行きます。

    ```go:GoLearnのインストール
    go get -t -u -v github.com/sjwhitworth/golearn
    ```

2. サンプルコードの実行
今回は機械学習の定番、アヤメのデータをKNNで分類していきます。

    ```go:サンプルコード
    package main

    import (
        "fmt"

        "github.com/sjwhitworth/golearn/base"
        "github.com/sjwhitworth/golearn/evaluation"
        "github.com/sjwhitworth/golearn/knn"
    )

    func main() {
        // ヘッダー付きのデータを読み込む
        // PandasやRのDataFrameのようなオブジェクトができます。
        // データセットのパスはフルパスで書いた方が確実です。
        rawData, err :=  base.ParseCSVToInstances("path/to/GOPATH/src/github.com/sjwhitworth/golearn/examples/datasets/iris.csv", false)
        // データがない場合の処理
        if err != nil {
            panic(err)
        }

        // データセットの概要を示す
        fmt.Println(rawData)

        // KNNを初期化
        // すげー簡単
        cls := knn.NewKnnClassifier("euclidean", 2)

        // データセットを学習用とテスト様に分離
        trainData, testData := base.InstancesTrainTestSplit(rawData, 0.50)

        // 学習
        cls.Fit(trainData)

        // テストデータを使って予測
        predictions := cls.Predict(testData)

        // 予測結果の出力
        fmt.Println(predictions)

        // precision/recallなどを出力
        confusionMat, err := evaluation.GetConfusionMatrix(testData, predictions)
        if err != nil {
            panic(fmt.Sprintf("Unable to get confusion matrix: %s", err.Error()))
        }
        fmt.Println(evaluation.GetSummary(confusionMat))
    }
    ```

3. 実行

    ```go:実行結果
    ~/go/src/github.com/toohsk/golearn-sample(branch:master*) » go run sample.go
    ../../sjwhitworth/golearn/knn/knn.go:8:2: cannot find package "github.com/gonum/matrix" in any of:
    	/usr/local/opt/go/libexec/src/github.com/gonum/matrix (from $GOROOT)
    	/Users/demouser/go/src/github.com/gonum/matrix (from $GOPATH)
    ../../sjwhitworth/golearn/base/classifier.go:4:2: cannot find package     "github.com/gonum/matrix/mat64" in any of:
	    /usr/local/opt/go/libexec/src/github.com/gonum/matrix/mat64 (from $GOROOT)
	    /Users/demouser/go/src/github.com/gonum/matrix/mat64 (from $GOPATH)
    ```
うん？？
動かない。。。
`gonum`とやらが不足しているみたい。

4. `go get` コマンドでgonumを取りに行きます。
GoLearnで使用するgonumの中のライブラリが色々とあるので、ダウンロードします。

    ```go:gonumのインストール
    go get github.com/gonum/matrix
    go get github.com/gonum/floats
    go get github.com/gonum/internal/asm
    ```

5. 再度実行

    ```go:実行結果
~/go/src/github.com/toohsk/golearn-sample(branch:master*) » go run sample.go
    Reference Class	True Positives	False Positives	True Negatives	Precision	Recall	F1 Score
    ---------------	--------------	---------------	--------------	---------	------	--------
    Iris-setosa	30		0		58		1.0000		1.0000	1.0000
    Iris-virginica	27		2		57		0.9310		0.9310	0.9310
    Iris-versicolor	27		2		57		0.9310		0.9310	0.9310
    Overall accuracy: 0.9545
    ```
分類されました。
本当はもっと出力されますが、実行してのお楽しみということで割愛させていただきます。

# でも、Goって遅いよね？
巷で噂の『Go言語遅い説』
今回は実行時間は計測していないのでわかりませんが、
小規模データなら遅いと感じないです。
気になる方は上記のサンプルを動かして見てください。

# 感想
まだまだ機械学習のモデルは不足しているので使えるものは少ないですが、
GoLearnは今後期待のライブラリだと思います。
GoLearnを使ってカグろうかなー