|
1 | 1 | package clusters |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "errors" |
4 | 5 | "math" |
5 | 6 | "math/rand" |
6 | 7 | "sync" |
@@ -108,6 +109,52 @@ func (c *kmeansClusterer) Learn(data [][]float64) error { |
108 | 109 | return nil |
109 | 110 | } |
110 | 111 |
|
| 112 | +func (c *kmeansClusterer) Test(data [][]float64, args ...interface{}) (*TestResult, error) { |
| 113 | + if len(data) == 0 { |
| 114 | + return nil, ErrEmptySet |
| 115 | + } |
| 116 | + |
| 117 | + clusters, ok := args[0].(int) |
| 118 | + if !ok { |
| 119 | + return nil, errors.New("Argument #0 is invalid") |
| 120 | + } |
| 121 | + |
| 122 | + var ( |
| 123 | + size = len(data) |
| 124 | + bounds = bounds(data) |
| 125 | + wks = make([]float64, clusters) |
| 126 | + wkbs = make([]float64, clusters) |
| 127 | + sk = make([]float64, clusters) |
| 128 | + one = make([]float64, clusters) |
| 129 | + bwkbs = make([]float64, clusters) |
| 130 | + ) |
| 131 | + |
| 132 | + for i := 0; i < clusters; i++ { |
| 133 | + c.Learn(data) |
| 134 | + |
| 135 | + wks[i] = math.Log(wk(c.d, c.m, c.a)) |
| 136 | + |
| 137 | + for j := 0; j < clusters; j++ { |
| 138 | + c.Learn(c.buildRandomizedSet(size, bounds)) |
| 139 | + |
| 140 | + bwkbs[j] = math.Log(wk(c.d, c.m, c.a)) |
| 141 | + one[j] = 1 |
| 142 | + } |
| 143 | + |
| 144 | + wkbs[i] = floats.Sum(bwkbs) / float64(clusters) |
| 145 | + |
| 146 | + floats.Scale(wkbs[i], one) |
| 147 | + floats.Sub(bwkbs, one) |
| 148 | + floats.Mul(bwkbs, bwkbs) |
| 149 | + |
| 150 | + sk[i] = math.Sqrt(floats.Sum(bwkbs) / float64(clusters)) |
| 151 | + } |
| 152 | + |
| 153 | + floats.Scale(math.Sqrt(1+(1/float64(clusters))), sk) |
| 154 | + |
| 155 | + return nil, nil |
| 156 | +} |
| 157 | + |
111 | 158 | func (c *kmeansClusterer) Sizes() []int { |
112 | 159 | c.mu.RLock() |
113 | 160 | defer c.mu.RUnlock() |
@@ -324,3 +371,20 @@ func (c *kmeansClusterer) check() { |
324 | 371 |
|
325 | 372 | c.oldchanges = c.changes |
326 | 373 | } |
| 374 | + |
| 375 | +func (c *kmeansClusterer) buildRandomizedSet(size int, bounds []*[2]float64) [][]float64 { |
| 376 | + var ( |
| 377 | + l = len(bounds) |
| 378 | + r = make([][]float64, size) |
| 379 | + ) |
| 380 | + |
| 381 | + for i := 0; i < size; i++ { |
| 382 | + r[i] = make([]float64, l) |
| 383 | + |
| 384 | + for j := 0; j < l; j++ { |
| 385 | + r[i][j] = uniform(bounds[j]) |
| 386 | + } |
| 387 | + } |
| 388 | + |
| 389 | + return r |
| 390 | +} |
0 commit comments