From fdec43737decd958e31da04bfcebd60e973d3858 Mon Sep 17 00:00:00 2001 From: "Bernhard J. Berger" <bernhard.berger@uni-bremen.de> Date: Wed, 18 Jan 2023 09:37:59 +0100 Subject: [PATCH] Automatic scaling of values. --- .../svr/GaussianKernelSVRFunctionFactory.java | 40 +++++++++++++------ .../HellingerKernelSVRFunctionFactory.java | 27 ++++++++++++- ...rbolicTangentKernelSVRFunctionFactory.java | 27 ++++++++++++- .../surrogate/svr/KernelBasedSVRFunction.java | 23 +++++++++-- .../svr/KernelBasedSVRFunctionFactory.java | 40 +++++++++++++++++-- .../LaplacianKernelSVRFunctionFactory.java | 27 ++++++++++++- .../svr/LinearKernelSVRFunctionFactory.java | 27 ++++++++++++- .../svr/PearsonKernelSVRFunctionFactory.java | 27 ++++++++++++- .../PolynomialKernelSVRFunctionFactory.java | 27 ++++++++++++- ...inPlateSplineKernelSVRFunctionFactory.java | 27 ++++++++++++- 10 files changed, 266 insertions(+), 26 deletions(-) diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/GaussianKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/GaussianKernelSVRFunctionFactory.java index 5cc2dcdd..683dc8b1 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/GaussianKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/GaussianKernelSVRFunctionFactory.java @@ -1,25 +1,14 @@ package de.evoal.surrogate.svr; import de.evoal.core.api.properties.PropertiesSpecification; -import de.evoal.core.api.properties.stream.PropertiesPairStreamSupplier; -import de.evoal.core.api.utils.Requirements; import de.evoal.surrogate.api.configuration.Parameter; import de.evoal.surrogate.api.configuration.PartialFunctionConfiguration; -import de.evoal.surrogate.api.function.AbstractPartialSurrogateFunctionFactory; import de.evoal.surrogate.api.function.PartialSurrogateFunction; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import smile.math.kernel.MercerKernel; import smile.regression.KernelMachine; -import smile.regression.SVR; import javax.enterprise.context.Dependent; import javax.inject.Named; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; @Dependent @Named("gaussian-svr") @@ -41,6 +30,33 @@ public class GaussianKernelSVRFunctionFactory extends KernelBasedSVRFunctionFact .findFirst() .orElse(0.1); - return new KernelBasedSVRFunction(configuration, regression, "gaussian", requiredInput, actualInput, producedOutput, margin); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + + + + return new KernelBasedSVRFunction(configuration, regression, "gaussian", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HellingerKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HellingerKernelSVRFunctionFactory.java index 01b5f81b..981ec17a 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HellingerKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HellingerKernelSVRFunctionFactory.java @@ -30,6 +30,31 @@ public class HellingerKernelSVRFunctionFactory extends KernelBasedSVRFunctionFac .findFirst() .orElse(0.1); - return new KernelBasedSVRFunction(configuration, regression, "hellinger", requiredInput, actualInput, producedOutput, margin); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + + return new KernelBasedSVRFunction(configuration, regression, "hellinger", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HyperbolicTangentKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HyperbolicTangentKernelSVRFunctionFactory.java index 5b221072..45cf4e7b 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HyperbolicTangentKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/HyperbolicTangentKernelSVRFunctionFactory.java @@ -29,7 +29,32 @@ public class HyperbolicTangentKernelSVRFunctionFactory extends KernelBasedSVRFun .map(Double.class::cast) .findFirst() .orElse(0.1); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; - return new KernelBasedSVRFunction(configuration, regression, "hyperbolic-tangent", requiredInput, actualInput, producedOutput, margin); + + return new KernelBasedSVRFunction(configuration, regression, "hyperbolic-tangent", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunction.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunction.java index 550e5994..2e295396 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunction.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunction.java @@ -3,6 +3,7 @@ package de.evoal.surrogate.svr; import de.evoal.core.api.properties.Properties; import de.evoal.core.api.properties.PropertiesSpecification; import de.evoal.languages.model.ddl.RepresentationType; +import de.evoal.surrogate.api.configuration.Parameter; import de.evoal.surrogate.api.configuration.PartialFunctionConfiguration; import de.evoal.surrogate.api.function.AbstractPartialSurrogateFunction; @@ -33,9 +34,17 @@ public class KernelBasedSVRFunction extends AbstractPartialSurrogateFunction { * Actual SVR */ private final KernelMachine<double []> regression; + private final double[] sourceMeans; + private final double[] sourceSDs; + private final double[] targetMeans; + private final double[] targetSDs; - public KernelBasedSVRFunction(final PartialFunctionConfiguration configuration, final KernelMachine<double []> regression, final String kernelName, final PropertiesSpecification input, final PropertiesSpecification actualInput, final PropertiesSpecification output, final double gamma) { + public KernelBasedSVRFunction(final PartialFunctionConfiguration configuration, final KernelMachine<double []> regression, final String kernelName, final PropertiesSpecification input, final PropertiesSpecification actualInput, final PropertiesSpecification output, final double gamma, final double[] sourceMeans, final double[] sourceSDs, final double[] targetMeans, final double[] targetSDs) { super(configuration, KernelHelper.toParameters(regression, kernelName), input, output); + this.sourceMeans = sourceMeans; + this.sourceSDs = sourceSDs; + this.targetMeans = targetMeans; + this.targetSDs = targetSDs; final List<Function<Properties, Double>> inputConverts = new LinkedList<>(); @@ -58,6 +67,14 @@ public class KernelBasedSVRFunction extends AbstractPartialSurrogateFunction { this.regression = regression; this.gamma = gamma; + + final List<Parameter> parameters = new LinkedList<>(); + addParameter("kernel-source-means", sourceMeans, parameters); + addParameter("kernel-source-sds", sourceSDs, parameters); + addParameter("kernel-target-means", targetMeans, parameters); + addParameter("kernel-target-sds", targetSDs, parameters); + + getParameters().addAll(parameters); } @Override @@ -65,10 +82,10 @@ public class KernelBasedSVRFunction extends AbstractPartialSurrogateFunction { final double [] inputData = new double[indices.length]; for(int i = 0; i < inputData.length; ++i) { - inputData[i] = inputConverters[i].apply(input); + inputData[i] = (inputConverters[i].apply(input) - sourceMeans[i]) / sourceSDs[i]; } - final double predictedValue = regression.predict(inputData); + final double predictedValue = (regression.predict(inputData) * targetSDs[0]) + targetMeans[0]; final Object [] outputData = new Object[1]; outputData[0] = outputConverter.apply(predictedValue); diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunctionFactory.java index 475658fe..b82cb676 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/KernelBasedSVRFunctionFactory.java @@ -11,13 +11,13 @@ import de.evoal.surrogate.api.configuration.PartialFunctionConfiguration; import de.evoal.surrogate.api.function.AbstractPartialSurrogateFunctionFactory; import de.evoal.surrogate.api.function.PartialSurrogateFunction; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.math3.stat.descriptive.moment.Mean; +import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation; import smile.math.kernel.MercerKernel; import smile.regression.KernelMachine; import smile.regression.SVR; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -60,6 +60,33 @@ public abstract class KernelBasedSVRFunctionFactory extends AbstractPartialSurro double [][] sourceArray = sources.toArray(new double [][] {}); double [] targetArray = targets.stream().mapToDouble(Double.class::cast).toArray(); + double [] sourceMeans = new double [requiredInput.size()]; + double [] sourceSD = new double [requiredInput.size()]; + + double [] targetMean = new double [1]; + double [] targetSD = new double [1]; + + for(int propertyIndex = 0; propertyIndex < requiredInput.size(); ++propertyIndex) { + double [] values = new double [sourceArray.length]; + for(int individualIndex = 0; individualIndex < sourceArray.length; ++individualIndex) { + values[individualIndex] = sourceArray[individualIndex][propertyIndex]; + } + + calculateStatisticalInformation(values, propertyIndex, sourceMeans, sourceSD); + } + calculateStatisticalInformation(targetArray, 0, targetMean, targetSD); + + + // start scaling of trainings data + for(int individualIndex = 0; individualIndex < sourceArray.length; ++individualIndex) { + for (int propertyIndex = 0; propertyIndex < requiredInput.size(); ++propertyIndex) { + sourceArray[individualIndex][propertyIndex] = (sourceArray[individualIndex][propertyIndex] - sourceMeans[propertyIndex]) / sourceSD[propertyIndex]; + + } + targetArray[individualIndex] = (targetArray[individualIndex] - targetMean[0]) / targetSD[0]; + } + + final Map<String, Object> params = parameters.stream() .collect(Collectors.toMap(Parameter::getName, Parameter::getValue)); @@ -69,7 +96,12 @@ public abstract class KernelBasedSVRFunctionFactory extends AbstractPartialSurro final KernelMachine<double []> regression = SVR.fit(sourceArray, targetArray, toKernel.apply(params), epsilon, margin, tolerance); - return new KernelBasedSVRFunction(configuration, regression, nameOfKernel, requiredInput, actualInput, producedOutput, margin); + return new KernelBasedSVRFunction(configuration, regression, nameOfKernel, requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSD, targetMean, targetSD); + } + + private void calculateStatisticalInformation(final double[] values, final int index, final double[] means, final double[] sds) { + means[index] = new Mean().evaluate(values, 0, values.length); + sds[index] = new StandardDeviation().evaluate(values); } /** diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LaplacianKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LaplacianKernelSVRFunctionFactory.java index 537cc924..34422492 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LaplacianKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LaplacianKernelSVRFunctionFactory.java @@ -29,7 +29,32 @@ public class LaplacianKernelSVRFunctionFactory extends KernelBasedSVRFunctionFac .map(Double.class::cast) .findFirst() .orElse(0.1); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; - return new KernelBasedSVRFunction(configuration, regression, "laplacian", requiredInput, actualInput, producedOutput, margin); + + return new KernelBasedSVRFunction(configuration, regression, "laplacian", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LinearKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LinearKernelSVRFunctionFactory.java index 2c14a66b..8ecab5a5 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LinearKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/LinearKernelSVRFunctionFactory.java @@ -30,6 +30,31 @@ public class LinearKernelSVRFunctionFactory extends KernelBasedSVRFunctionFactor .findFirst() .orElse(0.1); - return new KernelBasedSVRFunction(configuration, regression, "linear", requiredInput, actualInput, producedOutput, margin); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + + return new KernelBasedSVRFunction(configuration, regression, "linear", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PearsonKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PearsonKernelSVRFunctionFactory.java index 87043f92..bb424761 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PearsonKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PearsonKernelSVRFunctionFactory.java @@ -30,6 +30,31 @@ public class PearsonKernelSVRFunctionFactory extends KernelBasedSVRFunctionFacto .findFirst() .orElse(0.1); - return new KernelBasedSVRFunction(configuration, regression, "pearson", requiredInput, actualInput, producedOutput, margin); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + + return new KernelBasedSVRFunction(configuration, regression, "pearson", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PolynomialKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PolynomialKernelSVRFunctionFactory.java index 42d8cd8f..e8f0963f 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PolynomialKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/PolynomialKernelSVRFunctionFactory.java @@ -29,7 +29,32 @@ public class PolynomialKernelSVRFunctionFactory extends KernelBasedSVRFunctionFa .map(Double.class::cast) .findFirst() .orElse(0.1); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; - return new KernelBasedSVRFunction(configuration, regression, "polynomial", requiredInput, actualInput, producedOutput, margin); + + return new KernelBasedSVRFunction(configuration, regression, "polynomial", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/ThinPlateSplineKernelSVRFunctionFactory.java b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/ThinPlateSplineKernelSVRFunctionFactory.java index a7559ce8..bee225e8 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/ThinPlateSplineKernelSVRFunctionFactory.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/de/evoal/surrogate/svr/ThinPlateSplineKernelSVRFunctionFactory.java @@ -30,6 +30,31 @@ public class ThinPlateSplineKernelSVRFunctionFactory extends KernelBasedSVRFunct .findFirst() .orElse(0.1); - return new KernelBasedSVRFunction(configuration, regression, "thin-plate-spine-svr", requiredInput, actualInput, producedOutput, margin); + final double[] sourceMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get(); + final double[] sourceSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-source-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetMeans = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-means".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + final double[] targetSDs = (double [])configuration.getState() + .stream() + .filter(p -> "kernel-target-sds".equals(p.getName())) + .map(Parameter::getValue) + .findFirst() + .get();; + + return new KernelBasedSVRFunction(configuration, regression, "thin-plate-spine-svr", requiredInput, actualInput, producedOutput, margin, sourceMeans, sourceSDs, targetMeans, targetSDs); } } -- GitLab