i'm trying to create a program about KNN method and now I'm stuck in loop for determining the class. Here's my coding :
public static void main(String[] args) {
int titikx, titiky, k;
int[] titikxl = new int[]{1, 1, 3, 2, 4, 6}; //first feature
int[] titiky1 = new int[]{1, 3, 1, 5, 3, 2}; //second feature
ArrayList<Double> nx = new ArrayList<Double>(), ny = new ArrayList<Double>(),
fn = new ArrayList<Double>(), arclass1 = new ArrayList<Double>(),
arclass2 = new ArrayList<Double>();
//input hew data's features and k
Scanner input = new Scanner(System.in);
System.out.println("Input first feature : ");
titikx = input.nextInt();
System.out.println("Input second feature : ");
titiky = input.nextInt();
System.out.println("Input k : ");
k = input.nextInt();
//count distance between new data and training data
int i = 0, j = 0;
while(i < titikxl.length || j <titiky1.length){
nx.add(Math.pow(titikx - titikxl[i], 2));
ny.add(Math.pow(titiky - titiky1[j], 2));
i++;
j++;
}
System.out.println(nx);
System.out.println(ny);
//convert arraylist to array
Double[] nxarray = nx.toArray(new Double[nx.size()]);
Double[] nyarray = ny.toArray(new Double[ny.size()]);
//sum the array of distance first feature and second feature to get result
int ii = 0, jj = 0;
while (ii < nxarray.length || jj < nyarray.length){
fn.add(Math.sqrt(nxarray[ii] + nyarray[jj]));
ii++;
jj++;
}
System.out.println(fn);
Double[] fnarray = fn.toArray(new Double[fn.size()]);
Double[] oldfnarray = fnarray; //array result before sort ascending
//ascending array
for(int id1 = 0; id1 < fnarray.length; id1++){
for(int id2 = id1 + 1; id2 < fnarray.length; id2++){
if(fnarray[id1]>fnarray[id2]){
double temp = fnarray[id2];
fnarray[id2] = fnarray[id1];
fnarray[id1] = temp;
}
}
}
for(int id = 0; id < fnarray.length; id++){
System.out.print(fnarray[id] + " ");
}
System.out.println();
double[] classa = new double[]{oldfnarray[0], oldfnarray[1], oldfnarray[2]};
double[] classb = new double[]{oldfnarray[3], oldfnarray[4], oldfnarray[5]};
//determining what class the new data belongs
for(int idb = 0; idb < classa.length; idb++){
for(int idc = 0; idc < classb.length; idc++){
for(int ida = 0; ida < fnarray.length; ida++){
while(ida < k){
if (classa[idb] == fnarray[ida]){
arclass1.add(fnarray[ida]);
}
if (classb[idc] == fnarray[ida]){
arclass2.add(fnarray[ida]);
}
}
}
}
}
if(arclass1.size() < arclass2.size()){
System.out.println("The Class is B");
} else{
System.out.println("The Class is A");
}
}
And the result is :
Input first feature : 2
Input second feature : 3
Input k : 3
[1.0, 1.0, 1.0, 0.0, 4.0, 16.0] //distance feature x
[4.0, 0.0, 4.0, 4.0, 0.0, 1.0] //distance feature y
[2.23606797749979, 1.0, 2.23606797749979, 2.0, 2.0, 4.123105625617661] //result
1.0 2.0 2.0 2.23606797749979 2.23606797749979 4.123105625617661 //ascended result
//looping forever
BUILD STOPPED (total time: 35 seconds)
As you can see, in the section determining class, when enter the loop the program seems doing the last loop forever. I try to modified it as capable as I could, yet still there's no result but error and running forever. Please help. Thank you most kindly.
The problem is the endless while loop - ida's value never changes. I suggest modifying the entire code block because it is more complicated than it needs to be.
Before coming up with a solution, let's determine what we already know:
k-neighbors (the sorted distances array, with indexes smaller than k)It becomes obvious that in order to determine the class, we need to:
A (we need a first inner loop) or class B (we need second inner loop)A, we increase counter for class A, otherwise we do that for class BA is greater, then the feature belongs in class A, otherwise in class BTo better understand what is going on, the k-NN classification algorithm is described comprehensively in this tutorial.
Code (same structure as yours, though I renamed variables and simplified some parts for readability):
import java.util.Arrays;
import java.util.Scanner;
public class KNN {
public static void main(String[] args) {
int[] feature1 = new int[] { 1, 1, 3, 2, 4, 6 };
int[] feature2 = new int[] { 1, 3, 1, 5, 3, 2 };
//input hew data's features and k
Scanner input = new Scanner(System.in);
System.out.println("Input first feature : ");
int newFeature1 = input.nextInt();
System.out.println("Input second feature : ");
int newFeature2 = input.nextInt();
System.out.println("Input k : ");
int k = input.nextInt();
input.close();
//count distance between new data and training data
double[] distances1 = new double[feature1.length];
double[] distances2 = new double[feature2.length];
for (int i = 0; i < distances1.length; i++) {
distances1[i] = Math.pow(newFeature1 - feature1[i], 2);
}
for (int i = 0; i < distances2.length; i++) {
distances2[i] = Math.pow(newFeature2 - feature2[i], 2);
}
System.out.println("Distance between first feature and first feature training data: " + Arrays.toString(distances1));
System.out.println("Distance between second feature and second feature training data: " + Arrays.toString(distances2));
//sum the array of distance first feature and second feature to get result
double[] distanceSums = new double[distances1.length];
for (int i = 0; i < distances1.length; i++) {
distanceSums[i] = Math.sqrt(distances1[i] + distances2[i]);
}
System.out.println("Distance sums: " + Arrays.toString(distanceSums));
// sort array ascending
double[] distanceSumsSorted = new double[distanceSums.length];
System.arraycopy(distanceSums, 0, distanceSumsSorted, 0, distanceSums.length);
Arrays.sort(distanceSumsSorted);
System.out.println("Sorted distance sums: " + Arrays.toString(distanceSumsSorted));
double[] classAMembers = new double[] { distanceSums[0], distanceSums[1], distanceSums[2] };
double[] classBMembers = new double[] { distanceSums[3], distanceSums[4], distanceSums[5] };
//determining what class the new data belongs
int classACounts = 0;
int classBCounts = 0;
for (int i = 0; i < k; i++) {
// check if nearest neighbor belongs to class A
for (int j = 0; j < classAMembers.length; j++) {
if (distanceSumsSorted[i] == classAMembers[j]) {
classACounts++;
break;
}
}
// check if nearest neighbor belongs to class B
for (int j = 0; j < classBMembers.length; j++) {
if (distanceSumsSorted[i] == classBMembers[j]) {
classBCounts++;
break;
}
}
}
System.out.println("Class A members: " + Arrays.toString(classAMembers));
System.out.println("Class B members: " + Arrays.toString(classBMembers));
System.out.println("Counts for class A: " + classACounts);
System.out.println("Counts for class B: " + classBCounts);
if (classACounts < classBCounts){
System.out.println("The Class is B.");
}
else {
System.out.println("The Class is A.");
}
}
}
For your example data the program outputs:
Input first feature : 2
Input second feature : 3
Input k : 3
Distance between first feature and first feature training data: [1.0, 1.0, 1.0, 0.0, 4.0, 16.0]
Distance between second feature and second feature training data: [4.0, 0.0, 4.0, 4.0, 0.0, 1.0]
Distance sums: [2.23606797749979, 1.0, 2.23606797749979, 2.0, 2.0, 4.123105625617661]
Sorted distance sums: [1.0, 2.0, 2.0, 2.23606797749979, 2.23606797749979, 4.123105625617661]
Class A members: [2.23606797749979, 1.0, 2.23606797749979]
Class B members: [2.0, 2.0, 4.123105625617661]
Counts for class A: 1
Counts for class B: 2
The Class is B.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With