Skip to content

Commit

Permalink
Merge pull request #37 from acsolle66/issue25
Browse files Browse the repository at this point in the history
Issue 25 - refractored java files
  • Loading branch information
Samyssmile authored Oct 11, 2023
2 parents f81766c + f1e8ce8 commit 0d8f804
Show file tree
Hide file tree
Showing 18 changed files with 31 additions and 44 deletions.
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

0 comments on commit 0d8f804

Please sign in to comment.