Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 25 - refractored java files #37

Merged
merged 2 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion example/src/main/java/de/example/benchmark/Benchmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ private void run() {
});


//Sort and print results with numeration begin with best average accuracy
System.out.println("Classifier performances (sorted by average accuracy):");
results.entrySet().stream()
.map(entry -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public double[][] getTestLabels() {
}

private double[][] featuresOf(List<Penguin> data) {
double[][] features = new double[data.size()][4]; // 4 numerische Eigenschaften
double[][] features = new double[data.size()][4];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand All @@ -159,7 +159,7 @@ private double[][] featuresOf(List<Penguin> data) {
}

private double[][] labelsOf(List<Penguin> data) {
double[][] labels = new double[data.size()][3]; // 3 Pinguinarten
double[][] labels = new double[data.size()][3];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public double[][] getTestLabels() {
}

private double[][] featuresOf(List<Penguin> data) {
double[][] features = new double[data.size()][4]; // 4 numerische Eigenschaften
double[][] features = new double[data.size()][4];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand All @@ -77,7 +77,7 @@ private double[][] featuresOf(List<Penguin> data) {
return features;
}
private double[][] labelsOf(List<Penguin> data) {
double[][] labels = new double[data.size()][3]; // 3 Pinguinarten
double[][] labels = new double[data.size()][3];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,16 @@ public class DecisionTreeExample {
private static final boolean NORMALIZE = true;

public static void main(String[] args) {
// Get IRIS dataset

var datasetProvider = new IrisProvider(NORMALIZE, SHUFFLE, 0.6);
datasetProvider.printStatistics();

//Get Features and Labels
double[][] features = datasetProvider.getTrainFeatures();
double[][] labels = datasetProvider.getTrainLabels();

// Train Decision Tree
DecisionTree decisionTree = new DecisionTree(8, 2, 1, 4);
decisionTree.train(features, labels);

// Evaluate Decision Tree
double[][] testFeatures = datasetProvider.getTestFeatures();
double[][] testLabels = datasetProvider.getTestLabels();
decisionTree.evaluate(testFeatures, testLabels);
Expand Down
2 changes: 1 addition & 1 deletion example/src/main/java/de/example/knn/KnnIrisExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static void main(String[] args) {
irisDataProcessor.split(data, TRAIN_TEST_SPLIT_RATIO);

Classifier knn = new KnnClassifier(2);
//Train and evaluate

knn.train(irisDataProcessor.getTrainFeatures(), irisDataProcessor.getTrainLabels());
knn.evaluate(irisDataProcessor.getTestFeatures(), irisDataProcessor.getTestLabels());
}
Expand Down
5 changes: 2 additions & 3 deletions example/src/main/java/de/example/knn/KnnSeabornExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ public class KnnSeabornExample {
private static final File CSV_FILE = new File("example" + File.separator + "datasets" + File.separator + "seaborn-penguins" + File.separator + "penguins.csv");

public static void main(String[] args) {
//Load Data, shuffle, normalize, filter incomplete records out.
var seabornDataProcessor = new SeabornDataProcessor();
List<Penguin> data = seabornDataProcessor.loadDataSetFromCSV(CSV_FILE, ',', SHUFFLE, NORMALIZE, FILTER_INCOMPLETE_RECORDS);
//Split dataset into train and test

Dataset<Penguin> dataset = seabornDataProcessor.split(data, TRAIN_TEST_SPLIT_RATIO);
var seabornProvider = new SeabornProvider(data, dataset.trainData(), dataset.testData());
seabornProvider.printStatistics();

Classifier knn = new KnnClassifier(2);
//Train and evaluate
knn.train(seabornProvider.getTrainFeatures(), seabornProvider.getTrainLabels());
knn.evaluate(seabornProvider.getTestFeatures(), seabornProvider.getTestLabels());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@ public class MultilayerPerceptronExample {
private final static boolean NORMALIZE = true;

public static void main(String[] args) {
// Get IRIS dataset
var datasetProvider = new IrisProvider(NORMALIZE, SHUFFLE, 0.7);
datasetProvider.printStatistics();

//Get Features and Labels
double[][] features = datasetProvider.getTrainFeatures();
double[][] labels = datasetProvider.getTrainLabels();

//Get Test Features and Labels
double[][] testFeatures = datasetProvider.getTestFeatures();
double[][] testLabels = datasetProvider.getTestLabels();

Expand Down
5 changes: 1 addition & 4 deletions example/src/main/java/de/example/svm/SVMExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ public static void main(String[] args){
var datasetProvider = new IrisProvider(NORMALIZE, SHUFFLE, 0.6);
datasetProvider.printStatistics();

//Get Features and Labels
var features = datasetProvider.getTrainFeatures();
// 1 - SATOSA 2 - VERSICOLOR 3 - VIRGINICA
var labels = datasetProvider.getTrainLabels();


Classifier supportVectorMachine = new SupportVectorMachine(SVMKernel.LINEAR, 1);
//ONEvsONE Strategy

supportVectorMachine.train(features, labels);

double[][] testFeatures = datasetProvider.getTestFeatures();
Expand Down
6 changes: 3 additions & 3 deletions lib/src/main/java/de/edux/data/reader/CSVIDataReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
public class CSVIDataReader implements IDataReader {

public List<String[]> readFile(File file, char separator) {
CSVParser csvParser = new CSVParserBuilder().withSeparator(separator).build(); // custom separator
CSVParser customCSVParser = new CSVParserBuilder().withSeparator(separator).build();
List<String[]> result;
try(CSVReader reader = new CSVReaderBuilder(
new FileReader(file))
.withCSVParser(csvParser) // custom CSV parser
.withSkipLines(1) // skip the first line, header info
.withCSVParser(customCSVParser)
.withSkipLines(1)
.build()){
result = reader.readAll();
} catch (CsvException | IOException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package de.edux.functions.initialization;

public enum Initialization {
//Xavier and HE
XAVIER {
@Override
public double[] weightInitialization(int inputSize, double[] weights) {
Expand Down
16 changes: 13 additions & 3 deletions lib/src/main/java/de/edux/ml/nn/network/MultilayerPerceptron.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,32 @@ public MultilayerPerceptron(NetworkConfiguration config, double[][] testFeatures
}

private double[] feedforward(double[] input) {
double[] currentInput = input;

double[] currentInput = passInputTroughAllHiddenLayers(input);

double[] output = passInputTroughOutputLayer(currentInput);

return outputLayerActivationFunction.calculateActivation(output);
}

private double[] passInputTroughAllHiddenLayers(double[] input) {
double[] currentInput = input;
for (Neuron[] layer : hiddenLayers) {
double[] hiddenOutputs = new double[layer.length];
for (int i = 0; i < layer.length; i++) {
hiddenOutputs[i] = layer[i].calculateOutput(currentInput);
}
currentInput = hiddenOutputs;
}
return currentInput;
}

private double[] passInputTroughOutputLayer(double[] currentInput) {
double[] output = new double[config.outputSize()];
for (int i = 0; i < config.outputSize(); i++) {
output[i] = outputLayer[i].calculateOutput(currentInput);
}

return outputLayerActivationFunction.calculateActivation(output);
return output;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ public double[] predict(double[] feature) {
for (Future<double[]> future : futures) {
try {
double[] prediction = future.get();
/* voteMap.merge(prediction, 1L, Long::sum);*/
double label = getIndexOfHighestValue(prediction);
voteMap.merge(label, 1L, Long::sum);
} catch (InterruptedException | ExecutionException e) {
Expand Down
2 changes: 0 additions & 2 deletions lib/src/main/java/de/edux/ml/svm/ISupportVectorMachine.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ public interface ISupportVectorMachine {

void train(double[][] features, int[] labels);

// Methode zum Klassifizieren eines einzelnen Datenpunkts
int predict(double[] features);

// Methode zum Evaluieren der Leistung der SVM auf einem Testdatensatz
double evaluate(double[][] features, int[] labels);
}
9 changes: 1 addition & 8 deletions lib/src/main/java/de/edux/ml/svm/SupportVectorMachine.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,25 @@ public SupportVectorMachine(SVMKernel kernel, double c) {
@Override
public boolean train(double[][] features, double[][] labels) {
var oneDLabels = convert2DLabelArrayTo1DLabelArray(labels);
// Identify unique class labels
Set<Integer> uniqueLabels = Arrays.stream(oneDLabels).boxed().collect(Collectors.toSet());
Integer[] uniqueLabelsArray = uniqueLabels.toArray(new Integer[0]);

// In One-vs-One, you should consider every possible pair of classes
for (int i = 0; i < uniqueLabelsArray.length; i++) {
for (int j = i + 1; j < uniqueLabelsArray.length; j++) {
String key = uniqueLabelsArray[i] + "-" + uniqueLabelsArray[j];
SVMModel model = new SVMModel(kernel, c);

// Filter the features and labels for the two classes
List<double[]> list = new ArrayList<>();
List<Integer> pairLabelsList = new ArrayList<>();
for (int k = 0; k < features.length; k++) {
if (oneDLabels[k] == uniqueLabelsArray[i] || oneDLabels[k] == uniqueLabelsArray[j]) {
list.add(features[k]);
// Ensure that the sign of the label matches our assumption
pairLabelsList.add(oneDLabels[k] == uniqueLabelsArray[i] ? 1 : -1);
}
}
double[][] pairFeatures = list.toArray(new double[0][]);
int[] pairLabels = pairLabelsList.stream().mapToInt(Integer::intValue).toArray();

// Train the model on the pair
model.train(pairFeatures, pairLabels);
models.put(key, model);
}
Expand All @@ -76,18 +71,16 @@ public boolean train(double[][] features, double[][] labels) {
@Override
public double[] predict(double[] features) {
Map<Integer, Integer> voteCount = new HashMap<>();
// In One-vs-One, you look at the prediction of each model and count the votes

for (Map.Entry<String, SVMModel> entry : models.entrySet()) {
int prediction = entry.getValue().predict(features);

// map prediction back to actual class label
String[] classes = entry.getKey().split("-");
int classLabel = (prediction == 1) ? Integer.parseInt(classes[0]) : Integer.parseInt(classes[1]);

voteCount.put(classLabel, voteCount.getOrDefault(classLabel, 0) + 1);
}

// The final prediction is the class with the most votes
int prediction = voteCount.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey();
double[] result = new double[models.size()];
result[prediction - 1] = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ private DataProcessor<String> getDummyDataUtil() {

@Override
public void normalize(List<String> dataset) {
// Mock normalize for the sake of testing
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public double[][] getTestLabels() {
}

private double[][] featuresOf(List<Penguin> data) {
double[][] features = new double[data.size()][4]; // 4 numerische Eigenschaften
double[][] features = new double[data.size()][4];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand All @@ -157,7 +157,7 @@ private double[][] featuresOf(List<Penguin> data) {
}

private double[][] labelsOf(List<Penguin> data) {
double[][] labels = new double[data.size()][3]; // 3 Pinguinarten
double[][] labels = new double[data.size()][3];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand Down
4 changes: 2 additions & 2 deletions lib/src/test/java/de/edux/data/provider/SeabornProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public double[][] getTrainFeatures() {
}

private double[][] featuresOf(List<Penguin> data) {
double[][] features = new double[data.size()][4]; // 4 numerische Eigenschaften
double[][] features = new double[data.size()][4];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand All @@ -70,7 +70,7 @@ public double[][] getTrainLabels() {
}

private double[][] labelsOf(List<Penguin> data) {
double[][] labels = new double[data.size()][3]; // 3 Pinguinarten
double[][] labels = new double[data.size()][3];

for (int i = 0; i < data.size(); i++) {
Penguin p = data.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

public class ActivationFunctionTest {

private static final double DELTA = 1e-6; // used to compare floating point numbers
private static final double DELTA = 1e-6;

@Test
public void testSigmoid() {
Expand Down