Perceptron (unfinished)
This commit is contained in:
parent
3a30bab4bc
commit
84a1b61477
73
src/machine_learning/perceptron/Perceptron.java
Normal file
73
src/machine_learning/perceptron/Perceptron.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
90
src/machine_learning/perceptron/Vector.java
Normal file
90
src/machine_learning/perceptron/Vector.java
Normal 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("]", ")");
|
||||||
|
}
|
||||||
|
}
|
39
test/machine_learning/perceptron/PerceptronTest.java
Normal file
39
test/machine_learning/perceptron/PerceptronTest.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
58
test/machine_learning/perceptron/VectorTest.java
Normal file
58
test/machine_learning/perceptron/VectorTest.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user