goClustering
goClustering is an implementation of following clustering algorithm in Golang.
Ward's method
Ward's method is a distance criterion in hierarchical cluster algorithm.
This method puts two groups into one to minimize the total within-cluster variance. For detail, see here.
How to Install
You can get goClustering by using go get:
go get github.com/cipepser/goClustering/...
To visualize the dendrogram, you also install gonum/plot
.
go get gonum.org/v1/plot/...
How to Use
This hierarchical cluster algorithm have two parts:
- Execute Ward's method
- Visualize
In execute Ward's method step, your input data must be n * d
matrix, where n is an observation and d is a dimension of feature vectors.
As a result of this step, you can get the ward.Tree
which is binary-tree of the result of hierarchical clustering with distance of each group.
You can execute Ward's method like this:
T := ward.Ward(X)
Second stap is Visualize step. You can visualize the dendrogram of ward.Tree
by gonum/plot
like:
d, _ := plotter.NewDendrogram(T)
Where, T
is a result of first step. And you create a plot to add above d
.
p, err := plot.New()
p.Add(d)
You can also customize title and labels of x-axis and y-axis.
p.Title.Text = "Dendrogram"
p.X.Label.Text = "data"
p.Y.Label.Text = "distance"
Name the leaf nodes and rotate names.
p.NominalX("aaa", "bbb", "ccc", "ddd", "eee", "fff")
p.X.Tick.Label.Rotation = math.Pi / 3
p.X.Tick.Label.YAlign = draw.YCenter
p.X.Tick.Label.XAlign = draw.XRight
Example
package main
import (
"math"
"github.com/cipepser/goClustering/ward"
"github.com/cipepser/goClustering/vis"
"gonum.org/v1/plot"
"gonum.org/v1/plot/vg"
"gonum.org/v1/plot/vg/draw"
)
func main() {
// input data set
X := [][]float64{
{0, 0},
{2, 2},
{1, 1},
{2, -1.2},
{3, 2.2},
{3.5, 0.5},
}
// Ward's method
T := ward.Ward(X)
// draw the dendrogram
d, err := plotter.NewDendrogram(T)
if err != nil {
panic(err)
}
p, err := plot.New()
if err != nil {
panic(err)
}
p.Add(d)
p.Title.Text = "Dendrogram"
p.X.Label.Text = "data"
p.NominalX("aaa", "bbb", "ccc", "ddd", "eee", "fff")
p.X.Tick.Label.Rotation = math.Pi / 3
p.X.Tick.Label.YAlign = draw.YCenter
p.X.Tick.Label.XAlign = draw.XRight
p.Y.Label.Text = "distance"
// save as a png file
file := "img.png"
if err = p.Save(10*vg.Inch, 6*vg.Inch, file); err != nil {
panic(err)
}
}
Result
References