Perceptron (unfinished)

This commit is contained in:
Niklas Birk 2019-06-20 13:17:23 +02:00
parent 3a30bab4bc
commit 84a1b61477
4 changed files with 260 additions and 0 deletions

View File

@ -0,0 +1,73 @@
package machine_learning.perceptron;
import java.util.List;
public class Perceptron
{
public void learn(List<Vector> positives, List<Vector> negatives)
{
var weight = this.getInitializationVector(positives, negatives);
do
{
for (var x : positives)
{
if (weight.scalar(x) <= 0)
{
weight = weight.add(x);
}
}
for (var x : negatives)
{
if (weight.scalar(x) > 0)
{
weight = weight.subtract(x);
}
}
System.out.println(weight);
}
while (elementsAreCorrectClassified(positives, weight, 1) && elementsAreCorrectClassified(negatives, weight, 0));
System.out.println("-----------------------------------");
System.out.println("-- All are classified correctly. --");
System.out.println("-----------------------------------");
}
private Vector getInitializationVector(List<Vector> positives, List<Vector> negatives)
{/*
var a = new Vector(positives.get(0).dimension());
for (var x : positives)
{
a = a.add(x);
}
var b = new Vector(positives.get(0).dimension());
for (var x : negatives)
{
b = b.add(x);
}
return a.subtract(b);*/
return new Vector(positives.get(0).dimension());
}
private boolean elementsAreCorrectClassified(List<Vector> vectors, Vector weight, int expectedClass)
{
int actualClass;
for (var x : vectors)
{
actualClass = weight.scalar(x) > 0 ? 1 : 0;
if (actualClass != expectedClass)
{
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,90 @@
package machine_learning.perceptron;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Vector
{
private List<Double> values;
public Vector(int dim)
{
this.values = new ArrayList<>();
for (int i = 0; i < dim; i++)
{
this.values.add(0d);
}
}
public Vector(List<Double> values)
{
this.values = values;
}
public int dimension()
{
return this.values.size();
}
public Vector add(Vector b)
{
return new Vector(IntStream.range(0,
this.values.size())
.mapToObj(i -> this.values.get(i) + b.values.get(i))
.collect(Collectors.toCollection(ArrayList::new))
);
}
public Vector subtract(Vector b)
{
return new Vector(IntStream.range(0,
this.values.size())
.mapToObj(i -> this.values.get(i) - b.values.get(i))
.collect(Collectors.toCollection(ArrayList::new))
);
}
public double scalar(Vector b)
{
return IntStream.range(0,
this.values.size())
.mapToDouble(i -> this.values.get(i) * b.values.get(i))
.sum();
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
Vector vector = (Vector) o;
return Objects.equals(values, vector.values);
}
@Override
public int hashCode()
{
return values != null ? values.hashCode() : 0;
}
@Override
public String toString()
{
return values.toString()
.replace("[", "(")
.replace("]", ")");
}
}

View File

@ -0,0 +1,39 @@
package machine_learning.perceptron;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import java.util.ArrayList;
import java.util.List;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class PerceptronTest
{
List<Vector> positives;
List<Vector> negatives;
@BeforeAll
void initLearnData()
{
this.positives = new ArrayList<>(List.of(
new Vector(List.of(8d, 4d)),
new Vector(List.of(8d, 6d)),
new Vector(List.of(9d, 2d)),
new Vector(List.of(9d, 5d)))
);
this.negatives = new ArrayList<>(List.of(
new Vector(List.of(6d, 1d)),
new Vector(List.of(7d, 3d)),
new Vector(List.of(8d, 2d)),
new Vector(List.of(9d, 0d)))
);
}
@Test
void shouldClassifyCorrect()
{
new Perceptron().learn(this.positives, this.negatives);
}
}

View File

@ -0,0 +1,58 @@
package machine_learning.perceptron;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class VectorTest
{
@Test
void shouldInitializeZeroVector()
{
var v = new Vector(3);
var expected = new Vector(List.of(0d, 0d, 0d));
assertEquals(3, v.dimension());
assertEquals(expected, v);
}
@Test
void shouldReturnCorrectVectorWhenAdding()
{
var v1 = new Vector(List.of(1d, 2d));
var v2 = new Vector(List.of(3d, 4d));
var result = v1.add(v2);
var expected = new Vector(List.of(4d, 6d));
assertEquals(expected, result);
}
@Test
void shouldReturnCorrectVectorWhenSubtracting()
{
var v1 = new Vector(List.of(1d, 2d));
var v2 = new Vector(List.of(3d, 4d));
var result = v1.subtract(v2);
var expected = new Vector(List.of(-2d, -2d));
assertEquals(expected, result);
}
@Test
void shouldReturnCorrectVectorWhenScalar()
{
var v1 = new Vector(List.of(1d, 2d));
var v2 = new Vector(List.of(3d, 4d));
var result = v1.scalar(v2);
var expected = 11d;
assertEquals(expected, result);
}
}