Added kNearestNeighbour and refactored Vector to a package level above and added a constructor

This commit is contained in:
Niklas Birk
2019-06-27 00:01:49 +02:00
parent 5264853c8e
commit 54cfe2dece
7 changed files with 189 additions and 21 deletions

View File

@ -1,4 +1,4 @@
package machine_learning.perceptron;
package machine_learning;
import java.util.*;
import java.util.stream.Collectors;
@ -10,12 +10,16 @@ public class Vector
public Vector(int dim)
{
this.values = new ArrayList<>();
this(IntStream.range(0, dim)
.mapToDouble(i -> 0d)
.toArray());
}
for (int i = 0; i < dim; i++)
{
this.values.add(0d);
}
public Vector(double... value)
{
this(Arrays.stream(value)
.boxed()
.collect(Collectors.toList()));
}
public Vector(List<Double> values)
@ -66,6 +70,14 @@ public class Vector
.sum());
}
public double distance(Vector b)
{
return Math.sqrt(IntStream.range(0,
this.dimension())
.mapToDouble(i -> (this.get(i) - b.get(i)) * (this.get(i) - b.get(i)))
.sum());
}
public Vector divide(double div)
{
var divided = new ArrayList<Double>();

View File

@ -0,0 +1,7 @@
package machine_learning.nearest_neighbour;
public enum DataClass
{
POSITIVE,
NEGATIVE
}

View File

@ -0,0 +1,8 @@
package machine_learning.nearest_neighbour;
import machine_learning.Vector;
public interface Distance
{
double distance(Vector a, Vector b);
}

View File

@ -0,0 +1,67 @@
package machine_learning.nearest_neighbour;
import machine_learning.Vector;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class KNearestNeighbour
{
private Distance distance;
private int k;
public KNearestNeighbour(Distance distance)
{
this(distance, 1);
}
public KNearestNeighbour(Distance distance, int k)
{
this.distance = distance;
this.k = k;
}
public DataClass kNearestNeighbour(List<Vector> positives, List<Vector> negatives, Vector toClassify)
{
var nearestNeighbours = this.nearestNeighbours(
Stream.concat(positives.stream(), negatives.stream())
.collect(Collectors.toList()),
toClassify
);
var positivesWithNearestNeighboursAmount = nearestNeighbours.stream()
.filter(positives::contains)
.count();
var negativesWithNearestNeighboursAmount = nearestNeighbours.stream()
.filter(negatives::contains)
.count();
if (positivesWithNearestNeighboursAmount > negativesWithNearestNeighboursAmount)
{
return DataClass.POSITIVE;
}
else if (positivesWithNearestNeighboursAmount < negativesWithNearestNeighboursAmount)
{
return DataClass.NEGATIVE;
}
return new Random().nextBoolean() ? DataClass.POSITIVE : DataClass.NEGATIVE;
}
private List<Vector> nearestNeighbours(List<Vector> vectors, Vector vector)
{
var nearestNeighbours = vectors.stream()
.map(v -> Map.entry(this.distance.distance(v, vector), v))
.sorted((e1, e2) -> e1.getKey() >= e2.getKey() ? (e1.getKey().equals(e2.getKey()) ? 0 : 1) : -1)
.map(Map.Entry::getValue)
.collect(Collectors.toList());
return nearestNeighbours.subList(0, this.k);
}
}

View File

@ -1,5 +1,7 @@
package machine_learning.perceptron;
import machine_learning.Vector;
import java.util.List;
public class Perceptron