-
Notifications
You must be signed in to change notification settings - Fork 0
/
KNN.ts
52 lines (45 loc) · 1.65 KB
/
KNN.ts
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
import * as tf from '@tensorflow/tfjs'
import {Tensor} from '@tensorflow/tfjs'
const {sub, neg} = tf;
/**
* A simple implementation of KNN which will
* find the best neighbor combination required to yield the highest results
* @constructor Instantiates a KNN Model
* @returns An object instance of the model
*/
export class KNearestNeighbors {
constructor(
private numNeighbor: number,
// private batchSize: number = 10,
private selfFitX: Tensor,
private selfFitY: Tensor,
) {
const numClasses = new Set(selfFitY.dataSync()).size
this.selfFitY = tf.oneHot(selfFitY.cast('int32'), numClasses)
}
/**
* Using Euclidean distances, it finds for every sample in x where it should belong
* based on the training data
* @param x - The input dataset
* @returns The predictions for where every sample from X belongs
*/
predict(x: Tensor) {
const distance = euclideanDistance(this.selfFitX,x)
const {indices: topKIndices} = tf.topk(neg(distance), this.numNeighbor)
const countPred = tf.gather(this.selfFitY, topKIndices).sum(1)
const predictions = tf.argMax(countPred, 1)
// console.log('Prediction Confidence: ', div(predCount, this.numNeighbor).dataSync())
// return tf.argMax(predCount, 1)
return predictions
}
}
/**
* Calculate the Euclidean Distance between two Tensors
* @param x - Training Dataset
* @param y - Test Dataset
* @returns The distance between the two tensors
*/
function euclideanDistance(x: Tensor, y: Tensor) {
// return tf.norm(, y), 'euclidean')
return tf.norm(sub(x, y.expandDims(1)), undefined, 2)
}