arnaucube
arnaucube/galdricPublic Self-hosted repository
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}