k Nearest Neighbours Classifier (kNN) is a powerful but computational costly nonlinear classifier. Basically, kNN works based on distance calculation and finding of closest neighbour vectors according to a distance function. Distance function can be l1 (Manhattan distance), l2 (Euclidean distance) or a different available appropriate distance function. kNN uses a hyper parameter (k) that implies count of closest neighbours.
Algorithm find closest k vector to current vector, and returns classification result as class label of the largest matched number of class between these k closest vectors.
document.addEventListener('DOMContentLoaded', (e) => { drawPoints(); }); var point = { x: 0, y: 0 }; var k = 3; var datas = [ { c: 1, x: 10, y: 100 }, { c: 1, x: -10, y: 50 }, { c: 1, x: 50, y: 150 }, { c: 2, x: 100, y: 80 }, { c: 1, x: 30, y: 200 }, { c: 2, x: 200, y: 50 }, { c: 2, x: 120, y: 30 }, { c: 2, x: 100, y: 150 }, { c: 3, x: 300, y: 50 }, { c: 1, x: -150, y: 200 }, { c: 3, x: -300, y: 400 }, { c: 3, x: 233, y: 333 }, { c: 2, x: 127, y: 190 }, { c: 3, x: 100, y: -32 }, { c: 1, x: -50, y: -12 }, { c: 1, x: -101, y: -50 }, { c: 1, x: -301, y: -19 }, { c: 2, x: 127, y: -22 }, { c: 3, x: 120, y: -100 }, { c: 2, x: -50, y: -200 }, { c: 3, x: 800, y: 100 }, { c: 3, x: 150, y: -150 }, { c: 3, x: 70, y: -80 }, { c: 3, x: 70, y: -500 }, { c: 3, x: 200, y: -300 }, { c: 2, x: -50, y: -150 }, { c: 3, x: 111, y: -200 }, { c: 3, x: 301, y: -310 }, { c: 3, x: 200, y: -151 }, { c: 1, x: -122, y: -99 }, { c: 1, x: -301, y: -499 }, { c: 1, x: 401, y: -1 }, ]; function start() { let classColor = ""; setValues(); drawCurrentPoint(); let c = knnClassify(); if (c == 1) classColor = "red"; else if (c == 2) classColor = "green"; else classColor = "purple"; alert(classColor); } function knnClassify() { var classificationResults = [ { c: 1, count: 0 }, { c: 2, count: 0 }, { c: 3, count: 0 } ]; let distances = []; for (let i = 0; i < datas.length; i++) { let distance = l2Distance(datas[i], point); let distanceToClass = { c: datas[i].c, d: distance }; distances.push(distanceToClass); } distances.sort(function (a, b) { return a.d - b.d; }); for (let i = 0; i < k; i++) { for (let k = 0; k < classificationResults.length; k++) { if (classificationResults[k].c == distances[i].c) { classificationResults[k].count++; } } } classificationResults.sort(function (a, b) { return b.count - a.count; }); return classificationResults[0].c; } function l2Distance(point1, point2) { return Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2)); } function drawPoints() { var canvas = document.getElementById("g"); for (let i = 0; i < datas.length; i++) { let circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');; circle.setAttributeNS(null, "cx", datas[i].x); circle.setAttributeNS(null, "cy", datas[i].y); circle.setAttributeNS(null, "r", 3); if (datas[i].c == 1) circle.setAttributeNS(null, "fill", "red"); else if (datas[i].c == 2) circle.setAttributeNS(null, "fill", "green"); else circle.setAttributeNS(null, "fill", "purple"); canvas.appendChild(circle); } } function drawCurrentPoint() { var canvas = document.getElementById("g"); let circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); circle.setAttributeNS(null, "cx", point.x); circle.setAttributeNS(null, "cy", point.y); circle.setAttributeNS(null, "r", 3); circle.setAttributeNS(null, "fill", "orange"); canvas.appendChild(circle); } function setValues() { k = parseFloat(document.getElementById("pk").value); point.x = parseFloat(document.getElementById("pX").value); point.y = parseFloat(document.getElementById("pY").value); }HTML Codes:
<div> <input id="pk" type="text" value="3" />->k </div> <div> <input id="pX" type="text" value="0" />->X </div> <div> <input id="pY" type="text" value="0" />->Y </div> <div id="resultDiv" style="margin-top: 20px;"></div> <div style="margin-top: 20px;"> <button onclick="start()" type="button">CLASSIFY</button> </div> <div style="margin-top: 50px;"> <svg height="500" id="canvas" width="500"> <g id="g" transform="translate(250 250) scale(1,-1)"> <line style="stroke-width: 1; stroke: rgb(0, 0, 255);" x1="-1000" x2="1000" y1="0" y2="0"></line> <line style="stroke-width: 1; stroke: rgb(0, 0, 255);" x1="0" x2="0" y1="-1000" y2="1000"></line> </g> </svg> </div>