galdric/knn.go
knn.goRaw
1package main
2
3import (
4 "fmt"
5 "sort"
6)
7
8func euclideanDist(img1, img2 [][]float64) float64 {
9 var dist float64
10 for i := 0; i < len(img1); i++ {
11 for j := 0; j < len(img1[i]); j++ {
12 dist += (img1[i][j] - img2[i][j]) * (img1[i][j] - img2[i][j])
13 }
14 }
15
16 return dist
17}
18
19type Neighbour struct {
20 Dist float64
21 Label string
22}
23
24func isNeighbour(neighbours []Neighbour, dist float64, label string) []Neighbour {
25 var temp []Neighbour
26
27 for i := 0; i < len(neighbours); i++ {
28 temp = append(temp, neighbours[i])
29 }
30 ntemp := Neighbour{dist, label}
31 temp = append(temp, ntemp)
32
33 //now, sort the temp array
34 sort.Slice(temp, func(i, j int) bool {
35 return temp[i].Dist < temp[j].Dist
36 })
37
38 for i := 0; i < len(neighbours); i++ {
39 neighbours[i] = temp[i]
40 }
41
42 return neighbours
43}
44
45func getMapKey(dataset map[string]ImgDataset) string {
46 for k, _ := range dataset {
47 return k
48 }
49 return ""
50}
51
52type LabelCount struct {
53 Label string
54 Count int
55}
56
57func averageLabel(neighbours []Neighbour) string {
58 labels := make(map[string]int)
59 for _, n := range neighbours {
60 labels[n.Label]++
61 }
62 //create array from map
63 var a []LabelCount
64 for k, v := range labels {
65 a = append(a, LabelCount{k, v})
66 }
67 sort.Slice(a, func(i, j int) bool {
68 return a[i].Count > a[j].Count
69 })
70 fmt.Println(a)
71 //send the most appeared neighbour in k
72 return a[0].Label
73}
74func knn(dataset Dataset, input [][]float64) string {
75 k := 10
76 var neighbours []Neighbour
77 label := getMapKey(dataset)
78 for i := 0; i < k; i++ {
79 /*neighbours[i].Dist = euclideanDist(dataset["leopard"][0], input)
80 neighbours[i].Label = "leopard"*/
81 neighbours = append(neighbours, Neighbour{euclideanDist(dataset[label][0], input), label})
82 }
83 for l, v := range dataset {
84 for i := 0; i < len(v); i++ {
85 dNew := euclideanDist(v[i], input)
86 /*if dNew < d {
87 d = dNew
88 label = l
89 }*/
90 neighbours = isNeighbour(neighbours, dNew, l)
91 }
92 }
93 for i := 0; i < len(neighbours); i++ {
94 fmt.Print(neighbours[i].Label + " - ")
95 fmt.Println(neighbours[i].Dist)
96 }
97
98 r := averageLabel(neighbours)
99 return r
100}