-
Notifications
You must be signed in to change notification settings - Fork 0
/
kNN.js
82 lines (64 loc) · 1.74 KB
/
kNN.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
if(typeof train_data == 'undefined'){
console.log('Data is undefined');
}
// Algorithm
var kNN = function(k){
var self = this;
self.k = k || 3;
this.fit = function(){
console.log("Train data is already classified: ", train_data);
};
// Usage: this.predict([20, 204, 204]);
this.predict = function(test_data){
var distance = [];
// Calculate distance between test_data and each trained data.
Object.keys(train_data).forEach(function (key) {
var label = key;
var labelData = train_data[label];
for (var i = labelData.length - 1; i >= 0; i--) {
// console.log("Label: "+ label + " | Calculating distance between tuplas: ", test_data+" - "+labelData[i]);
// avg(distance)
var avgDistance = (
Math.pow( labelData[i][0]-test_data[0] , 2 ) +
Math.pow( labelData[i][1]-test_data[1] , 2) +
Math.pow( labelData[i][2]-test_data[2] , 2)
) / 3;
distance.push( {"label":label, "value":avgDistance} );
};
});
// Order distance DESC
distance.sort(function(a,b) {
if (a.value < b.value)
return -1;
if (a.value > b.value)
return 1;
return 0;
});
// console.log(distance);
return nearstNeighbors(self.k, distance);
}
// Private functions
function nearstNeighbors(k, arr){
var votes = [];
var counter = {};
for (var i = 0; i < k; i++) {
var label = arr[i].label;
if( !counter[label] ){
counter[label] = 0;
}
counter[label]++;
votes.push({"label":label, "count":counter[label]});
};
console.log("counter", counter);
// Order distance DESC
votes.reverse(function(a,b) {
if (a.count < b.count)
return -1;
if (a.count > b.count)
return 1;
return 0;
});
console.log("votes", votes);
return votes[0]["label"];
}
};