From 07e134994b0a7294c92c123725600d5ab8f69ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 27 Feb 2023 07:48:05 +0100 Subject: [PATCH 01/67] Fixing and extending OCEL, CELOE, Rho, Multiheuristic, and CWR --- .../celoe/AccuracyBasedComparator.java | 63 +++ .../org/dllearner/algorithms/celoe/CELOE.java | 118 +++++- .../algorithms/ocel/ExampleBasedNode.java | 9 +- .../algorithms/ocel/MultiHeuristic.java | 65 ++-- .../org/dllearner/algorithms/ocel/OCEL.java | 189 +++++++-- .../ocel/QualityBasedComparator.java | 87 +++++ .../java/org/dllearner/core/AbstractCELA.java | 13 +- .../dllearner/learningproblems/PosNegLP.java | 48 +++ .../learningproblems/PosNegLPStandard.java | 3 +- .../reasoning/ClosedWorldReasoner.java | 359 +++++++++--------- .../refinementoperators/RhoDRDown.java | 307 ++++++++++++--- .../utilities/owl/ExpressionDecomposer.java | 167 ++++++++ .../owl/OWLClassExpressionCleaner.java | 10 + .../owl/OWLClassExpressionMinimizer.java | 2 +- interfaces/pom.xml | 8 +- 15 files changed, 1139 insertions(+), 309 deletions(-) create mode 100644 components-core/src/main/java/org/dllearner/algorithms/celoe/AccuracyBasedComparator.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/ocel/QualityBasedComparator.java create mode 100644 components-core/src/main/java/org/dllearner/utilities/owl/ExpressionDecomposer.java diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/AccuracyBasedComparator.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/AccuracyBasedComparator.java new file mode 100644 index 0000000000..5ac2fa46d7 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/AccuracyBasedComparator.java @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2007 - 2016, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.dllearner.algorithms.celoe; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; + +import java.util.Comparator; + +public class AccuracyBasedComparator implements Comparator { + + private final OWLClassExpressionLengthMetric lengthMetric; + + public AccuracyBasedComparator(OWLClassExpressionLengthMetric lengthMetric) { + this.lengthMetric = lengthMetric; + } + + @Override + public int compare(OENode node1, OENode node2) { + int result = compareByAccuracy(node1, node2); + + if (result != 0) { + return result; + } + + return compareByLength(node1, node2); + } + + private int compareByAccuracy(OENode node1, OENode node2) { + double node1Accuracy = node1.getAccuracy(); + double node2Accuracy = node2.getAccuracy(); + + return Double.compare(node1Accuracy, node2Accuracy); + } + + private int compareByLength(OENode node1, OENode node2) { + int node1Length = OWLClassExpressionUtils.getLength(node1.getDescription(), lengthMetric); + int mode2Length = OWLClassExpressionUtils.getLength(node2.getDescription(), lengthMetric); + + return Integer.compare(mode2Length, node1Length); + } + + @Override + public boolean equals(Object o) { + return (o instanceof AccuracyBasedComparator); + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index 369d0d944e..2c02e868af 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -21,6 +21,9 @@ import com.google.common.collect.Sets; import com.jamonapi.Monitor; import com.jamonapi.MonitorFactory; +import org.dllearner.algorithms.ocel.ExampleBasedNode; +import org.dllearner.algorithms.ocel.MultiHeuristic; +import org.dllearner.algorithms.ocel.QualityBasedComparator; import org.dllearner.core.*; import org.dllearner.core.config.ConfigOption; import org.dllearner.core.owl.ClassHierarchy; @@ -50,6 +53,7 @@ import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; import java.io.File; +import java.text.DecimalFormat; import java.util.*; import java.util.concurrent.TimeUnit; @@ -171,6 +175,22 @@ public class CELOE extends AbstractCELA implements Cloneable{ private boolean stopOnFirstDefinition = false; private int expressionTestCountLastImprovement; + + OWLClassExpressionLengthMetric lengthMetric = OWLClassExpressionLengthMetric.getDefaultMetric(); + + private TreeMap solutionCandidates; + private final double solutionCandidatesMinAccuracyDiff = 0.0001; + + @ConfigOption(defaultValue = "0.0", description = "determines a lower bound on noisiness of an expression with respect to noisePercentage " + + "in order to be considered a reasonable solution candidate (must be non-negative), e.g. for noisePercentage = 15 and noisePercentageMargin = 5, " + + "the algorithm will suggest expressions with the number of misclassified positives less than or equal to 20% of all examples " + + "as solution candidates as well; note: difference between accuracies of any two candidates must be at least 0.01% to ensure diversity") + private double noisePercentageMargin = 0.0; + + @ConfigOption(defaultValue = "20", description = "the number of solution candidates within margin to be presented, sorted in descending order by accuracy") + private int maxNrOfResultsWithinMargin = 20; + + private double noiseWithMargin; @SuppressWarnings("unused") @@ -228,6 +248,9 @@ public CELOE(CELOE celoe){ setWriteSearchTree(celoe.writeSearchTree); setReplaceSearchTree(celoe.replaceSearchTree); + + setMaxNrOfResultsWithinMargin(celoe.maxNrOfResultsWithinMargin); + setNoisePercentageMargin(celoe.noisePercentageMargin); } public CELOE(AbstractClassExpressionLearningProblem problem, AbstractReasonerComponent reasoner) { @@ -259,6 +282,11 @@ public void init() throws ComponentInitException { heuristic = new OEHeuristicRuntime(); heuristic.init(); } + + // TODO: MY copy from MultiHeuristic +// if (heuristic instanceof OEHeuristicRuntime) { +// ((OEHeuristicRuntime) heuristic).setLengthMetric(lengthMetric); +// } minimizer = new OWLClassExpressionMinimizer(dataFactory, reasoner); @@ -313,6 +341,17 @@ public void init() throws ComponentInitException { if (!((AbstractRefinementOperator) operator).isInitialized()) operator.init(); + + operator.setLengthMetric(lengthMetric); + + AccuracyBasedComparator solutionComparator = new AccuracyBasedComparator(lengthMetric); + solutionCandidates = new TreeMap<>(solutionComparator); + + if (noisePercentageMargin < 0) { + noisePercentageMargin = 0.0; + } + + noiseWithMargin = (noisePercentage + noisePercentageMargin) / 100.0; initialized = true; } @@ -334,11 +373,13 @@ public void start() { showIfBetterSolutionsFound(); // chose best node according to heuristics +// long s = System.nanoTime(); nextNode = getNextNodeToExpand(); int horizExp = nextNode.getHorizontalExpansion(); // apply refinement operator TreeSet refinements = refineNode(nextNode); +// accTime += (System.nanoTime() - s) / 1000; while(!refinements.isEmpty() && !terminationCriteriaSatisfied()) { // pick element from set @@ -358,7 +399,7 @@ public void start() { showIfBetterSolutionsFound(); // update the global min and max horizontal expansion values - updateMinMaxHorizExp(nextNode); +// updateMinMaxHorizExp(nextNode); // write the search tree (if configured) if (writeSearchTree) { @@ -372,6 +413,8 @@ public void start() { // print some stats printAlgorithmRunStats(); + + printSolutionCandidates(); // print solution(s) logger.info("solutions:\n" + getSolutionString()); @@ -506,7 +549,7 @@ private TreeSet refineNode(OENode node) { MonitorFactory.getTimeMonitor("refineNode").stop(); return refinements; } - + /** * Add node to search tree if it is not too weak. * @return TRUE if node was added and FALSE otherwise @@ -616,7 +659,23 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { // System.out.println(bestEvaluatedDescriptions.getSet().size()); } - + + if (accuracy >= 1 - noiseWithMargin) { + if (solutionCandidates.isEmpty() + || (node.getAccuracy() > solutionCandidates.firstKey().getAccuracy() + && solutionCandidates.keySet().stream().allMatch( + n -> Math.abs(node.getAccuracy() - n.getAccuracy()) > solutionCandidatesMinAccuracyDiff + ) + ) + ) { + solutionCandidates.put(node, getCurrentRuntimeInMilliSeconds() / 1000.0); + } + + if (solutionCandidates.size() > maxNrOfResultsWithinMargin) { + solutionCandidates.pollFirstEntry(); + } + } + return true; } @@ -761,18 +820,45 @@ private void reset() { bestEvaluatedDescriptions.getSet().clear(); expressionTests = 0; runtimeVsBestScore.clear(); + + solutionCandidates.clear(); } private void printAlgorithmRunStats() { if (stop) { logger.info("Algorithm stopped ("+expressionTests+" descriptions tested). " + searchTree.size() + " nodes in the search tree.\n"); + logger.info(reasoner.toString()); } else { totalRuntimeNs = System.nanoTime()-nanoStartTime; logger.info("Algorithm terminated successfully (time: " + Helper.prettyPrintNanoSeconds(totalRuntimeNs) + ", "+expressionTests+" descriptions tested, " + searchTree.size() + " nodes in the search tree).\n"); logger.info(reasoner.toString()); } } - + + private void printSolutionCandidates() { + DecimalFormat df = new DecimalFormat(); + + if (solutionCandidates.size() > 0) { + // we do not need to print the best node if we display the top 20 solutions below anyway + logger.info("solutions within margin (at most " + maxNrOfResultsWithinMargin + " are shown):"); + int show = 1; + for (OENode c : solutionCandidates.descendingKeySet()) { + logger.info(show + ": " + renderer.render(c.getDescription()) + + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " + + df.format(100 * computeTestingAccuracy(c.getDescription())) + "%" + + ", length " + OWLClassExpressionUtils.getLength(c.getDescription()) + + ", depth " + OWLClassExpressionUtils.getDepth(c.getDescription()) + + ", time " + df.format(solutionCandidates.get(c)) + "s)"); + if (show >= maxNrOfResultsWithinMargin) { + break; + } + show++; + } + } else { + logger.info("no appropriate solutions within margin found (try increasing the noisePercentageMargin)"); + } + } + private void showIfBetterSolutionsFound() { if(!singleSuggestionMode && bestEvaluatedDescriptions.getBestAccuracy() > currentHighestAccuracy) { currentHighestAccuracy = bestEvaluatedDescriptions.getBestAccuracy(); @@ -781,14 +867,18 @@ private void showIfBetterSolutionsFound() { long durationInMillis = getCurrentRuntimeInMilliSeconds(); String durationStr = getDurationAsString(durationInMillis); + OWLClassExpression bestDescription = bestEvaluatedDescriptions.getBest().getDescription(); + double testAccuracy = computeTestingAccuracy(bestDescription); + // track new best accuracy if enabled if(keepTrackOfBestScore) { runtimeVsBestScore.put(getCurrentRuntimeInMilliSeconds(), currentHighestAccuracy); } - logger.info("more accurate (" + dfPercent.format(currentHighestAccuracy) + ") class expression found after " + durationStr + ": " + descriptionToString(bestEvaluatedDescriptions.getBest().getDescription())); + + logger.info("more accurate (training: " + dfPercent.format(currentHighestAccuracy) + ", testing: " + dfPercent.format(testAccuracy) + ") class expression found after " + durationStr + ": " + descriptionToString(bestEvaluatedDescriptions.getBest().getDescription())); } } - + private void writeSearchTree(TreeSet refinements) { StringBuilder treeString = new StringBuilder("best node: ").append(bestEvaluatedDescriptions.getBest()).append("\n"); if (refinements.size() > 1) { @@ -1100,6 +1190,22 @@ public SortedMap getRuntimeVsBestScore(long ticksIntervalTimeValue return map; } + public int getMaxNrOfResultsWithinMargin() { + return maxNrOfResultsWithinMargin; + } + + public void setMaxNrOfResultsWithinMargin(int maxNrOfResultsWithinMargin) { + this.maxNrOfResultsWithinMargin = maxNrOfResultsWithinMargin; + } + + public double getNoisePercentageMargin() { + return noisePercentageMargin; + } + + public void setNoisePercentageMargin(double noisePercentageMargin) { + this.noisePercentageMargin = noisePercentageMargin; + } + /* (non-Javadoc) * @see java.lang.Object#clone() */ diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/ExampleBasedNode.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/ExampleBasedNode.java index 5a34f8e10e..3d900ba660 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/ExampleBasedNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/ExampleBasedNode.java @@ -20,10 +20,12 @@ import org.dllearner.core.AbstractCELA; import org.dllearner.core.AbstractSearchTreeNode; +import org.dllearner.core.Heuristic; import org.dllearner.core.StringRenderer; import org.dllearner.learningproblems.PosNegLP; import org.dllearner.utilities.datastructures.SearchTreeNode; import org.dllearner.utilities.datastructures.WeakSearchTreeNode; +import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLIndividual; @@ -71,12 +73,14 @@ public enum QualityEvaluationMethod { START, REASONER, TOO_WEAK_LIST, OVERLY_GEN private boolean isPosOnlyCandidate = true; private OCEL learningAlgorithm; + private ExampleBasedHeuristic heuristic; - public ExampleBasedNode(OWLClassExpression concept, AbstractCELA learningAlgorithm) { + public ExampleBasedNode(OWLClassExpression concept, AbstractCELA learningAlgorithm, ExampleBasedHeuristic heuristic) { this.concept = concept; horizontalExpansion = 0; isQualityEvaluated = false; this.learningAlgorithm = (OCEL) learningAlgorithm; + this.heuristic = heuristic; } public void setHorizontalExpansion(int horizontalExpansion) { @@ -145,8 +149,7 @@ public String getStats() { // comment this out to display the heuristic score with default parameters // learningAlgorithm.getHeuristic() int nrOfPositiveExamples = ((PosNegLP) learningAlgorithm.getLearningProblem()).getPositiveExamples().size(); - int nrOfNegativeExamples = ((PosNegLP) learningAlgorithm.getLearningProblem()).getNegativeExamples().size(); - double heuristicScore = MultiHeuristic.getNodeScore(this, nrOfPositiveExamples, nrOfNegativeExamples, learningAlgorithm.getNegativeWeight(), learningAlgorithm.getStartNodeBonus(), learningAlgorithm.getExpansionPenaltyFactor(), learningAlgorithm.getNegationPenalty()); + double heuristicScore = heuristic.getNodeScore(this); ret += "h:" +df.format(heuristicScore) + " "; int wrongPositives = nrOfPositiveExamples - coveredPositives.size(); diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/MultiHeuristic.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/MultiHeuristic.java index b6def2af70..69e91784f5 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/MultiHeuristic.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/MultiHeuristic.java @@ -23,10 +23,11 @@ import org.dllearner.core.ComponentInitException; import org.dllearner.core.annotations.NoConfigOption; import org.dllearner.core.config.ConfigOption; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataSomeValuesFrom; -import org.semanticweb.owlapi.model.OWLObjectComplementOf; +import org.dllearner.utilities.owl.ExpressionDecomposer; +import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; +import org.semanticweb.owlapi.model.*; +import java.util.List; import java.util.Set; /** @@ -100,6 +101,10 @@ public class MultiHeuristic implements ExampleBasedHeuristic, Component { private int nrOfNegativeExamples; @NoConfigOption private int nrOfExamples; + + private final ExpressionDecomposer decomposer = new ExpressionDecomposer(); + + private OWLClassExpressionLengthMetric lengthMetric = OWLClassExpressionLengthMetric.getDefaultMetric(); @Deprecated public MultiHeuristic(int nrOfPositiveExamples, int nrOfNegativeExamples) { @@ -161,7 +166,7 @@ public double getNodeScore(ExampleBasedNode node) { } else { accuracy += startNodeBonus; } - int he = node.getHorizontalExpansion() - getHeuristicLengthBonus(node.getConcept()); + double he = node.getHorizontalExpansion() - getHeuristicLengthBonus(node.getConcept()); return accuracy + gainBonusFactor * gain - expansionPenaltyFactor * he - nodeChildPenalty * node.getChildren().size(); } @@ -176,34 +181,30 @@ public static double getNodeScore(ExampleBasedNode node, int nrOfPositiveExample // this function can be used to give some constructs a length bonus // compared to their syntactic length - private int getHeuristicLengthBonus(OWLClassExpression description) { - - - int bonus = 0; - - Set nestedClassExpressions = description.getNestedClassExpressions(); - for (OWLClassExpression expression : nestedClassExpressions) { - // do not count TOP symbols (in particular in ALL r.TOP and EXISTS r.TOP) + private double getHeuristicLengthBonus(OWLClassExpression description) { + double bonus = 0.0; + + for (OWLClassExpression expression : decomposer.decompose(description)) { + // encourage the algorithm to refine EXISTS r.TOP and MIN n r.TOP + // as they provide little extra information + if ((expression instanceof OWLObjectSomeValuesFrom && ((OWLObjectSomeValuesFrom) expression).getFiller().isOWLThing()) + || (expression instanceof OWLObjectMinCardinality && ((OWLObjectMinCardinality) expression).getFiller().isOWLThing()) + ) { + bonus += lengthMetric.getClassLength() / 2.0; + } + // do not count TOP symbols in ALL r.TOP and MAX n r.BOTTOM // as they provide no extra information - if(expression.isOWLThing()) - bonus = 1; //2; - - // we put a penalty on negations, because they often overfit - // (TODO: make configurable) - else if(expression instanceof OWLObjectComplementOf) { - bonus = -negationPenalty; + else if ((expression instanceof OWLObjectAllValuesFrom && ((OWLObjectAllValuesFrom) expression).getFiller().isOWLThing()) + || (expression instanceof OWLObjectMaxCardinality && ((OWLObjectMaxCardinality) expression).getFiller().isOWLNothing()) + ) { + bonus += lengthMetric.getClassLength(); } - -// if(OWLClassExpression instanceof BooleanValueRestriction) -// bonus = -1; - - // some bonus for doubles because they are already penalised by length 3 - else if(expression instanceof OWLDataSomeValuesFrom) { -// System.out.println(description); - bonus = 3; //2; + // optionally, penalize negations (they may cause the algorithm to overfit) + else if(expression instanceof OWLObjectComplementOf) { + bonus -= negationPenalty; } } - + return bonus; } @@ -270,4 +271,12 @@ public int getNegationPenalty() { public void setNegationPenalty(int negationPenalty) { this.negationPenalty = negationPenalty; } + + public OWLClassExpressionLengthMetric getLengthMetric() { + return lengthMetric; + } + + public void setLengthMetric(OWLClassExpressionLengthMetric lengthMetric) { + this.lengthMetric = lengthMetric; + } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index 997bd3c68a..77369c9d9a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -83,14 +83,18 @@ public class OCEL extends AbstractCELA { // often the learning problems needn't be accessed directly; instead // use the example sets below and the posonly variable - private OWLClassExpression startDescription; private int nrOfExamples; private int nrOfPositiveExamples; private Set positiveExamples; private int nrOfNegativeExamples; private Set negativeExamples; + private Set positiveTestExamples; + private Set negativeTestExamples; + private boolean anyTestExamples = false; + private int allowedMisclassifications = 0; + private int allowedMisclassificationsWithinMargin = 0; // search tree options @ConfigOption(defaultValue = "false", description = "specifies whether to write a search tree") @@ -149,8 +153,13 @@ public class OCEL extends AbstractCELA { @ConfigOption(defaultValue = "30", description = "maximum number of candidates to retain") private int candidatePostReductionSize = 30; + @ConfigOption(defaultValue = "300", description = "the number of seconds between two consecutive candidate reductions") + private long candidateReductionInterval = 300L; + // solution protocol - private List solutions = new LinkedList<>(); + private TreeMap solutions; + private TreeMap solutionCandidates; + private final double solutionCandidatesMinAccuracyDiff = 0.0001; @ConfigOption(defaultValue = "false", description = "specifies whether to compute and log benchmark information") private boolean computeBenchmarkInformation = false; @@ -243,6 +252,20 @@ public class OCEL extends AbstractCELA { @ConfigOption(defaultValue = "0.0", description = "noise regulates how many positives can be misclassified and when " + "the algorithm terminates") private double noisePercentage = noisePercentageDefault; + private double noise = noisePercentage / 100.0; + + @ConfigOption(defaultValue = "0.0", description = "determines a lower bound on noisiness of an expression with respect to noisePercentage " + + "in order to be considered a reasonable solution candidate (must be non-negative), e.g. for noisePercentage = 15 and noisePercentageMargin = 5, " + + "the algorithm will suggest expressions with the number of misclassified positives less than or equal to 20% of all examples " + + "as solution candidates as well; note: difference between accuracies of any two candidates must be at least 0.01% to ensure diversity") + private double noisePercentageMargin = 0.0; + + @ConfigOption(defaultValue = "20", description = "the number of solutions to be presented, sorted in descending order by accuracy") + private int maxNrOfResults = 20; + + @ConfigOption(defaultValue = "20", description = "the number of solution candidates within margin to be presented, sorted in descending order by accuracy") + private int maxNrOfResultsWithinMargin = 20; + @ConfigOption( defaultValue = "owl:Thing", description = "You can specify a start class for the algorithm", @@ -292,6 +315,7 @@ public void init() throws ComponentInitException { throw new RuntimeException("does not work with positive examples only yet"); } else { heuristic = new MultiHeuristic(((PosNegLP) getLearningProblem()).getPositiveExamples().size(), ((PosNegLP) getLearningProblem()).getNegativeExamples().size(), negativeWeight, startNodeBonus, expansionPenaltyFactor, negationPenalty); + ((MultiHeuristic) heuristic).setLengthMetric(lengthMetric); } } else { // we need to set some variables to make the heuristic work @@ -358,6 +382,10 @@ public void init() throws ComponentInitException { } operator.setLengthMetric(lengthMetric); + if (heuristic instanceof MultiHeuristic) { + ((MultiHeuristic) heuristic).setLengthMetric(lengthMetric); + } + // create an algorithm object and pass all configuration // options to it @@ -372,6 +400,20 @@ public void init() throws ComponentInitException { // note: used concepts and roles do not need to be passed // as argument, because it is sufficient to prepare the // concept and role hierarchy accordingly + + noise = noisePercentage / 100.0; + + positiveTestExamples = ((PosNegLP) learningProblem).getPositiveTestExamples(); + negativeTestExamples = ((PosNegLP) learningProblem).getNegativeTestExamples(); + anyTestExamples = positiveTestExamples.size() > 0 || negativeTestExamples.size() > 0; + + QualityBasedComparator solutionComparator = new QualityBasedComparator(lengthMetric); + solutions = new TreeMap<>(solutionComparator); + solutionCandidates = new TreeMap<>(solutionComparator); + + if (noisePercentageMargin < 0) { + noisePercentageMargin = 0.0; + } initialized = true; } @@ -386,6 +428,7 @@ public void start() { searchTree = new SearchTreeNonWeakPartialSet<>(heuristic); searchTreeStable = new SearchTreeNonWeak<>(nodeComparatorStable); solutions.clear(); + solutionCandidates.clear(); maxExecutionTimeAlreadyReached = false; minExecutionTimeAlreadyReached = false; guaranteeXgoodAlreadyReached = false; @@ -409,17 +452,18 @@ public void start() { */ // calculate quality threshold required for a solution - allowedMisclassifications = (int) Math.round(noisePercentage * nrOfExamples / 100); + allowedMisclassifications = (int) Math.round(noisePercentage * nrOfExamples / 100.0); + allowedMisclassificationsWithinMargin = (int) Math.round((noisePercentage + noisePercentageMargin) * nrOfExamples / 100.0); // start search with start class ExampleBasedNode startNode; - if (startDescription == null) { - startNode = new ExampleBasedNode(dataFactory.getOWLThing(), this); + if (startClass == null) { + startNode = new ExampleBasedNode(dataFactory.getOWLThing(), this, heuristic); startNode.setCoveredExamples(positiveExamples, negativeExamples); } else { - startNode = new ExampleBasedNode(startDescription, this); - Set coveredNegatives = reasoner.hasType(startDescription, negativeExamples); - Set coveredPositives = reasoner.hasType(startDescription, positiveExamples); + startNode = new ExampleBasedNode(startClass, this, heuristic); + Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); + Set coveredPositives = reasoner.hasType(startClass, positiveExamples); startNode.setCoveredExamples(coveredPositives, coveredNegatives); } @@ -440,7 +484,7 @@ public void start() { long lastReductionTime = System.nanoTime(); // try a traversal after x seconds long traversalInterval = 300L * 1000000000L; - long reductionInterval = 300L * 1000000000L; + long reductionInterval = candidateReductionInterval * 1000000000L; long currentTime; while (!isTerminationCriteriaReached()) { @@ -469,8 +513,13 @@ public void start() { if (bestNodeStable.getCovPosMinusCovNeg() < searchTreeStable.best() .getCovPosMinusCovNeg()) { String acc = new DecimalFormat(".00%").format((searchTreeStable.best().getAccuracy())); + String testAcc = new DecimalFormat(".00%").format(computeTestingAccuracy(searchTreeStable.best().getConcept())); // no handling needed, it will just look ugly in the output - logger.info("more accurate (" + acc + ") class expression found: " + renderer.render(searchTreeStable.best().getConcept())); + logger.info( + "Time " + ((System.currentTimeMillis() - runtime) / 1000.0) + + "s: more accurate (training: " + acc + ", testing: " + testAcc + + ") class expression found: " + renderer.render(searchTreeStable.best().getConcept()) + ); if (logger.isTraceEnabled()) { logger.trace(Sets.difference(positiveExamples, bestNodeStable.getCoveredNegatives()).toString()); logger.trace(Sets.difference(negativeExamples, bestNodeStable.getCoveredNegatives()).toString()); @@ -512,17 +561,38 @@ public void start() { loop++; }// end while + if (solutionCandidates.size() > 0) { + // we do not need to print the best node if we display the top 20 solutions below anyway + logger.info("solutions within margin (at most " + maxNrOfResultsWithinMargin + " are shown):"); + int show = 1; + for (ExampleBasedNode c : solutionCandidates.descendingKeySet()) { + logger.info(show + ": " + renderer.render(c.getConcept()) + + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " + + df.format(100 * computeTestingAccuracy(c.getConcept())) + "%" + + ", length " + OWLClassExpressionUtils.getLength(c.getConcept()) + + ", depth " + OWLClassExpressionUtils.getDepth(c.getConcept()) + + ", time " + df.format(solutionCandidates.get(c)) + "s)"); + if (show >= maxNrOfResultsWithinMargin) { + break; + } + show++; + } + } else { + logger.info("no appropriate solutions within margin found (try increasing the noisePercentageMargin)"); + } + if (solutions.size() > 0) { - int solutionLimit = 20; // we do not need to print the best node if we display the top 20 solutions below anyway - logger.info("solutions (at most " + solutionLimit + " are shown):"); + logger.info("solutions (at most " + maxNrOfResults + " are shown):"); int show = 1; - for (ExampleBasedNode c : solutions) { + for (ExampleBasedNode c : solutions.descendingKeySet()) { logger.info(show + ": " + renderer.render(c.getConcept()) - + " (accuracy " + df.format(100 * c.getAccuracy()) + "%, length " - + OWLClassExpressionUtils.getLength(c.getConcept()) - + ", depth " + OWLClassExpressionUtils.getDepth(c.getConcept()) + ")"); - if (show >= solutionLimit) { + + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " + + df.format(100 * computeTestingAccuracy(c.getConcept())) + "%" + + ", length " + OWLClassExpressionUtils.getLength(c.getConcept()) + + ", depth " + OWLClassExpressionUtils.getDepth(c.getConcept()) + + ", time " + df.format(solutions.get(c)) + "s)"); + if (show >= maxNrOfResults) { break; } show++; @@ -539,6 +609,7 @@ public void start() { int conceptTests = conceptTestsReasoner + conceptTestsTooWeakList + conceptTestsOverlyGeneralList; if (stop) { logger.info("Algorithm stopped (" + conceptTests + " descriptions tested).\n"); + logger.info(reasoner.toString()); } else { logger.info("Algorithm terminated successfully (" + conceptTests + " descriptions tested).\n"); logger.info(reasoner.toString()); @@ -634,7 +705,7 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, properRefinements.add(refinement); tooWeakList.add(refinement); - ExampleBasedNode newNode = new ExampleBasedNode(refinement, this); + ExampleBasedNode newNode = new ExampleBasedNode(refinement, this, heuristic); newNode.setHorizontalExpansion(OWLClassExpressionUtils.getLength(refinement, lengthMetric) - 1); newNode.setTooWeak(true); newNode.setQualityEvaluationMethod(ExampleBasedNode.QualityEvaluationMethod.TOO_WEAK_LIST); @@ -691,7 +762,7 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, if (nonRedundant) { // newly created node - ExampleBasedNode newNode = new ExampleBasedNode(refinement, this); + ExampleBasedNode newNode = new ExampleBasedNode(refinement, this, heuristic); // die -1 ist wichtig, da sonst keine gleich langen Refinements // für den neuen Knoten erlaubt wären z.B. person => male newNode.setHorizontalExpansion(OWLClassExpressionUtils.getLength(refinement, lengthMetric) - 1); @@ -732,17 +803,18 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, // are performed => rely on fast instance checker) for (OWLIndividual i : coveredPositives) { // TODO: move code to a separate function - if (quality != -1) { - boolean covered = reasoner.hasType(refinement, i); - if (!covered) - misclassifiedPositives++; - else - newlyCoveredPositives.add(i); + if (quality == -1) { + break; + } - if (misclassifiedPositives > allowedMisclassifications) - quality = -1; + boolean covered = reasoner.hasType(refinement, i); + if (!covered) + misclassifiedPositives++; + else + newlyCoveredPositives.add(i); - } + if (misclassifiedPositives > allowedMisclassifications) + quality = -1; } Set newlyCoveredNegatives = null; @@ -759,6 +831,7 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, propernessCalcReasoningTimeNs += System.nanoTime() - propCalcReasoningStart2; newNode.setQualityEvaluationMethod(ExampleBasedNode.QualityEvaluationMethod.REASONER); + // TODO: MY use noise or remove noise variable entirely if (quality != -1 && !(((PosNegLP) learningProblem).getAccuracyMethod() instanceof AccMethodNoWeakness) && ((PosNegLP) learningProblem).getAccuracyMethod().getAccOrTooWeak2( newlyCoveredPositives.size(), nrOfPositiveExamples - newlyCoveredPositives.size(), @@ -782,8 +855,30 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, tooWeakList.add(refinement); } else { // Lösung gefunden - if (quality >= 0 && quality <= allowedMisclassifications) { - solutions.add(newNode); + if (quality >= 0) { + if (quality <= allowedMisclassifications) { + solutions.put(newNode, (System.currentTimeMillis() - runtime) / 1000.0); + + if (solutions.size() > maxNrOfResults) { + solutions.pollFirstEntry(); + } + } + + if (quality <= allowedMisclassificationsWithinMargin) { + if (solutionCandidates.isEmpty() + || (newNode.getAccuracy() > solutionCandidates.firstKey().getAccuracy() + && solutionCandidates.keySet().stream().allMatch( + n -> Math.abs(newNode.getAccuracy() - n.getAccuracy()) > solutionCandidatesMinAccuracyDiff + ) + ) + ) { + solutionCandidates.put(newNode, (System.currentTimeMillis() - runtime) / 1000.0); + } + + if (solutionCandidates.size() > maxNrOfResultsWithinMargin) { + solutionCandidates.pollFirstEntry(); + } + } } // we need to make sure that all positives are covered @@ -983,7 +1078,7 @@ private void traverseTree() { //noinspection UnusedAssignment currentAccuracy = accuracy; - if (accuracy > 1 - (noisePercentage / 100)) { + if (accuracy > 1 - noise) { logger.info("traversal found " + mc); logger.info("accuracy: " + accuracy); System.exit(0); @@ -1431,4 +1526,36 @@ public void setHeuristic(ExampleBasedHeuristic heuristic) { public ExampleBasedHeuristic getHeuristic() { return heuristic; } + + public long getCandidateReductionInterval() { + return candidateReductionInterval; + } + + public void setCandidateReductionInterval(long candidateReductionInterval) { + this.candidateReductionInterval = candidateReductionInterval; + } + + public double getNoisePercentageMargin() { + return noisePercentageMargin; + } + + public void setNoisePercentageMargin(double noisePercentageMargin) { + this.noisePercentageMargin = noisePercentageMargin; + } + + public double getMaxNrOfResults() { + return maxNrOfResults; + } + + public void setMaxNrOfResults(int maxNrOfResults) { + this.maxNrOfResults = maxNrOfResults; + } + + public double getMaxNrOfResultsWithinMargin() { + return maxNrOfResultsWithinMargin; + } + + public void setMaxNrOfResultsWithinMargin(int maxNrOfResultsWithinMargin) { + this.maxNrOfResultsWithinMargin = maxNrOfResultsWithinMargin; + } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/QualityBasedComparator.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/QualityBasedComparator.java new file mode 100644 index 0000000000..cf94923d4d --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/QualityBasedComparator.java @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2007 - 2016, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.dllearner.algorithms.ocel; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; + +import java.util.Comparator; + +public class QualityBasedComparator implements Comparator { + + private final OWLClassExpressionLengthMetric lengthMetric; + + public QualityBasedComparator(OWLClassExpressionLengthMetric lengthMetric) { + this.lengthMetric = lengthMetric; + } + + @Override + public int compare(ExampleBasedNode node1, ExampleBasedNode node2) { + if (node1.isQualityEvaluated() && node2.isQualityEvaluated()) { + return compareByQuality(node1, node2); + } + + throw new RuntimeException("Nodes with not evaluated quality are incomparable."); + } + + private int compareByQuality(ExampleBasedNode node1, ExampleBasedNode node2) { + int result = Boolean.compare(node2.isTooWeak(), node1.isTooWeak()); + + if (result != 0) { + return result; + } + + result = compareWithNonWeakQuality(node1, node2); + + if (result != 0) { + return result; + } + + return node1.getConcept().compareTo(node2.getConcept()); + } + + private int compareWithNonWeakQuality(ExampleBasedNode node1, ExampleBasedNode node2) { + int result = compareByAccuracy(node1, node2); + + if (result != 0) { + return result; + } + + return compareByLength(node1, node2); + } + + private int compareByAccuracy(ExampleBasedNode node1, ExampleBasedNode node2) { + double node1Accuracy = node1.getAccuracy(); + double node2Accuracy = node2.getAccuracy(); + + return Double.compare(node1Accuracy, node2Accuracy); + } + + private int compareByLength(ExampleBasedNode node1, ExampleBasedNode node2) { + int node1Length = OWLClassExpressionUtils.getLength(node1.getConcept(), lengthMetric); + int mode2Length = OWLClassExpressionUtils.getLength(node2.getConcept(), lengthMetric); + + return Integer.compare(mode2Length, node1Length); + } + + @Override + public boolean equals(Object o) { + return (o instanceof QualityBasedComparator); + } +} diff --git a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java index 96d262b656..cdbe4132fc 100644 --- a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java +++ b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java @@ -356,6 +356,7 @@ protected String getSolutionString() { str += current + ": " + descriptionString + " (pred. acc.: " + dfPercent.format(reasoningUtil.getAccuracyOrTooWeak2(new AccMethodPredAcc(true), description, positiveExamples, negativeExamples, 1)) + + " / " + dfPercent.format(computeTestingAccuracy(description)) + ", F-measure: "+ dfPercent.format(reasoningUtil.getAccuracyOrTooWeak2(new AccMethodFMeasure(true), description, positiveExamples, negativeExamples, 1)); AccMethodTwoValued accuracyMethod = ((PosNegLP)learningProblem).getAccuracyMethod(); @@ -372,7 +373,15 @@ protected String getSolutionString() { } return str; } - + + protected double computeTestingAccuracy(OWLClassExpression description) { + if (learningProblem instanceof PosNegLP) { + return ((PosNegLP) learningProblem).getTestAccuracyOrTooWeak(description, 1); + } + + return 0.0; + } + /** * Computes an internal class hierarchy that only contains classes * that are allowed. @@ -494,7 +503,7 @@ protected OWLClassExpression rewrite(OWLClassExpression ce) { // replace \exists r.\top with \exists r.range(r) which is easier to read for humans niceDescription = ConceptTransformation.replaceRange(niceDescription, reasoner); - niceDescription = ConceptTransformation.appendSomeValuesFrom(niceDescription); +// niceDescription = ConceptTransformation.appendSomeValuesFrom(niceDescription); return niceDescription; } diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java index 426186d4db..36608e62bd 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java @@ -30,6 +30,7 @@ import org.dllearner.core.config.ConfigOption; import org.dllearner.reasoning.SPARQLReasoner; import org.dllearner.utilities.Helper; +import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLIndividual; import org.semanticweb.owlapi.model.OWLNamedIndividual; import org.springframework.beans.factory.annotation.Autowired; @@ -50,6 +51,12 @@ public abstract class PosNegLP extends AbstractClassExpressionLearningProblem negativeExamples = new TreeSet<>(); protected Set allExamples = new TreeSet<>(); + @ConfigOption(description = "list of positive testing examples") + protected Set positiveTestExamples = new TreeSet<>(); + @ConfigOption(description = "list of negative testing examples") + protected Set negativeTestExamples = new TreeSet<>(); + protected Set allTestExamples = new TreeSet<>(); + @ConfigOption(description = "\"Specifies whether to use retrieval or instance checks for testing a concept. - NO LONGER FULLY SUPPORTED.",defaultValue = "false") private boolean useRetrievalForClassification = false; @ConfigOption(description = "Percent Per Length Unit", defaultValue = "0.05", required = false) @@ -109,10 +116,35 @@ public void init() throws ComponentInitException { // sanity check whether examples are contained in KB Helper.checkIndividuals(reasoner, allExamples); + + if(positiveTestExamples.isEmpty()) { + logger.warn("No positive testing examples have been set."); + } + + // check if some negative examples have been set and give warning if not + if(negativeTestExamples.isEmpty()) { + logger.warn("No negative testing examples have been set."); + } + + // check if there is some overlap between positive and negative examples and give warning + // in that case + SetView testOverlap = Sets.intersection(positiveTestExamples, negativeTestExamples); + if(!testOverlap.isEmpty()) { + logger.warn("You declared some individuals as both positive and negative testing examples."); + } + + allTestExamples = Sets.union(positiveTestExamples, negativeTestExamples); + + // sanity check whether examples are contained in KB + Helper.checkIndividuals(reasoner, allTestExamples); initialized = true; } + public double getTestAccuracyOrTooWeak(OWLClassExpression description, double noise) { + return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); + } + public Set getNegativeExamples() { return negativeExamples; } @@ -129,6 +161,22 @@ public void setPositiveExamples(Set set) { this.positiveExamples=set; } + public Set getNegativeTestExamples() { + return negativeTestExamples; + } + + public Set getPositiveTestExamples() { + return positiveTestExamples; + } + + public void setNegativeTestExamples(Set negativeTestExamples) { + this.negativeTestExamples = negativeTestExamples; + } + + public void setPositiveTestExamples(Set positiveTestExamples) { + this.positiveTestExamples = positiveTestExamples; + } + public double getPercentPerLengthUnit() { return percentPerLengthUnit; } diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java index 87ae5616f5..d8e3bbe872 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java @@ -24,6 +24,7 @@ import org.dllearner.utilities.owl.OWLClassExpressionUtils; import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLIndividual; +import org.semanticweb.owlapi.model.OWLNamedIndividual; import java.util.SortedSet; @@ -115,7 +116,7 @@ public EvaluatedDescription evaluate(OWLClassExpression description, double nois return new EvaluatedDescriptionPosNeg(description, score); } - /* (non-Javadoc) + /* (non-Javadoc) * @see java.lang.Object#clone() */ @Override diff --git a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java index d81bde0633..7efdf7da1c 100644 --- a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java +++ b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java @@ -92,15 +92,15 @@ public class ClosedWorldReasoner extends AbstractReasonerComponent { private Map> classInstancesNeg = new TreeMap<>(); // object property mappings private Map>> opPos = new TreeMap<>(); -// private Map> opPos = new TreeMap<>(); + // private Map> opPos = new TreeMap<>(); // data property mappings private Map>> dpPos = new TreeMap<>(); - // datatype property mappings + // datatype property mappings // we have one mapping for true and false for efficiency reasons private Map> bdPos = new TreeMap<>(); private Map> bdNeg = new TreeMap<>(); - // for int and double we assume that a property can have several values, + // for int and double we assume that a property can have several values, // althoug this should be rare, // e.g. hasValue(object,2) and hasValue(object,3) private Map>> dd = new TreeMap<>(); @@ -113,10 +113,10 @@ public class ClosedWorldReasoner extends AbstractReasonerComponent { private boolean defaultNegation = true; @ConfigOption(description = "This option controls how to interpret the all quantifier in forall r.C. " - + "The standard option is to return all those which do not have an r-filler not in C. " - + "The domain semantics is to use those which are in the domain of r and do not have an r-filler not in C. " - + "The forallExists semantics is to use those which have at least one r-filler and do not have an r-filler not in C.", - defaultValue = "standard") + + "The Standard option instructs the reasoner to return all individuals which do not have an r-filler not in C. " + + "The NonEmpty semantics restricts this set only to those individuals which have at least one r-filler." + + "The SomeOnly semantics further restricts this set only to those individuals which have at least one r-filler in C.", + defaultValue = "SomeOnly") private ForallSemantics forAllSemantics = ForallSemantics.SomeOnly; public enum ForallSemantics { @@ -139,7 +139,7 @@ public enum DisjointnessSemantics { INSTANCE_BASED } - private DisjointnessSemantics disjointnessSemantics = DisjointnessSemantics.INSTANCE_BASED; + private DisjointnessSemantics disjointnessSemantics = DisjointnessSemantics.EXPLICIT; @ConfigOption(defaultValue = "false") private boolean materializeExistentialRestrictions = false; @@ -153,12 +153,12 @@ public ClosedWorldReasoner() { } public ClosedWorldReasoner(TreeSet individuals, - Map> classInstancesPos, - Map>> opPos, - Map>> id, - Map> bdPos, - Map> bdNeg, - KnowledgeSource... sources) { + Map> classInstancesPos, + Map>> opPos, + Map>> id, + Map> bdPos, + Map> bdNeg, + KnowledgeSource... sources) { super(new HashSet<>(Arrays.asList(sources))); this.individuals = individuals; this.classInstancesPos = classInstancesPos; @@ -212,7 +212,7 @@ public ClosedWorldReasoner(OWLAPIReasoner baseReasoner) { /* * (non-Javadoc) - * + * * @see org.dllearner.core.Component#init() */ @Override @@ -224,7 +224,7 @@ public void init() throws ComponentInitException { // loadOrDematerialize(); materialize(); - + initialized = true; } @@ -294,8 +294,8 @@ private void materialize() { individuals = (TreeSet) baseReasoner.getIndividuals(); int totalEntities = baseReasoner.getClasses().size() + - baseReasoner.getObjectProperties().size() + - baseReasoner.getDatatypeProperties().size(); + baseReasoner.getObjectProperties().size() + + baseReasoner.getDatatypeProperties().size(); AtomicInteger i = new AtomicInteger(); @@ -306,12 +306,12 @@ private void materialize() { classInstancesPos.put(cls, pos); if (isDefaultNegation()) { - /* - * we should avoid this operation because it returns a new - * set and thus could lead to memory issues - * Instead, we could later answer '\neg A(x)' by just check - * for A(x) and return the inverse. - */ + /* + * we should avoid this operation because it returns a new + * set and thus could lead to memory issues + * Instead, we could later answer '\neg A(x)' by just check + * for A(x) and return the inverse. + */ if (precomputeNegations) { classInstancesNeg.put(cls, new TreeSet<>(Sets.difference(individuals, pos))); } @@ -391,7 +391,7 @@ private void materialize() { } } - //materialize facts based on OWL punning, i.e.: + //materialize facts based on OWL punning, i.e.: //for each A in N_C if (handlePunning && OWLPunningDetector.hasPunning(baseReasoner.getReasoner().getRootOntology())) { OWLOntology ontology = baseReasoner.getReasoner().getRootOntology(); @@ -446,8 +446,8 @@ private void fill(SortedSet individuals, OWLClassExpression d) { OWLIndividual newIndividual = df.getOWLNamedIndividual(IRI.create("http://dllearner.org#genInd_" + i++)); newIndividuals.add(newIndividual); map - .computeIfAbsent(individual, k -> new TreeSet<>()) - .add(newIndividual); + .computeIfAbsent(individual, k -> new TreeSet<>()) + .add(newIndividual); } fill(newIndividuals, filler); @@ -458,7 +458,7 @@ private void fill(SortedSet individuals, OWLClassExpression d) { @Override public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individual) - throws ReasoningMethodUnsupportedException { + throws ReasoningMethodUnsupportedException { if (description.isOWLThing()) { return true; @@ -507,7 +507,7 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ OWLIndividual subject = entry.getKey(); SortedSet objects = entry.getValue(); - // check if the individual is contained in the objects and + // check if the individual is contained in the objects and // subject is of type C if (objects.contains(individual)) { if (hasTypeImpl(fillerConcept, subject)) { @@ -562,21 +562,13 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ return forAllSemantics == ForallSemantics.Standard; } - boolean hasCorrectFiller = false; for (OWLIndividual value : values) { - if (hasTypeImpl(fillerConcept, value)) { - hasCorrectFiller = true; - } else { + if (!hasTypeImpl(fillerConcept, value)) { return false; } } - if (forAllSemantics == ForallSemantics.SomeOnly) { - return hasCorrectFiller; - } else { - return true; - } - + return true; } else {// \forall r.C SortedSet values = opPos.get(property).get(individual); @@ -622,7 +614,7 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ OWLIndividual subject = entry.getKey(); SortedSet objects = entry.getValue(); - // count the number of subjects which are related to the individual such that + // count the number of subjects which are related to the individual such that // subject is of type C if (objects.contains(individual)) { if (hasTypeImpl(fillerConcept, subject)) { @@ -656,14 +648,14 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ if (hasTypeImpl(fillerConcept, roleFiller)) { nrOfFillers++; if (nrOfFillers == cardinality - || (handlePunning && property == OWLPunningDetector.punningProperty)) { + || (handlePunning && property == OWLPunningDetector.punningProperty)) { return true; } - // early abort: e.g. >= 10 hasStructure.Methyl; + // early abort: e.g. >= 10 hasStructure.Methyl; // if there are 11 fillers and 2 are not Methyl, the result // is false } else { - if (values.size() - index < cardinality) { + if (values.size() - index + nrOfFillers < cardinality) { return false; } } @@ -676,6 +668,10 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ OWLClassExpression fillerConcept = ((OWLObjectMaxCardinality) description).getFiller(); int cardinality = ((OWLObjectMaxCardinality) description).getCardinality(); + if (fillerConcept.isOWLNothing()) { + return true; + } + if (property.isAnonymous()) { Map> mapping = opPos.get(property.getNamedProperty()); @@ -697,11 +693,11 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ if (nrOfFillers > cardinality) { return false; } - // early abort: e.g. <= 5 hasStructure.Methyl; + // early abort: e.g. <= 5 hasStructure.Methyl; // if there are 6 fillers and 2 are not Methyl, the result // is true } else { - if (nrOfSubjects - index <= cardinality) { + if (nrOfSubjects - index + nrOfFillers <= cardinality) { return true; } } @@ -726,11 +722,11 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ if (nrOfFillers > cardinality) { return false; } - // early abort: e.g. <= 5 hasStructure.Methyl; + // early abort: e.g. <= 5 hasStructure.Methyl; // if there are 6 fillers and 2 are not Methyl, the result // is true } else { - if (roleFillers.size() - index <= cardinality) { + if (roleFillers.size() - index + nrOfFillers <= cardinality) { return true; } } @@ -770,7 +766,7 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ // is false } else { // not enough remaining individuals that could belong to filler class - if (roleFillers.size() - index <= cardinality) { + if (roleFillers.size() - index + nrOfFillers < cardinality) { return false; } } @@ -786,7 +782,7 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ if (property.isAnonymous()) { for (Entry> entry : mapping - .entrySet()) { + .entrySet()) { OWLIndividual subject = entry.getKey(); SortedSet objects = entry.getValue(); @@ -821,7 +817,7 @@ else if (description instanceof OWLDataSomeValuesFrom) { if (property.isAnonymous()) { throw new ReasoningMethodUnsupportedException("Retrieval for class expression " - + description + " unsupported. Inverse object properties not supported."); + + description + " unsupported. Inverse object properties not supported."); } if (filler.isDatatype()) { // filler is a datatype @@ -891,7 +887,7 @@ else if (description instanceof OWLDataSomeValuesFrom) { } else if (OWLAPIUtils.dtDatatypes.contains(datatype)) { SortedSet values = dpPos.get(property).get(individual); - // TODO we cannot ensure the sorting, because OWL API does only String comparison + // TODO we cannot ensure the sorting, because OWL API does only String comparison // on the lexical String value // no value exists if (values == null) { @@ -920,7 +916,7 @@ else if (description instanceof OWLDataSomeValuesFrom) { } if ((minDateTime != null && parser.parseDateTime(values.last().getLiteral()).isBefore(minDateTime)) - || (maxDateTime != null && parser.parseDateTime(values.first().getLiteral()).isAfter(maxDateTime))) { + || (maxDateTime != null && parser.parseDateTime(values.first().getLiteral()).isAfter(maxDateTime))) { return false; } @@ -936,7 +932,7 @@ else if (description instanceof OWLDataSomeValuesFrom) { OWLDataOneOf dataOneOf = (OWLDataOneOf) filler; Set values = dataOneOf.getValues(); - // given \exists r.{v_1,...,v_n} we can check for each value v_i + // given \exists r.{v_1,...,v_n} we can check for each value v_i // if (\exists r.{v_i})(ind) holds for (OWLLiteral value : values) { @@ -954,7 +950,7 @@ else if (description instanceof OWLDataSomeValuesFrom) { if (property.isAnonymous()) { throw new ReasoningMethodUnsupportedException("Retrieval for class expression " - + description + " unsupported. Inverse object properties not supported."); + + description + " unsupported. Inverse object properties not supported."); } Map> mapping = dpPos.get(property); @@ -967,7 +963,7 @@ else if (description instanceof OWLDataSomeValuesFrom) { } throw new ReasoningMethodUnsupportedException("Instance check for class expression " - + description + " of type " + description.getClassExpressionType() + " unsupported."); + + description + " of type " + description.getClassExpressionType() + " unsupported."); } @Override @@ -997,8 +993,8 @@ public SortedSet getIndividualsImplStandard(OWLClassExpression co @SuppressWarnings("unchecked") public SortedSet getIndividualsImplFast(OWLClassExpression description) - throws ReasoningMethodUnsupportedException { - // policy: returned sets are clones, i.e. can be modified + throws ReasoningMethodUnsupportedException { + // policy: returned sets are clones, i.e. can be modified // (of course we only have to clone the leafs of a class OWLClassExpression tree) if (description.isOWLThing()) { return (TreeSet) individuals.clone(); @@ -1052,9 +1048,9 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri // each individual is connected to a set of individuals via the property; // we loop through the complete mapping return mapping.entrySet().stream() - .filter(e -> e.getValue().stream().anyMatch(targetSet::contains)) - .map(Entry::getKey) - .collect(Collectors.toCollection(TreeSet::new)); + .filter(e -> e.getValue().stream().anyMatch(targetSet::contains)) + .map(Entry::getKey) + .collect(Collectors.toCollection(TreeSet::new)); } else if (description instanceof OWLObjectAllValuesFrom) { // \forall restrictions are difficult to handle; assume we want to check // \forall hasChild.male with domain(hasChild)=Person; then for all non-persons @@ -1081,8 +1077,8 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri // each individual is connected to a set of individuals via the property; // we loop through the complete mapping mapping.entrySet().stream() - .filter(e -> e.getValue().stream().anyMatch(ind -> !targetSet.contains(ind))) - .forEach(e -> returnSet.remove(e.getKey())); + .filter(e -> e.getValue().stream().anyMatch(ind -> !targetSet.contains(ind))) + .forEach(e -> returnSet.remove(e.getKey())); return returnSet; } else if (description instanceof OWLObjectMinCardinality) { @@ -1141,7 +1137,7 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri // the mapping of instances related by r Map> mapping = getTargetIndividuals(property); - // initially all individuals are in the return set and we then remove those + // initially all individuals are in the return set and we then remove those // with too many fillers SortedSet returnSet = (SortedSet) individuals.clone(); @@ -1158,7 +1154,6 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri for (OWLIndividual ind : fillers) { // stop inner loop when there are more fillers than allowed if (nrOfFillers > number) { - returnSet.remove(entry.getKey()); break; } // early termination when there are not enough remaining candidates that could belong to C @@ -1170,6 +1165,10 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri } index++; } + + if (nrOfFillers > number) { + returnSet.remove(entry.getKey()); + } } return returnSet; @@ -1211,17 +1210,17 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri // the mapping of instances related by r Map> mapping = - property.isAnonymous() ? // \exists r^{-1}.{a} -> invert the mapping, i.e. get all objects that - // are related by r to (at least) one subject which is of type C - Multimaps.invertFrom( - MapUtils.createSortedMultiMap(opPos.get(property.getNamedProperty())), - TreeMultimap.create()).asMap() : - opPos.get(property.getNamedProperty()); + property.isAnonymous() ? // \exists r^{-1}.{a} -> invert the mapping, i.e. get all objects that + // are related by r to (at least) one subject which is of type C + Multimaps.invertFrom( + MapUtils.createSortedMultiMap(opPos.get(property.getNamedProperty())), + TreeMultimap.create()).asMap() : + opPos.get(property.getNamedProperty()); return mapping.entrySet().stream() - .filter(e -> e.getValue().contains(value)) - .map(Entry::getKey) - .collect(Collectors.toCollection(TreeSet::new)); + .filter(e -> e.getValue().contains(value)) + .map(Entry::getKey) + .collect(Collectors.toCollection(TreeSet::new)); } else if (description instanceof OWLDataSomeValuesFrom) { OWLDataPropertyExpression property = ((OWLDataSomeValuesFrom) description).getProperty(); OWLDataRange filler = ((OWLDataSomeValuesFrom) description).getFiller(); @@ -1231,117 +1230,117 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri return new TreeSet<>(dpPos.get(property).keySet()); } else if (filler instanceof OWLDataIntersectionOf) { return ((OWLDataIntersectionOf) filler).getOperands().stream() - .map(dr -> getIndividuals(df.getOWLDataSomeValuesFrom(property, dr))) - .reduce((s1, s2) -> { - s1.retainAll(s2); - return s1; - }) - .orElse(new TreeSet<>()); + .map(dr -> getIndividuals(df.getOWLDataSomeValuesFrom(property, dr))) + .reduce((s1, s2) -> { + s1.retainAll(s2); + return s1; + }) + .orElse(new TreeSet<>()); } else if (filler instanceof OWLDataUnionOf) { return ((OWLDataUnionOf) filler).getOperands().stream() - .map(dr -> getIndividuals(df.getOWLDataSomeValuesFrom(property, dr))) - .reduce((s1, s2) -> { - s1.addAll(s2); - return s1; - }) - .orElse(new TreeSet<>()); + .map(dr -> getIndividuals(df.getOWLDataSomeValuesFrom(property, dr))) + .reduce((s1, s2) -> { + s1.addAll(s2); + return s1; + }) + .orElse(new TreeSet<>()); } else if (filler instanceof OWLDataComplementOf) { return new TreeSet<>(Sets.difference( - individuals, - getIndividualsImpl(df.getOWLDataSomeValuesFrom( - property, - ((OWLDataComplementOf) filler).getDataRange())))); + individuals, + getIndividualsImpl(df.getOWLDataSomeValuesFrom( + property, + ((OWLDataComplementOf) filler).getDataRange())))); } else if (filler instanceof OWLDatatypeRestriction) { OWLDatatype datatype = ((OWLDatatypeRestriction) filler).getDatatype(); Set facetRestrictions = ((OWLDatatypeRestriction) filler).getFacetRestrictions(); if (OWLAPIUtils.floatDatatypes.contains(datatype)) { double min = facetRestrictions.stream() - .filter(fr -> fr.getFacet() == OWLFacet.MIN_INCLUSIVE) - .map(fr -> fr.getFacetValue().isDouble() ? fr.getFacetValue().parseDouble() : (double) fr.getFacetValue().parseFloat()) - .findAny().orElse(-Double.MAX_VALUE); + .filter(fr -> fr.getFacet() == OWLFacet.MIN_INCLUSIVE) + .map(fr -> fr.getFacetValue().isDouble() ? fr.getFacetValue().parseDouble() : (double) fr.getFacetValue().parseFloat()) + .findAny().orElse(-Double.MAX_VALUE); double max = facetRestrictions.stream() - .filter(fr -> fr.getFacet() == OWLFacet.MAX_INCLUSIVE) - .map(fr -> fr.getFacetValue().isDouble() ? fr.getFacetValue().parseDouble() : (double) fr.getFacetValue().parseFloat()) - .findAny().orElse(Double.MAX_VALUE); + .filter(fr -> fr.getFacet() == OWLFacet.MAX_INCLUSIVE) + .map(fr -> fr.getFacetValue().isDouble() ? fr.getFacetValue().parseDouble() : (double) fr.getFacetValue().parseFloat()) + .findAny().orElse(Double.MAX_VALUE); return dd.getOrDefault(property, new HashMap<>()).entrySet().stream() - .filter(e -> { - SortedSet values = e.getValue(); - - // we can skip if largest number is below minimum or lowest number is above maximum - if (values.last() < min || values.first() > max) { - return false; - } - - // search a value which is in the interval - return values.stream().anyMatch(val -> val >= min && val <= max); - }) - .map(Entry::getKey) - .collect(Collectors.toCollection(TreeSet::new)); + .filter(e -> { + SortedSet values = e.getValue(); + + // we can skip if largest number is below minimum or lowest number is above maximum + if (values.last() < min || values.first() > max) { + return false; + } + + // search a value which is in the interval + return values.stream().anyMatch(val -> val >= min && val <= max); + }) + .map(Entry::getKey) + .collect(Collectors.toCollection(TreeSet::new)); // } else if (OWLAPIUtils.intDatatypes.contains(datatype)) { int min = facetRestrictions.stream() - .filter(fr -> fr.getFacet() == OWLFacet.MIN_INCLUSIVE) - .map(fr -> fr.getFacetValue().parseInteger()) - .findAny().orElse(-Integer.MAX_VALUE); + .filter(fr -> fr.getFacet() == OWLFacet.MIN_INCLUSIVE) + .map(fr -> fr.getFacetValue().parseInteger()) + .findAny().orElse(-Integer.MAX_VALUE); int max = facetRestrictions.stream() - .filter(fr -> fr.getFacet() == OWLFacet.MAX_INCLUSIVE) - .map(fr -> fr.getFacetValue().parseInteger()) - .findAny().orElse(Integer.MAX_VALUE); + .filter(fr -> fr.getFacet() == OWLFacet.MAX_INCLUSIVE) + .map(fr -> fr.getFacetValue().parseInteger()) + .findAny().orElse(Integer.MAX_VALUE); return id.getOrDefault(property, new HashMap<>()).entrySet().stream() - .filter(e -> { - SortedSet values = e.getValue(); - - // we can skip if largest number is below minimum or lowest number is above maximum - if (values.last() < min || values.first() > max) { - return false; - } - - // search a value which is in the interval - return values.stream().anyMatch(val -> val >= min && val <= max); - }) - .map(Entry::getKey) - .collect(Collectors.toCollection(TreeSet::new)); + .filter(e -> { + SortedSet values = e.getValue(); + + // we can skip if largest number is below minimum or lowest number is above maximum + if (values.last() < min || values.first() > max) { + return false; + } + + // search a value which is in the interval + return values.stream().anyMatch(val -> val >= min && val <= max); + }) + .map(Entry::getKey) + .collect(Collectors.toCollection(TreeSet::new)); } else if (OWLAPIUtils.dtDatatypes.contains(datatype)) { OWLLiteral min = facetRestrictions.stream() - .filter(fr -> fr.getFacet() == OWLFacet.MIN_INCLUSIVE) - .map(OWLFacetRestriction::getFacetValue) - .findAny().orElse(null); + .filter(fr -> fr.getFacet() == OWLFacet.MIN_INCLUSIVE) + .map(OWLFacetRestriction::getFacetValue) + .findAny().orElse(null); OWLLiteral max = facetRestrictions.stream() - .filter(fr -> fr.getFacet() == OWLFacet.MAX_INCLUSIVE) - .map(OWLFacetRestriction::getFacetValue) - .findAny().orElse(null); + .filter(fr -> fr.getFacet() == OWLFacet.MAX_INCLUSIVE) + .map(OWLFacetRestriction::getFacetValue) + .findAny().orElse(null); return dpPos.getOrDefault(property, new HashMap<>()).entrySet().stream() - .filter(e -> e.getValue().stream().anyMatch(val -> OWLAPIUtils.inRange(val, min, max))) - .map(Entry::getKey) - .collect(Collectors.toCollection(TreeSet::new)); + .filter(e -> e.getValue().stream().anyMatch(val -> OWLAPIUtils.inRange(val, min, max))) + .map(Entry::getKey) + .collect(Collectors.toCollection(TreeSet::new)); } } else if (filler.getDataRangeType() == DataRangeType.DATA_ONE_OF) { OWLDataOneOf dataOneOf = (OWLDataOneOf) filler; Set values = dataOneOf.getValues(); return dpPos.getOrDefault(property, new HashMap<>()).entrySet().stream() - .filter(e -> !Sets.intersection(e.getValue(), values).isEmpty()) - .map(Entry::getKey) - .collect(Collectors.toCollection(TreeSet::new)); + .filter(e -> !Sets.intersection(e.getValue(), values).isEmpty()) + .map(Entry::getKey) + .collect(Collectors.toCollection(TreeSet::new)); } } else if (description instanceof OWLDataHasValue) { OWLDataPropertyExpression property = ((OWLDataHasValue) description).getProperty(); OWLLiteral value = ((OWLDataHasValue) description).getFiller(); return dpPos.getOrDefault(property, new HashMap<>()).entrySet().stream() - .filter(e -> e.getValue().contains(value)) - .map(Entry::getKey) - .collect(Collectors.toCollection(TreeSet::new)); + .filter(e -> e.getValue().contains(value)) + .map(Entry::getKey) + .collect(Collectors.toCollection(TreeSet::new)); } else if (description instanceof OWLObjectOneOf) { return new TreeSet(((OWLObjectOneOf) description).getIndividuals()); } throw new ReasoningMethodUnsupportedException("Retrieval for class expression " - + description + " unsupported."); + + description + " unsupported."); } @@ -1349,15 +1348,15 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri // or if r^{-1} invert the mapping private Map> getTargetIndividuals(OWLObjectPropertyExpression ope) { return ope.isAnonymous() - ? Multimaps.invertFrom( - MapUtils.createSortedMultiMap(opPos.get(ope.getNamedProperty())), - TreeMultimap.create()).asMap() - : opPos.get(ope.getNamedProperty()); + ? Multimaps.invertFrom( + MapUtils.createSortedMultiMap(opPos.get(ope.getNamedProperty())), + TreeMultimap.create()).asMap() + : opPos.get(ope.getNamedProperty()); } /* * (non-Javadoc) - * + * * @see org.dllearner.core.Reasoner#getAtomicConcepts() */ @Override @@ -1367,7 +1366,7 @@ public Set getClasses() { /* * (non-Javadoc) - * + * * @see org.dllearner.core.Reasoner#getAtomicRoles() */ @Override @@ -1432,7 +1431,7 @@ protected SortedSet getSubPropertiesImpl(OWLDataProperty role) /* * (non-Javadoc) - * + * * @see org.dllearner.core.Reasoner#getIndividuals() */ @Override @@ -1442,7 +1441,7 @@ public SortedSet getIndividuals() { /* * (non-Javadoc) - * + * * @see org.dllearner.core.Reasoner#getReasonerType() */ @Override @@ -1452,7 +1451,7 @@ public ReasonerType getReasonerType() { @Override public boolean isSuperClassOfImpl(OWLClassExpression superConcept, OWLClassExpression subConcept) { - // Negation neg = new Negation(subConcept); + // Negation neg = new Negation(subConcept); // Intersection c = new Intersection(neg,superConcept); // return fastRetrieval.calculateSets(c).getPosSet().isEmpty(); return baseReasoner.isSuperClassOfImpl(superConcept, subConcept); @@ -1480,7 +1479,7 @@ public boolean isDisjointImpl(OWLClass clsA, OWLClass clsB) { /* * (non-Javadoc) - * + * * @see org.dllearner.core.Reasoner#getBaseURI() */ @Override @@ -1490,7 +1489,7 @@ public String getBaseURI() { /* * (non-Javadoc) - * + * * @see org.dllearner.core.Reasoner#getPrefixes() */ @Override @@ -1592,7 +1591,7 @@ public Set getLabelImpl(OWLEntity entity) { /* * (non-Javadoc) - * + * * @see org.dllearner.core.ReasonerComponent#releaseKB() */ @Override @@ -1728,8 +1727,8 @@ public static void main(String[] args) throws Exception{ man.addAxiom(ontology, df.getOWLClassAssertionAxiom(clsA, df.getOWLNamedIndividual("s", pm))); IntStream.range(0, 5).forEach( i -> { man.addAxiom(ontology, df.getOWLObjectPropertyAssertionAxiom(op, - df.getOWLNamedIndividual("s", pm), - df.getOWLNamedIndividual("o" + i, pm))); + df.getOWLNamedIndividual("s", pm), + df.getOWLNamedIndividual("o" + i, pm))); }); IntStream.range(0, 5).forEach( i -> { man.addAxiom(ontology, df.getOWLClassAssertionAxiom(cls1, df.getOWLNamedIndividual("o" + i, pm))); @@ -1754,54 +1753,54 @@ public static void main(String[] args) throws Exception{ OWLClassExpression ce; SortedSet individuals = reasoner.getIndividuals( - df.getOWLDataSomeValuesFrom( - dp, - df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 2.0d))); + df.getOWLDataSomeValuesFrom( + dp, + df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 2.0d))); System.out.println(individuals); individuals = reasoner.getIndividuals( - df.getOWLDataSomeValuesFrom( - dp, - df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 1.9d))); + df.getOWLDataSomeValuesFrom( + dp, + df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 1.9d))); System.out.println(individuals); individuals = reasoner.getIndividuals( - df.getOWLDataSomeValuesFrom( - dp, - df.getOWLDataUnionOf( - df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 1.5d), - df.getOWLDatatypeMinMaxInclusiveRestriction(2.0d, 2.5d)) - )); + df.getOWLDataSomeValuesFrom( + dp, + df.getOWLDataUnionOf( + df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 1.5d), + df.getOWLDatatypeMinMaxInclusiveRestriction(2.0d, 2.5d)) + )); System.out.println(individuals); individuals = reasoner.getIndividuals( - df.getOWLDataSomeValuesFrom( - dp, - df.getOWLDataComplementOf( - df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 1.5d)) - )); + df.getOWLDataSomeValuesFrom( + dp, + df.getOWLDataComplementOf( + df.getOWLDatatypeMinMaxInclusiveRestriction(1.0d, 1.5d)) + )); // System.out.println(individuals); System.out.println(df.getOWLObjectIntersectionOf(clsA, - df.getOWLObjectMaxCardinality(2, op, cls1))); + df.getOWLObjectMaxCardinality(2, op, cls1))); individuals = reasoner.getIndividuals( - df.getOWLObjectIntersectionOf(clsA, - df.getOWLObjectMaxCardinality(2, op, cls1)) + df.getOWLObjectIntersectionOf(clsA, + df.getOWLObjectMaxCardinality(2, op, cls1)) ); System.out.println(individuals); individuals = reasoner.getIndividuals( - df.getOWLObjectMaxCardinality(10, op, cls1) + df.getOWLObjectMaxCardinality(10, op, cls1) ); System.out.println(individuals); individuals = reasoner.getIndividuals( - df.getOWLObjectMaxCardinality(8, op, cls1) + df.getOWLObjectMaxCardinality(8, op, cls1) ); System.out.println(individuals); individuals = reasoner.getIndividuals( - df.getOWLObjectMaxCardinality(3, op, cls1) + df.getOWLObjectMaxCardinality(3, op, cls1) ); System.out.println(individuals); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index e294b9fe18..16aa5678c7 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -42,6 +42,7 @@ import org.springframework.beans.factory.annotation.Autowired; import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl; import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; +import uk.ac.manchester.cs.owl.owlapi.OWLObjectComplementOfImpl; import java.util.*; import java.util.Map.Entry; @@ -49,7 +50,6 @@ import java.util.stream.Collectors; import static com.google.common.primitives.Ints.max; -import static java.util.stream.Collectors.summingInt; /** * A downward refinement operator, which makes use of domains @@ -191,6 +191,9 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C @ConfigOption(description="support of qualified cardinality restrictions (owl:minCardinality, owl:maxCardinality, owl:exactCardinality), e.g. \u2265 3 r.C ", defaultValue="true") private boolean useCardinalityRestrictions = true; + @ConfigOption(description="a set of roles which can be used in qualified cardinality restrictions") + protected Set allowedRolesInCardinalityRestrictions = null; + @ConfigOption(description="support of local reflexivity of an object property expression (owl:hasSelf), e.g. \u2203 loves.Self for a narcissistic", defaultValue="false") private boolean useHasSelf = false; @@ -266,6 +269,9 @@ public RhoDRDown(RhoDRDown op) { setUseStringDatatypes(op.useStringDatatypes); setUseNumericDatatypes(op.useNumericDatatypes); setUseTimeDatatypes(op.useTimeDatatypes); + setUseSomeOnly(op.useSomeOnly); + setAllowedRolesInCardinalityRestrictions(op.allowedRolesInCardinalityRestrictions); + initialized = false; } @@ -533,7 +539,9 @@ public Set refine(OWLClassExpression description, int maxLen mc = ConceptTransformation.nnf(mc); // check whether the intersection is OK (sanity checks), then add it - if(checkIntersection((OWLObjectIntersectionOf) mc)) + if(checkIntersection((OWLObjectIntersectionOf) mc) +// && checkRefinability((OWLNaryBooleanClassExpression) mc) + ) refinements.add(mc); } } @@ -564,7 +572,9 @@ public Set refine(OWLClassExpression description, int maxLen // note that we do not have to call clean here because a disjunction will // never be nested in another disjunction in this operator - refinements.add(md); +// if (checkRefinability((OWLNaryBooleanClassExpression) md)) { + refinements.add(md); +// } } } @@ -610,7 +620,9 @@ public Set refine(OWLClassExpression description, int maxLen // rule 3: EXISTS r.D => >= 2 r.D // (length increases by 1 so we have to check whether max length is sufficient) - if (useCardinalityRestrictions && + OWLObjectProperty prop = role.isAnonymous() ? role.getNamedProperty() : role.asOWLObjectProperty(); + + if (useCardinalityRestrictions && isPropertyAllowedInCardinalityRestrictions(prop) && maxLength > OWLClassExpressionUtils.getLength(description, lengthMetric) && maxNrOfFillers.get(role) > 1) { refinements.add(df.getOWLObjectMinCardinality(2, role, filler)); @@ -640,12 +652,12 @@ public Set refine(OWLClassExpression description, int maxLen } else if (description instanceof OWLObjectCardinalityRestriction) { OWLObjectPropertyExpression role = ((OWLObjectCardinalityRestriction) description).getProperty(); OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); - OWLClassExpression range = role.isAnonymous() ? opDomains.get(role.getNamedProperty()) : opRanges.get(role); + OWLClassExpression range = role.isAnonymous() ? opDomains.get(role.getNamedProperty()) : opRanges.get(role.asOWLObjectProperty()); int cardinality = ((OWLObjectCardinalityRestriction) description).getCardinality(); if(description instanceof OWLObjectMaxCardinality) { // rule 1: <= x r.C => <= x r.D if(useNegation || cardinality > 0){ - tmp = refine(filler, maxLength-lengthMetric.objectCardinalityLength-lengthMetric.objectProperyLength, null, range); + tmp = refineUpwards(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); for(OWLClassExpression d : tmp) { refinements.add(df.getOWLObjectMaxCardinality(cardinality,role,d)); @@ -654,7 +666,7 @@ public Set refine(OWLClassExpression description, int maxLen // rule 2: <= x r.C => <= (x-1) r.C // int number = max.getNumber(); - if((useNegation && cardinality > 1) || (!useNegation && cardinality > 2)){ + if (cardinality > 1) { refinements.add(df.getOWLObjectMaxCardinality(cardinality-1,role,filler)); } @@ -677,11 +689,11 @@ public Set refine(OWLClassExpression description, int maxLen refinements.add(df.getOWLObjectExactCardinality(cardinality,role,d)); } - // >= x r.C => >= (x+1) r.C + // = x r.C => = (x+1) r.C (not a downward refinement => commented out) // int number = min.getNumber(); - if(cardinality < maxNrOfFillers.get(role)){ - refinements.add(df.getOWLObjectExactCardinality(cardinality+1,role,filler)); - } +// if(cardinality < maxNrOfFillers.get(role)){ +// refinements.add(df.getOWLObjectExactCardinality(cardinality+1,role,filler)); +// } } } else if (description instanceof OWLDataSomeValuesFrom) { OWLDataProperty dp = ((OWLDataSomeValuesFrom) description).getProperty().asOWLDataProperty(); @@ -737,9 +749,10 @@ public Set refine(OWLClassExpression description, int maxLen } } - // if a refinement is not Bottom, Top, ALL r.Bottom a refinement of top can be appended + // if a refinement is not Bottom, Top, ALL r.Bottom, or intersection a refinement of top can be appended if(!description.isOWLThing() && !description.isOWLNothing() - && !(description instanceof OWLObjectAllValuesFrom && ((OWLObjectAllValuesFrom)description).getFiller().isOWLNothing())) { + && !(description instanceof OWLObjectIntersectionOf) + && !(description instanceof OWLObjectAllValuesFrom && ((OWLObjectAllValuesFrom)description).getFiller().isOWLNothing())) { // -1 because of the AND symbol which is appended int topRefLength = maxLength - OWLClassExpressionUtils.getLength(description, lengthMetric) - 1; @@ -818,7 +831,9 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if(checkIntersection(mc)) + if (checkIntersection(mc) +// && checkRefinability(mc) + ) refinements.add(mc); } } @@ -836,6 +851,183 @@ public Set refine(OWLClassExpression description, int maxLen return refinements; } + private Set refineUpwards( + OWLClassExpression description, int maxLength, + List knownRefinements, OWLClassExpression currDomain + ) { + OWLClassExpression negatedDescription = constructNegationInNNF(description); + // concept length can change because of the conversion process; as a heuristic + // we increase maxLength by the length difference of negated and original concept + int lengthDiff = Math.max(0, OWLClassExpressionUtils.getLength(negatedDescription, lengthMetric) - OWLClassExpressionUtils.getLength(description, lengthMetric)); + Set refinements = refine(negatedDescription, maxLength+lengthDiff+1, knownRefinements, currDomain); + TreeSet results = new TreeSet<>(); + + description = description.getNNF(); + + for (OWLClassExpression d : refinements) { + OWLClassExpression dNeg = constructNegationInNNF(d); + dNeg = ConceptTransformation.cleanConcept(dNeg); + + // to satisfy the guarantee that the method does not return longer + // concepts, we perform an additional check + if(description.compareTo(dNeg) != 0 && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength) { + results.add(dNeg); + } + } + + if (description.isOWLNothing()) { + results.add(df.getOWLThing()); + } + + return results; + } + + private OWLClassExpression constructNegationInNNF(OWLClassExpression description) { + OWLClassExpression negatedDescription = new OWLObjectComplementOfImpl(description); + negatedDescription = ConceptTransformation.nnf(negatedDescription); + + return negatedDescription; + } + + private boolean checkRefinability(OWLNaryBooleanClassExpression description) { + Set unrefinableOperands = new TreeSet<>(); + + for (OWLClassExpression op : description.getOperandsAsList()) { + if (unrefinableOperands.contains(op)) { + return false; + } + + if (!mayBeRefinable(op)) { + unrefinableOperands.add(op); + } + } + + return true; + } + + private boolean mayBeRefinable(OWLClassExpression description) { + if (description.isOWLThing()) { + return true; + } + + if (description.isOWLNothing()) { + return false; + } + + if(!description.isAnonymous()) { + Set refinements = classHierarchy.getSubClasses(description, true); + refinements.remove(df.getOWLNothing()); + + return !refinements.isEmpty(); + } + + if (description instanceof OWLObjectComplementOf) { + OWLClassExpression operand = ((OWLObjectComplementOf) description).getOperand(); + + if (operand.isAnonymous()){ + return false; + } + + Set refinements = classHierarchy.getSuperClasses(operand, true); + refinements.remove(df.getOWLThing()); + + return !refinements.isEmpty(); + } + + if (description instanceof OWLObjectIntersectionOf || description instanceof OWLObjectUnionOf) { + return true; + } + + if (description instanceof OWLObjectSomeValuesFrom) { + OWLObjectPropertyExpression role = ((OWLObjectSomeValuesFrom) description).getProperty(); + OWLClassExpression filler = ((OWLObjectSomeValuesFrom) description).getFiller(); + + if (mayBeRefinable(filler)) { + return true; + } + + Set moreSpecialRoles = objectPropertyHierarchy.getMoreSpecialRoles(role.getNamedProperty()); + + if (!moreSpecialRoles.isEmpty()) { + return true; + } + + OWLObjectProperty prop = role.isAnonymous() ? role.getNamedProperty() : role.asOWLObjectProperty(); + + if (useCardinalityRestrictions + && isPropertyAllowedInCardinalityRestrictions(prop) + && maxNrOfFillers.get(role) > 1 + ) { + return true; + } + + if (useHasValueConstructor && filler.isOWLThing()){ + Set frequentIndividuals = frequentValues.get(role); + + return frequentIndividuals != null; + } + + return false; + } + + if (description instanceof OWLObjectAllValuesFrom) { + OWLObjectPropertyExpression role = ((OWLObjectAllValuesFrom) description).getProperty(); + OWLClassExpression filler = ((OWLObjectAllValuesFrom) description).getFiller(); + + if (mayBeRefinable(filler)) { + return true; + } + + if (!filler.isOWLNothing() && !filler.isAnonymous()) { + return true; + } + + Set subProperties = objectPropertyHierarchy.getMoreSpecialRoles(role.getNamedProperty()); + + return !subProperties.isEmpty(); + } + + if (description instanceof OWLObjectCardinalityRestriction) { + OWLObjectPropertyExpression role = ((OWLObjectCardinalityRestriction) description).getProperty(); + OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); + int cardinality = ((OWLObjectCardinalityRestriction) description).getCardinality(); + + if (description instanceof OWLObjectMaxCardinality) { + if (cardinality > 1) { + return true; + } + + return (useNegation || cardinality > 0) && mayBeRefinable(constructNegationInNNF(description)); + } + + if (description instanceof OWLObjectMinCardinality) { + return cardinality < maxNrOfFillers.get(role) || mayBeRefinable(filler); + } + + if (description instanceof OWLObjectExactCardinality) { + return mayBeRefinable(filler); + } + } + + if (description instanceof OWLDataSomeValuesFrom) { + return true; // TODO: not implemented + } + + if (description instanceof OWLDataHasValue) { + OWLDataPropertyExpression dp = ((OWLDataHasValue) description).getProperty(); + + if (dp.isAnonymous()) { + return false; + } + + Set subDPs = dataPropertyHierarchy.getMoreSpecialRoles(dp.asOWLDataProperty()); + + return !subDPs.isEmpty(); + } + + return false; + } + private boolean isCombinable(OWLClassExpression ce, OWLClassExpression child) { boolean combinable = true; @@ -868,7 +1060,7 @@ private Set refine(OWLObjectAllValuesFrom ce, int maxLength) OWLObjectPropertyExpression role = ce.getProperty(); OWLClassExpression filler = ce.getFiller(); - OWLClassExpression range = role.isAnonymous() ? opDomains.get(role.getNamedProperty()) : opRanges.get(role); + OWLClassExpression range = role.isAnonymous() ? opDomains.get(role.getNamedProperty()) : opRanges.get(role.asOWLObjectProperty()); // rule 1: ALL r.D => ALL r.E Set tmp = refine(filler, maxLength-lengthMetric.objectAllValuesLength-lengthMetric.objectProperyLength, null, range); @@ -877,8 +1069,9 @@ private Set refine(OWLObjectAllValuesFrom ce, int maxLength) refinements.add(df.getOWLObjectAllValuesFrom(role, c)); } - // rule 2: ALL r.D => ALL r.BOTTOM if D is a most specific atomic concept - if(!filler.isOWLNothing() && !filler.isAnonymous() && tmp.size()==0) { + // rule 2 UPDATED: ALL r.TOP => ALL r.BOTTOM + // rationale behind the update: the concepts of the form ALL r.BOTTOM were previously really hard to reach + if(filler.isOWLThing()) { refinements.add(df.getOWLObjectAllValuesFrom(role, df.getOWLNothing())); } @@ -1231,15 +1424,17 @@ private void computeM() { logger.debug(sparql_debug, "most general properties:"); int lc = lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength; for(OWLObjectProperty r : objectPropertyHierarchy.getMostGeneralRoles()) { - int maxFillers = maxNrOfFillers.get(r); - logger.debug(sparql_debug, "`"+r+"="+maxFillers); - // zero fillers: <= -1 r.C does not make sense - // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, - // but we still keep it, because ALL r.NOT C may be difficult to reach - if((useNegation && maxFillers > 0) || (!useNegation && maxFillers > 1)) - m.get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLThing())); - -// m.get(lc).add(df.getOWLObjectExactCardinality(1, r, df.getOWLThing())); + if (isPropertyAllowedInCardinalityRestrictions(r)) { + int maxFillers = maxNrOfFillers.get(r); + logger.debug(sparql_debug, "`"+r+"="+maxFillers); + // zero fillers: <= -1 r.C does not make sense + // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, + // but we still keep it, because ALL r.NOT C may be difficult to reach + if((useNegation && maxFillers > 0) || (!useNegation && maxFillers > 1)) + m.get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLNothing())); + +// m.get(lc).add(df.getOWLObjectExactCardinality(1, r, df.getOWLThing())); + } } } @@ -1384,10 +1579,10 @@ private void computeM(OWLClassExpression nc) { // .collect(Collectors.toSet())); for(OWLObjectProperty p : mgr.get(nc)) { Set values = frequentValues.get(p); - values.forEach(val -> m.get(lc).add(df.getOWLObjectHasValue(p, val))); + values.forEach(val -> mA.get(nc).get(lc).add(df.getOWLObjectHasValue(p, val))); if(useInverse) { - values.forEach(val -> m.get(lc_i).add(df.getOWLObjectHasValue(p.getInverseProperty(), val))); + values.forEach(val -> mA.get(nc).get(lc_i).add(df.getOWLObjectHasValue(p.getInverseProperty(), val))); } } } @@ -1395,23 +1590,25 @@ private void computeM(OWLClassExpression nc) { if(useCardinalityRestrictions) { int lc = lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength; for(OWLObjectProperty r : mgr.get(nc)) { - int maxFillers = maxNrOfFillers.get(r); - // zero fillers: <= -1 r.C does not make sense - // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, - // but we still keep it, because ALL r.NOT C may be difficult to reach - if((useNegation && maxFillers > 0) || (!useNegation && maxFillers > 1)) { - mA.get(nc).get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLThing())); - } + if (isPropertyAllowedInCardinalityRestrictions(r)) { + int maxFillers = maxNrOfFillers.get(r); + // zero fillers: <= -1 r.C does not make sense + // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, + // but we still keep it, because ALL r.NOT C may be difficult to reach + if ((useNegation && maxFillers > 0) || (!useNegation && maxFillers > 1)) { + mA.get(nc).get(lc).add(df.getOWLObjectMaxCardinality(maxFillers - 1, r, df.getOWLNothing())); + } - // = 1 r.C -// mA.get(nc).get(lc).add(df.getOWLObjectExactCardinality(1, r, df.getOWLThing())); + // = 1 r.C +// mA.get(nc).get(lc).add(df.getOWLObjectExactCardinality(1, r, df.getOWLThing())); + } } } if(useHasSelf) { int lc = lengthMetric.objectSomeValuesLength + lengthMetric.objectProperyLength + lengthMetric.objectHasSelfLength; for(OWLObjectProperty p : mgr.get(nc)) { - m.get(lc).add(df.getOWLObjectHasSelf(p)); + mA.get(nc).get(lc).add(df.getOWLObjectHasSelf(p)); } } @@ -1493,7 +1690,7 @@ private SortedSet getNegClassCandidatesRecursive(OWLClassExp SortedSet candidates = new TreeSet<>(); // System.out.println("index " + index + " lower class " + lowerClass); - SortedSet superClasses = classHierarchy.getSuperClasses(lowerClass); + SortedSet superClasses = classHierarchy.getSuperClasses(lowerClass, true); if(reasoner instanceof SPARQLReasoner) { Collection meaningfulClasses = ((SPARQLReasoner)reasoner).getMeaningfulClasses(index, superClasses); @@ -1601,27 +1798,17 @@ private void computeApp(OWLClassExpression domain) { Set roleAppRoles = ((SPARQLReasoner) reasoner).getApplicableProperties(domain, mostGeneral); applicableRoles.addAll(roleAppRoles); } else { - SortedSet individuals1 = reasoner.getIndividuals(domain); // object properties for (OWLObjectProperty role : mostGeneral) { - // TODO: currently we just rely on named classes as roles, - // instead of computing dom(r) and ran(r) - OWLClassExpression d = opDomains.get(role); - - Set individuals2 = new HashSet<>(); - for (Entry> entry : reasoner.getPropertyMembers(role).entrySet()) { - OWLIndividual ind = entry.getKey(); - if (!entry.getValue().isEmpty()) { - individuals2.add(ind); - } + if (role.isTopEntity()) { + continue; } - boolean disjoint = Sets.intersection(individuals1, individuals2).isEmpty(); -// if(!isDisjoint(domain,d)) - if (!disjoint) { + OWLClassExpression d = opDomains.get(role); + + if (!isDisjoint(domain, d)) { // TODO: maybe do not use isDisjoint, it is meant for classes only applicableRoles.add(role); } - } } @@ -1779,6 +1966,10 @@ private boolean isNotAMeaningful(OWLClass a, OWLClass b) { return !reasoner.isSuperClassOf(d, b); } + private boolean isPropertyAllowedInCardinalityRestrictions(OWLObjectProperty property) { + return allowedRolesInCardinalityRestrictions == null || allowedRolesInCardinalityRestrictions.contains(property); + } + public int getFrequencyThreshold() { return frequencyThreshold; } @@ -2036,4 +2227,12 @@ public void setLengthMetric(OWLClassExpressionLengthMetric lengthMetric) { public void setNumericValuesSplitter(ValuesSplitter numericValuesSplitter) { this.numericValuesSplitter = numericValuesSplitter; } + + public Set getAllowedRolesInCardinalityRestrictions() { + return allowedRolesInCardinalityRestrictions; + } + + public void setAllowedRolesInCardinalityRestrictions(Set allowedRolesInCardinalityRestrictions) { + this.allowedRolesInCardinalityRestrictions = allowedRolesInCardinalityRestrictions; + } } diff --git a/components-core/src/main/java/org/dllearner/utilities/owl/ExpressionDecomposer.java b/components-core/src/main/java/org/dllearner/utilities/owl/ExpressionDecomposer.java new file mode 100644 index 0000000000..d509b26122 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/utilities/owl/ExpressionDecomposer.java @@ -0,0 +1,167 @@ +package org.dllearner.utilities.owl; + +import org.jetbrains.annotations.NotNull; +import org.semanticweb.owlapi.model.*; + +import java.util.ArrayList; +import java.util.List; + +// generates a list of all subexpressions (not proper, i.e. the concept itself is also included) +public class ExpressionDecomposer implements OWLClassExpressionVisitorEx> { + + public List decompose(OWLClassExpression expression) { + return expression.accept(this); + } + + @NotNull + @Override + public List visit(@NotNull OWLClass owlClass) { + return List.of(owlClass); + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectIntersectionOf owlObjectIntersectionOf) { + List result = new ArrayList<>(); + result.add(owlObjectIntersectionOf); + + for (OWLClassExpression op : owlObjectIntersectionOf.getOperandsAsList()) { + result.addAll(op.accept(this)); + } + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectUnionOf owlObjectUnionOf) { + List result = new ArrayList<>(); + result.add(owlObjectUnionOf); + + for (OWLClassExpression op : owlObjectUnionOf.getOperandsAsList()) { + result.addAll(op.accept(this)); + } + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectComplementOf owlObjectComplementOf) { + List result = new ArrayList<>(); + result.add(owlObjectComplementOf); + + result.addAll(owlObjectComplementOf.getOperand().accept(this)); + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectSomeValuesFrom owlObjectSomeValuesFrom) { + List result = new ArrayList<>(); + result.add(owlObjectSomeValuesFrom); + + result.addAll(owlObjectSomeValuesFrom.getFiller().accept(this)); + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectAllValuesFrom owlObjectAllValuesFrom) { + List result = new ArrayList<>(); + result.add(owlObjectAllValuesFrom); + + result.addAll(owlObjectAllValuesFrom.getFiller().accept(this)); + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectHasValue owlObjectHasValue) { + return List.of(owlObjectHasValue); + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectMinCardinality owlObjectMinCardinality) { + List result = new ArrayList<>(); + result.add(owlObjectMinCardinality); + + result.addAll(owlObjectMinCardinality.getFiller().accept(this)); + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectExactCardinality owlObjectExactCardinality) { + List result = new ArrayList<>(); + result.add(owlObjectExactCardinality); + + result.addAll(owlObjectExactCardinality.getFiller().accept(this)); + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectMaxCardinality owlObjectMaxCardinality) { + List result = new ArrayList<>(); + result.add(owlObjectMaxCardinality); + + result.addAll(owlObjectMaxCardinality.getFiller().accept(this)); + + return result; + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectHasSelf owlObjectHasSelf) { + return List.of(owlObjectHasSelf); + } + + @NotNull + @Override + public List visit(@NotNull OWLObjectOneOf owlObjectOneOf) { + return List.of(owlObjectOneOf); + } + + @NotNull + @Override + public List visit(@NotNull OWLDataSomeValuesFrom owlDataSomeValuesFrom) { + return List.of(owlDataSomeValuesFrom); + } + + @NotNull + @Override + public List visit(@NotNull OWLDataAllValuesFrom owlDataAllValuesFrom) { + return List.of(owlDataAllValuesFrom); + } + + @NotNull + @Override + public List visit(@NotNull OWLDataHasValue owlDataHasValue) { + return List.of(owlDataHasValue); + } + + @NotNull + @Override + public List visit(@NotNull OWLDataMinCardinality owlDataMinCardinality) { + return List.of(owlDataMinCardinality); + } + + @NotNull + @Override + public List visit(@NotNull OWLDataExactCardinality owlDataExactCardinality) { + return List.of(owlDataExactCardinality); + } + + @NotNull + @Override + public List visit(@NotNull OWLDataMaxCardinality owlDataMaxCardinality) { + return List.of(owlDataMaxCardinality); + } +} diff --git a/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionCleaner.java b/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionCleaner.java index f569ac80b3..c8867a9896 100644 --- a/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionCleaner.java +++ b/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionCleaner.java @@ -81,6 +81,11 @@ public OWLClassExpression visit(OWLObjectIntersectionOf ce) { operands.add(newOperand); } } + + if (operands.size() == 1) { + return operands.get(0); + } + Collections.sort(operands); return new OWLObjectIntersectionOfImplExt(operands); } @@ -99,6 +104,11 @@ public OWLClassExpression visit(OWLObjectUnionOf ce) { operands.add(newOperand); } } + + if (operands.size() == 1) { + return operands.get(0); + } + Collections.sort(operands); return new OWLObjectUnionOfImplExt(operands); } diff --git a/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionMinimizer.java b/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionMinimizer.java index 77b1d2ffc3..5ad0e20410 100644 --- a/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionMinimizer.java +++ b/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionMinimizer.java @@ -165,7 +165,7 @@ public OWLClassExpression visit(OWLObjectUnionOf ce) { newOperands.remove(op2); } else if(isSubClassOf(op1, op2)){ newOperands.remove(op1); - } else if(isSubClassOf(op1, df.getOWLObjectComplementOf(op2)) || isSubClassOf(op2, df.getOWLObjectComplementOf(op1))) { + } else if(reasoner.isEquivalentClass(op1, df.getOWLObjectComplementOf(op2))) { // check for C or not C return df.getOWLThing(); } diff --git a/interfaces/pom.xml b/interfaces/pom.xml index edbcdb8853..cb8c690eb9 100644 --- a/interfaces/pom.xml +++ b/interfaces/pom.xml @@ -67,7 +67,7 @@ interfaces - + org.codehaus.mojo appassembler-maven-plugin @@ -110,7 +110,9 @@ true - -Xms256m -Xmx2g + -Xms256m -Xmx64g + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.base/java.lang.invoke=ALL-UNNAMED -Dlog4j.configuration=file:@BASEDIR@/etc/log4j.properties false From 3ec54fd8a2c4ce6db953aa06b443d5f813bcae50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Tue, 28 Feb 2023 19:15:32 +0100 Subject: [PATCH 02/67] parcel integration, useNegation support --- components-core/pom.xml | 5 + .../org/dllearner/algorithms/celoe/CELOE.java | 34 +- .../org/dllearner/algorithms/ocel/OCEL.java | 30 +- .../algorithms/parcel/ParCELAbstract.java | 951 ++++++++ .../parcel/ParCELCompletenessComparator.java | 37 + .../parcel/ParCELCorrectnessComparator.java | 36 + ...arCELCoveredNegativeExampleComparator.java | 37 + .../parcel/ParCELDefaultHeuristic.java | 137 ++ ...CELDefinitionGenerationTimeComparator.java | 40 + .../ParCELDefinitionLengthComparator.java | 35 + .../parcel/ParCELEvaluationResult.java | 146 ++ .../algorithms/parcel/ParCELExtraNode.java | 167 ++ .../algorithms/parcel/ParCELHeuristic.java | 16 + .../algorithms/parcel/ParCELNode.java | 105 + .../algorithms/parcel/ParCELOntologyUtil.java | 83 + .../algorithms/parcel/ParCELPosNegLP.java | 640 +++++ .../ParCELRefinementOperatorFactory.java | 208 ++ .../parcel/ParCELRefinementOperatorPool.java | 112 + .../algorithms/parcel/ParCELScore.java | 38 + .../parcel/ParCELStringUtilities.java | 48 + .../algorithms/parcel/ParCELWorker.java | 185 ++ .../parcel/ParCELWorkerAbstract.java | 162 ++ .../parcel/ParCELWorkerThreadFactory.java | 20 + .../algorithms/parcel/ParCELearner.java | 360 +++ .../algorithms/parcel/ParCELearnerMBean.java | 18 + .../algorithms/parcel/celoe/CELOEPartial.java | 1290 ++++++++++ .../ParCELCorrectnessGreedyReducer.java | 94 + .../reducer/ParCELCoverageGreedyReducer.java | 77 + .../ParCELDefinitionLengthReducer.java | 57 + .../reducer/ParCELGenerationTimeReducer.java | 60 + .../ParCELImprovedCoverageGreedyReducer.java | 115 + ...arCELImprovedCoverageGreedyReducer_V2.java | 205 ++ .../parcel/reducer/ParCELReducer.java | 46 + .../split/ParCELDoubleSplitterAbstract.java | 82 + .../parcel/split/ParCELDoubleSplitterV1.java | 390 +++ .../algorithms/parcel/split/ValueCount.java | 113 + .../parcel/split/ValueCountSet.java | 60 + .../algorithms/parcelex/ParCELExAbstract.java | 186 ++ ...rCELExCombineCounterPartialDefinition.java | 134 + .../parcelex/ParCELExNodeTypes.java | 67 + .../parcelex/ParCELExUtilities.java | 73 + .../parcelex/ParCELExWorkerAbstract.java | 105 + .../algorithms/parcelex/ParCELWorkerExV1.java | 154 ++ .../parcelex/ParCELWorkerExV12.java | 175 ++ .../algorithms/parcelex/ParCELWorkerExV2.java | 213 ++ .../algorithms/parcelex/ParCELearnerExV1.java | 499 ++++ .../parcelex/ParCELearnerExV12.java | 868 +++++++ .../algorithms/parcelex/ParCELearnerExV2.java | 606 +++++ .../java/org/dllearner/core/AbstractCELA.java | 34 +- .../core/owl/ObjectPropertyHierarchy.java | 24 - .../refinementoperators/RhoDRDown.java | 91 +- .../owl/OWLClassExpressionUtils.java | 35 +- .../uncle_owl_large_parcelEx2_cross.conf | 127 + .../uncle_owl_large_parcelEx2_learn.conf | 127 + .../forte/uncle_owl_large_parcel_learn.conf | 126 + .../abd.muse.massey.ac.nz.owl | 809 ++++++ .../uca1_150_celoe_cross_noSplit12_180s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit12_300s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit12_600s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit38_180s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit38_300s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit38_600s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit38_60s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit38_90s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit6_180s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit6_300s.conf | 193 ++ .../uca1_150_celoe_cross_noSplit6_600s.conf | 193 ++ ...a1_150_parcel_cross_noSplitter12_180s.conf | 197 ++ ...a1_150_parcel_cross_noSplitter12_300s.conf | 197 ++ ...a1_150_parcel_cross_noSplitter12_600s.conf | 197 ++ ...a1_150_parcel_cross_noSplitter40_180s.conf | 197 ++ ...a1_150_parcel_cross_noSplitter40_300s.conf | 197 ++ ...a1_150_parcel_cross_noSplitter40_600s.conf | 197 ++ ...ca1_150_parcel_cross_noSplitter6_180s.conf | 197 ++ ...ca1_150_parcel_cross_noSplitter6_300s.conf | 197 ++ ...ca1_150_parcel_cross_noSplitter6_600s.conf | 197 ++ examples/showering-duration/uca1_150.owl | 2153 ++++++++++++++++ .../uca1_150_celoe_cross_300s.conf | 190 ++ .../uca1_150_celoe_cross_600s.conf | 190 ++ .../uca1_150_celoe_fort_300s.conf | 190 ++ .../uca1_150_celoe_learn_180s.conf | 190 ++ .../uca1_150_parcelEx12_cross.conf | 192 ++ .../uca1_150_parcelEx12_learn.conf | 191 ++ .../uca1_150_parcelEx1_cross.conf | 195 ++ .../uca1_150_parcelEx1_learn.conf | 195 ++ .../uca1_150_parcelEx2_cross.conf | 192 ++ .../uca1_150_parcelEx2_fort.conf | 192 ++ .../uca1_150_parcelEx2_learn.conf | 192 ++ .../uca1_150_parcel_cross.conf | 199 ++ .../uca1_150_parcel_fort.conf | 195 ++ .../uca1_150_parcel_learn.conf | 195 ++ .../org/dllearner/cli/CrossValidation.java | 10 + .../dllearner/cli/ExpressionValidation.java | 133 +- ...OEFortifiedCrossValidation3PhasesFair.java | 2021 +++++++++++++++ .../java/org/dllearner/cli/parcel/CLI.java | 400 +++ .../cli/parcel/ParCELCrossValidation.java | 652 +++++ .../ParCELExFortifiedCrossValidation.java | 1184 +++++++++ ...rCELExFortifiedCrossValidation3Phases.java | 2165 +++++++++++++++++ .../cli/parcel/ParCELExtraTestingNode.java | 67 + ...ELFortifiedCrossValidation3PhasesFair.java | 2092 ++++++++++++++++ .../ParCELTestingCorrectnessComparator.java | 58 + .../parcel/ParCELValidationMultiReducers.java | 506 ++++ .../cli/parcel/ParCELvaliadationData.java | 22 + .../java/org/dllearner/cli/parcel/Test.java | 65 + .../fortification/ConceptSimilarity.java | 1090 +++++++++ .../fortification/FortificationUtils.java | 703 ++++++ .../fortification/JaccardSimilarity.java | 473 ++++ .../cli/parcel/modeling/FoldInfor.java | 114 + .../parcel/modeling/FoldInforComparator.java | 25 + .../modeling/ParCELActualModelScoring.java | 90 + .../ParCELPredictionModelScoring.java | 212 ++ .../ParCELValidationModelAnalysis.java | 435 ++++ .../cli/parcel/modeling/PhaseInfor.java | 67 + 113 files changed, 31941 insertions(+), 82 deletions(-) create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCorrectnessComparator.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionGenerationTimeComparator.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionLengthComparator.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELEvaluationResult.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELHeuristic.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELOntologyUtil.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorPool.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELScore.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELStringUtilities.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerThreadFactory.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearnerMBean.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/celoe/CELOEPartial.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCorrectnessGreedyReducer.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCoverageGreedyReducer.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELDefinitionLengthReducer.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELGenerationTimeReducer.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELReducer.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterAbstract.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterV1.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCount.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCountSet.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExCombineCounterPartialDefinition.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExNodeTypes.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExUtilities.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java create mode 100644 components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java create mode 100644 examples/forte/uncle_owl_large_parcelEx2_cross.conf create mode 100644 examples/forte/uncle_owl_large_parcelEx2_learn.conf create mode 100644 examples/forte/uncle_owl_large_parcel_learn.conf create mode 100644 examples/showering-duration/abd.muse.massey.ac.nz.owl create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_180s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_300s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_600s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_180s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_300s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_600s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_60s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_90s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_180s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_300s.conf create mode 100644 examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_600s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_180s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_300s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_600s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_180s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_300s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_600s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_180s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_300s.conf create mode 100644 examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_600s.conf create mode 100644 examples/showering-duration/uca1_150.owl create mode 100644 examples/showering-duration/uca1_150_celoe_cross_300s.conf create mode 100644 examples/showering-duration/uca1_150_celoe_cross_600s.conf create mode 100644 examples/showering-duration/uca1_150_celoe_fort_300s.conf create mode 100644 examples/showering-duration/uca1_150_celoe_learn_180s.conf create mode 100644 examples/showering-duration/uca1_150_parcelEx12_cross.conf create mode 100644 examples/showering-duration/uca1_150_parcelEx12_learn.conf create mode 100644 examples/showering-duration/uca1_150_parcelEx1_cross.conf create mode 100644 examples/showering-duration/uca1_150_parcelEx1_learn.conf create mode 100644 examples/showering-duration/uca1_150_parcelEx2_cross.conf create mode 100644 examples/showering-duration/uca1_150_parcelEx2_fort.conf create mode 100644 examples/showering-duration/uca1_150_parcelEx2_learn.conf create mode 100644 examples/showering-duration/uca1_150_parcel_cross.conf create mode 100644 examples/showering-duration/uca1_150_parcel_fort.conf create mode 100644 examples/showering-duration/uca1_150_parcel_learn.conf create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/CELOEFortifiedCrossValidation3PhasesFair.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/CLI.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELCrossValidation.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation3Phases.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExtraTestingNode.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELFortifiedCrossValidation3PhasesFair.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELTestingCorrectnessComparator.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELValidationMultiReducers.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/ParCELvaliadationData.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/Test.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/fortification/ConceptSimilarity.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/fortification/FortificationUtils.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/fortification/JaccardSimilarity.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInfor.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInforComparator.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELActualModelScoring.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELPredictionModelScoring.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELValidationModelAnalysis.java create mode 100644 interfaces/src/main/java/org/dllearner/cli/parcel/modeling/PhaseInfor.java diff --git a/components-core/pom.xml b/components-core/pom.xml index 8319a8e129..48a6506bdb 100644 --- a/components-core/pom.xml +++ b/components-core/pom.xml @@ -519,6 +519,11 @@ commons-math3 + + org.apache.commons + commons-pool2 + + org.jgrapht jgrapht-core diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index 2c02e868af..88162a85a4 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -21,9 +21,6 @@ import com.google.common.collect.Sets; import com.jamonapi.Monitor; import com.jamonapi.MonitorFactory; -import org.dllearner.algorithms.ocel.ExampleBasedNode; -import org.dllearner.algorithms.ocel.MultiHeuristic; -import org.dllearner.algorithms.ocel.QualityBasedComparator; import org.dllearner.core.*; import org.dllearner.core.config.ConfigOption; import org.dllearner.core.owl.ClassHierarchy; @@ -366,6 +363,7 @@ public void start() { currentHighestAccuracy = 0.0; OENode nextNode; + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); logger.info("start class:" + startClass); addNode(startClass, null); @@ -373,13 +371,11 @@ public void start() { showIfBetterSolutionsFound(); // chose best node according to heuristics -// long s = System.nanoTime(); nextNode = getNextNodeToExpand(); int horizExp = nextNode.getHorizontalExpansion(); // apply refinement operator TreeSet refinements = refineNode(nextNode); -// accTime += (System.nanoTime() - s) / 1000; while(!refinements.isEmpty() && !terminationCriteriaSatisfied()) { // pick element from set @@ -399,7 +395,7 @@ public void start() { showIfBetterSolutionsFound(); // update the global min and max horizontal expansion values -// updateMinMaxHorizExp(nextNode); + updateMinMaxHorizExp(nextNode); // write the search tree (if configured) if (writeSearchTree) { @@ -418,6 +414,8 @@ public void start() { // print solution(s) logger.info("solutions:\n" + getSolutionString()); + + printBestConceptsTimesAndAccuracies(); isRunning = false; } @@ -668,7 +666,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { ) ) ) { - solutionCandidates.put(node, getCurrentRuntimeInMilliSeconds() / 1000.0); + solutionCandidates.put(node, getCurrentCpuMillis() / 1000.0); } if (solutionCandidates.size() > maxNrOfResultsWithinMargin) { @@ -806,8 +804,8 @@ private boolean terminationCriteriaSatisfied() { stop || (maxClassExpressionTestsAfterImprovement != 0 && (expressionTests - expressionTestCountLastImprovement >= maxClassExpressionTestsAfterImprovement)) || (maxClassExpressionTests != 0 && (expressionTests >= maxClassExpressionTests)) || - (maxExecutionTimeInSecondsAfterImprovement != 0 && ((System.nanoTime() - nanoStartTime) >= (maxExecutionTimeInSecondsAfterImprovement* 1000000000L))) || - (maxExecutionTimeInSeconds != 0 && ((System.nanoTime() - nanoStartTime) >= (maxExecutionTimeInSeconds* 1000000000L))) || + (maxExecutionTimeInSecondsAfterImprovement != 0 && ((getCurrentCpuMillis() - timeLastImprovement) >= (maxExecutionTimeInSecondsAfterImprovement * 1000L))) || + (maxExecutionTimeInSeconds != 0 && (getCurrentCpuMillis() >= (maxExecutionTimeInSeconds * 1000L))) || (terminateOnNoiseReached && (100*getCurrentlyBestAccuracy()>=100-noisePercentage)) || (stopOnFirstDefinition && (getCurrentlyBestAccuracy() >= 1)); } @@ -845,7 +843,7 @@ private void printSolutionCandidates() { for (OENode c : solutionCandidates.descendingKeySet()) { logger.info(show + ": " + renderer.render(c.getDescription()) + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " - + df.format(100 * computeTestingAccuracy(c.getDescription())) + "%" + + df.format(100 * computeTestAccuracy(c.getDescription())) + "%" + ", length " + OWLClassExpressionUtils.getLength(c.getDescription()) + ", depth " + OWLClassExpressionUtils.getDepth(c.getDescription()) + ", time " + df.format(solutionCandidates.get(c)) + "s)"); @@ -863,19 +861,29 @@ private void showIfBetterSolutionsFound() { if(!singleSuggestionMode && bestEvaluatedDescriptions.getBestAccuracy() > currentHighestAccuracy) { currentHighestAccuracy = bestEvaluatedDescriptions.getBestAccuracy(); expressionTestCountLastImprovement = expressionTests; - timeLastImprovement = System.nanoTime(); + timeLastImprovement = getCurrentCpuMillis(); long durationInMillis = getCurrentRuntimeInMilliSeconds(); String durationStr = getDurationAsString(durationInMillis); + double cpuTime = getCurrentCpuMillis() / 1000.0; + OWLClassExpression bestDescription = bestEvaluatedDescriptions.getBest().getDescription(); - double testAccuracy = computeTestingAccuracy(bestDescription); + double testAccuracy = computeTestAccuracy(bestDescription); // track new best accuracy if enabled if(keepTrackOfBestScore) { runtimeVsBestScore.put(getCurrentRuntimeInMilliSeconds(), currentHighestAccuracy); } - logger.info("more accurate (training: " + dfPercent.format(currentHighestAccuracy) + ", testing: " + dfPercent.format(testAccuracy) + ") class expression found after " + durationStr + ": " + descriptionToString(bestEvaluatedDescriptions.getBest().getDescription())); + logger.info( + "Time " + cpuTime + + "s: more accurate (training: " + dfPercent.format(currentHighestAccuracy) + + ", test: " + dfPercent.format(testAccuracy) + + ") class expression found after " + durationStr + ": " + + descriptionToString(bestEvaluatedDescriptions.getBest().getDescription()) + ); + + recordBestConceptTimeAndAccuracy(cpuTime, currentHighestAccuracy, testAccuracy); } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index 77369c9d9a..3f003c4d40 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -474,6 +474,7 @@ public void start() { ExampleBasedNode bestNode = startNode; ExampleBasedNode bestNodeStable = startNode; + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); logger.info("starting top down refinement with: " + renderer.render(startNode.getConcept()) + " (" + df.format(100 * startNode.getAccuracy()) + "% accuracy)"); int loop = 0; @@ -512,18 +513,24 @@ public void start() { // we record when a more accurate node is found and log it if (bestNodeStable.getCovPosMinusCovNeg() < searchTreeStable.best() .getCovPosMinusCovNeg()) { - String acc = new DecimalFormat(".00%").format((searchTreeStable.best().getAccuracy())); - String testAcc = new DecimalFormat(".00%").format(computeTestingAccuracy(searchTreeStable.best().getConcept())); + double time = getCurrentCpuMillis() / 1000.0; + double acc = (searchTreeStable.best().getAccuracy()); + double testAcc = computeTestAccuracy(searchTreeStable.best().getConcept()); + + DecimalFormat percentFormatter = new DecimalFormat(".00%"); // no handling needed, it will just look ugly in the output logger.info( - "Time " + ((System.currentTimeMillis() - runtime) / 1000.0) + - "s: more accurate (training: " + acc + ", testing: " + testAcc + + "Time " + time + + "s: more accurate (training: " + percentFormatter.format(acc) + ", test: " + percentFormatter.format(testAcc) + ") class expression found: " + renderer.render(searchTreeStable.best().getConcept()) ); if (logger.isTraceEnabled()) { logger.trace(Sets.difference(positiveExamples, bestNodeStable.getCoveredNegatives()).toString()); logger.trace(Sets.difference(negativeExamples, bestNodeStable.getCoveredNegatives()).toString()); } + + recordBestConceptTimeAndAccuracy(time, acc, testAcc); + printBestSolutions(5); printStatistics(false); bestNodeStable = searchTreeStable.best(); @@ -568,7 +575,7 @@ public void start() { for (ExampleBasedNode c : solutionCandidates.descendingKeySet()) { logger.info(show + ": " + renderer.render(c.getConcept()) + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " - + df.format(100 * computeTestingAccuracy(c.getConcept())) + "%" + + df.format(100 * computeTestAccuracy(c.getConcept())) + "%" + ", length " + OWLClassExpressionUtils.getLength(c.getConcept()) + ", depth " + OWLClassExpressionUtils.getDepth(c.getConcept()) + ", time " + df.format(solutionCandidates.get(c)) + "s)"); @@ -588,7 +595,7 @@ public void start() { for (ExampleBasedNode c : solutions.descendingKeySet()) { logger.info(show + ": " + renderer.render(c.getConcept()) + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " - + df.format(100 * computeTestingAccuracy(c.getConcept())) + "%" + + df.format(100 * computeTestAccuracy(c.getConcept())) + "%" + ", length " + OWLClassExpressionUtils.getLength(c.getConcept()) + ", depth " + OWLClassExpressionUtils.getDepth(c.getConcept()) + ", time " + df.format(solutions.get(c)) + "s)"); @@ -601,6 +608,9 @@ public void start() { logger.info("no appropriate solutions found (try increasing the noisePercentage parameter to what was reported as most accurate expression found above)"); } + + printBestConceptsTimesAndAccuracies(); + logger.debug("size of candidate set: " + searchTree.size()); printBestSolutions(20); @@ -857,7 +867,7 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, // Lösung gefunden if (quality >= 0) { if (quality <= allowedMisclassifications) { - solutions.put(newNode, (System.currentTimeMillis() - runtime) / 1000.0); + solutions.put(newNode, getCurrentCpuMillis() / 1000.0); if (solutions.size() > maxNrOfResults) { solutions.pollFirstEntry(); @@ -872,7 +882,7 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, ) ) ) { - solutionCandidates.put(newNode, (System.currentTimeMillis() - runtime) / 1000.0); + solutionCandidates.put(newNode, getCurrentCpuMillis() / 1000.0); } if (solutionCandidates.size() > maxNrOfResultsWithinMargin) { @@ -1231,7 +1241,7 @@ private boolean isTerminationCriteriaReached() { return true; } - long totalTimeNeeded = System.currentTimeMillis() - this.runtime; + long totalTimeNeeded = getCurrentCpuMillis(); long maxMilliSeconds = maxExecutionTimeInSeconds * 1000; long minMilliSeconds = minExecutionTimeInSeconds * 1000; int conceptTests = conceptTestsReasoner + conceptTestsTooWeakList + conceptTestsOverlyGeneralList; @@ -1244,7 +1254,7 @@ private boolean isTerminationCriteriaReached() { else if (maxExecutionTimeAlreadyReached) return true; //test - else if (maxMilliSeconds < totalTimeNeeded) { + else if (maxMilliSeconds <= totalTimeNeeded) { this.stop(); logger.info("Maximum time (" + maxExecutionTimeInSeconds + " seconds) reached, stopping now..."); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java new file mode 100644 index 0000000000..d739f7e773 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -0,0 +1,951 @@ +package org.dllearner.algorithms.parcel; + +import org.apache.log4j.Logger; +import org.dllearner.algorithms.celoe.OENode; +import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer; +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterAbstract; +import org.dllearner.core.*; +import org.dllearner.core.config.ConfigOption; +import org.dllearner.core.owl.ClassHierarchy; +import org.dllearner.core.owl.DatatypePropertyHierarchy; +import org.dllearner.core.owl.OWLObjectUnionOfImplExt; +import org.dllearner.core.owl.ObjectPropertyHierarchy; +import org.dllearner.refinementoperators.CustomHierarchyRefinementOperator; +import org.dllearner.refinementoperators.CustomStartRefinementOperator; +import org.dllearner.refinementoperators.RefinementOperator; +import org.dllearner.refinementoperators.RhoDRDown; +import org.dllearner.utilities.owl.EvaluatedDescriptionComparator; +import org.dllearner.utilities.owl.OWLAPIRenderers; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.springframework.beans.factory.annotation.Autowired; + +import java.lang.invoke.MethodHandles; +import java.text.DecimalFormat; +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.Collectors; + +/** + * Abstract class for all ParCEL algorithms family + * + * @author An C. Tran + * + */ +public abstract class ParCELAbstract extends AbstractCELA implements ParCELearnerMBean { + + protected static final Logger logger = Logger.getLogger(MethodHandles.lookup().lookupClass()); + + // ---------------------------------- + // configuration options + // ---------------------------------- + @ConfigOption(defaultValue = "4", description = "Number of workers will be created to serve the learner") + protected int numberOfWorkers = 4; // + + @ConfigOption(defaultValue = "0.0", description = "The percentage of noise within the examples") + protected double noisePercentage = 0.0; + protected double noiseAllowed; // = this.noisePercentage/100d; + + @ConfigOption(defaultValue = "10", description = "Max number of splits will be applied for data properties with double range. This parameter is not used if a Splitter is provided") + protected int maxNoOfSplits = 10; + + @ConfigOption(defaultValue = "0", description = "Minimal coverage that a partial definition must approach so that it can be used") + protected double minimalCoverage = 0; //0 means no constrain on this condition + + @ConfigOption(defaultValue = "false", description = "Use value restriction or not") + protected boolean useHasValue = false; + + @ConfigOption(defaultValue = "true", description = "Use negation or not") + protected boolean useNegation = true; + + @ConfigOption(defaultValue = "false", description = "Use data restriction or not") + protected boolean useHasData = false; + + @ConfigOption(defaultValue = "true", description = "Use cardinality restrictions or not") + protected boolean useCardinalityRestrictions = true; + + @ConfigOption(defaultValue = "5", description = "Cardinality limit") + protected int cardinalityLimit = 5; + + @ConfigOption(defaultValue = "owl:Thing", + description = "You can specify a start class for the algorithm. To do this, you have to use Manchester OWL syntax either with full IRIs or prefixed IRIs.", + exampleValue = "ex:Male or http://example.org/ontology/Female") + protected OWLClassExpression startClass; // description of the root node + + protected ParCELDoubleSplitterAbstract splitter = null; + + + protected int maxHorizExp = 0; + + + //------------------------------------------- + //common variables for the learner + //------------------------------------------- + + /** + * Hold all generated description to avoid the duplicated descriptions (this may contains only + * the weak description but it may take time to check both in this data structure and the search + * tree to check for the duplication). Redundancy in this case may help increasing performance. + */ + protected ConcurrentSkipListSet allDescriptions = null; + + + /** + * The search tree holds all evaluated descriptions that are not correct and not weak ==> + * candidate for partial definitions. Nodes in the search tree must be sorted so that it can + * help the searching more efficiently (best search rather than 'blind' breath first or depth + * first)
+ * NOTE: node = (description + accuracy/correctness/completeness/... values) + */ + protected ConcurrentSkipListSet searchTree = null; + + + /** + * partial definitions (they should be sorted so that we can get the best + * partial definition at any time) + */ + protected SortedSet partialDefinitions = null; + + + + /** + * Heuristic used in the searching expansion (choosing node for expansion) + */ + protected ParCELHeuristic heuristic = null; + + + /** + * Reducer which will be used to reduce the partial definitions + */ + protected ParCELReducer reducer = null; + + + /** + * Pool of workers + */ + protected ThreadPoolExecutor workerPool; + + // configuration for worker pool + protected int minNumberOfWorker = 2; + protected int maxNumberOfWorker = 4; // max number of workers will be created + protected final int maxTaskQueueLength = 2000; + protected final long keepAliveTime = 100; // ms + + //examples + protected Set positiveExamples; + protected Set negativeExamples; + protected Set positiveTestExamples; + protected Set negativeTestExamples; + + /** + * Refinement operator pool which provides refinement operators + */ + protected ParCELRefinementOperatorPool refinementOperatorPool; + + @ConfigOption(description = "The refinement operator to use (currently only rho is supported)") + protected RefinementOperator operator; + + /** + * contains tasks submitted to thread pool + */ + protected BlockingQueue taskQueue; + + + // just for pretty representation of description + protected String baseURI; + protected Map prefix; + + protected final DecimalFormat df = new DecimalFormat(); + + /** + * This may be considered as the noise allowed in learning, i.e. the maximum number of positive + * examples can be discard (uncovered) + */ + protected int uncoveredPositiveExampleAllowed = 0; + + /** + * Holds the uncovered positive example, this will be updated when the worker found a partial + * definition since the callback method "definitionFound" is synchronized", there is no need to + * create a thread-safe for this set + */ + protected Set uncoveredPositiveExamples; + + // --------------------------------------------------------- + // flags to indicate the status of the application + // --------------------------------------------------------- + /** + * The learner is stopped (reasons: done, timeout, out of memory, etc.) + */ + protected volatile boolean stop = false; + + /** + * All positive examples are covered + */ + protected volatile boolean done = false; + + /** + * Learner get timeout + */ + protected volatile boolean timeout = false; + + // ------------------------------------------------ + // variables for statistical purpose + // ------------------------------------------------ + protected long miliStarttime = Long.MIN_VALUE; + protected long miliLearningTime = Long.MIN_VALUE; + + // some properties for statistical purpose + protected int currentMaxHorizExp = 0; + protected int bestDescriptionLength = 0; + protected double maxAccuracy = 0.0d; + + // will be used in MBean for debugging purpose + protected int noOfCompactedPartialDefinition; + protected int noOfUncoveredPositiveExamples; + + // number of task created (for debugging purpose only) + protected int noOfTask = 0; + + protected long trainingTime = 0; + + public ParCELAbstract() { + super(); + this.reducer = new ParCELImprovedCoverageGreedyReducer(); + } + + /** + * + * Constructor for the learning algorithm + * + * @param learningProblem + * Learning problem, must be a PDLLPosNegLP + * @param reasoningService + * Reasoner + */ + public ParCELAbstract(ParCELPosNegLP learningProblem, AbstractReasonerComponent reasoningService) { + super(learningProblem, reasoningService); + + // default compactor used by this algorithm + this.reducer = new ParCELImprovedCoverageGreedyReducer(); + //this.reducer = new ParCELPredScoreReducer(); + } + + private double getCurrentAccuracy() + { + double acc = (this.negativeExamples.size() + this.positiveExamples.size() - + this.uncoveredPositiveExamples.size())/ + (double) (this.positiveExamples.size() + this.negativeExamples.size()); + return acc; + } + + protected void initOperatorIfAny() { + if (operator == null) { + return; + } + + if (operator instanceof CustomHierarchyRefinementOperator) { + ClassHierarchy classHierarchy = initClassHierarchy(); + ObjectPropertyHierarchy objectPropertyHierarchy = initObjectPropertyHierarchy(); + DatatypePropertyHierarchy datatypePropertyHierarchy = initDataPropertyHierarchy(); + + ((CustomHierarchyRefinementOperator) operator).setClassHierarchy(classHierarchy); + ((CustomHierarchyRefinementOperator) operator).setObjectPropertyHierarchy(objectPropertyHierarchy); + ((CustomHierarchyRefinementOperator) operator).setDataPropertyHierarchy(datatypePropertyHierarchy); + } + + if (operator instanceof RhoDRDown) { + ((RhoDRDown) operator).setUseDisjunction(false); + } + } + + protected void initSearchTree() { + // create a start node in the search tree + // currently, start class is always Thing (initialised in the init() method) + allDescriptions.add(startClass); + + double accuracy = this.positiveExamples.size() / (double) (this.positiveExamples.size() + this.negativeExamples.size()); + ParCELNode startNode = new ParCELNode(null, startClass, accuracy, 0, 1.0); + searchTree.add(startNode); + } + + /** + * ============================================================================================ + * Callback method for worker when partial definitions found (callback for an evaluation request + * from reducer)
+ * If a definition (partial) found, do the following tasks:
+ * 1. Add the definition into the partial definition set
+ * 2. Update: uncovered positive examples, max accuracy, best description length
+ * 3. Check for the completeness of the learning. If yes, stop the learning
+ * + * @param definitions + * New partial definitions + */ + public void newPartialDefinitionsFound(Set definitions) { + + for (ParCELExtraNode def : definitions) { + // NOTE: in the previous version, this node will be added back into the search tree + // it is not necessary since in DLLearn, a definition may be revised to get a better one + // but + // in this approach, we do not refine partial definition. + + // remove uncovered positive examples by the positive examples covered by the new + // partial definition + int uncoveredPositiveExamplesRemoved; + int uncoveredPositiveExamplesSize; + + //re-calculate the generation time of pdef + def.setGenerationTime(def.getGenerationTime() - miliStarttime); + + synchronized (uncoveredPositiveExamples) { + uncoveredPositiveExamplesRemoved = this.uncoveredPositiveExamples.size(); + this.uncoveredPositiveExamples.removeAll(def.getCoveredPositiveExamples()); + uncoveredPositiveExamplesSize = this.uncoveredPositiveExamples.size(); + } //end of uncovere dPositive examples synchronise + + uncoveredPositiveExamplesRemoved -= uncoveredPositiveExamplesSize; + + if (uncoveredPositiveExamplesRemoved > 0) { + + // set the generation time for the new partial definition + //def.setGenerationTime(System.currentTimeMillis() - miliStarttime); //this is set by workers + synchronized (partialDefinitions) { + partialDefinitions.add(def); + } + + // for used in bean (for tracing purpose) + this.noOfUncoveredPositiveExamples -= uncoveredPositiveExamplesRemoved; + + ((ParCELPosNegLP) this.learningProblem) + .setUncoveredPositiveExamples(uncoveredPositiveExamples); + + if (logger.isTraceEnabled() || logger.isDebugEnabled()) { + logger.trace("PARTIAL definition found: " + + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered positive examples (" + + def.getCoveredPositiveExamples().size() + "): " + + def.getCoveredPositiveExamples() + + "\n\t - uncovered positive examples left: " + + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + } else if (logger.isInfoEnabled()) { + logger.info("PARTIAL definition found, uncovered positive examples left: " + + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + double acc = this.getCurrentAccuracy(); + double actualTrainingTime = getCurrentCpuMillis() / 1000.0; + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double testAcc = computeTestAccuracy(bestDescription); + + logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); + + recordBestConceptTimeAndAccuracy(actualTrainingTime, acc, testAcc); + } + + } + + // update the max accuracy and max description length + if (def.getAccuracy() > this.maxAccuracy) { + this.maxAccuracy = def.getAccuracy(); + this.bestDescriptionLength = OWLClassExpressionUtils.getLength(def.getDescription()); + } + + // check if the complete definition found + if (uncoveredPositiveExamplesSize <= uncoveredPositiveExampleAllowed) { + this.done = true; + // stop(); + } + } + } + + @Override + protected double computeTestAccuracy(OWLClassExpression description) { + if (learningProblem instanceof ParCELPosNegLP) { + return ((ParCELPosNegLP) learningProblem).getTestAccuracy(description); + } + + return 0.0; + } + + protected void createRefinementOperatorPool() throws ComponentInitException { + if (operator == null || !(operator instanceof RhoDRDown)) { + // ----------------------------------------- + // prepare for refinement operator creation + // ----------------------------------------- + Set usedConcepts = new TreeSet<>(reasoner.getClasses()); + + // remove the ignored concepts out of the list of concepts will be used by refinement + // operator + if (this.ignoredConcepts != null) { + usedConcepts.removeAll(ignoredConcepts); + } //set ignored concept is applicable + + ClassHierarchy classHierarchy = (ClassHierarchy) reasoner.getClassHierarchy().cloneAndRestrict(usedConcepts); + + // create a splitter and refinement operator pool + // there are two options: i) using object pool, ii) using set of objects (removed from + // this revision) + if (this.splitter != null) { + splitter.setReasoner(reasoner); + splitter.setPositiveExamples(positiveExamples); + splitter.setNegativeExamples(negativeExamples); + splitter.init(); + + Map> splits = splitter.computeSplits(); + + // i) option 1: create an object pool + refinementOperatorPool = new ParCELRefinementOperatorPool(reasoner, classHierarchy, + startClass, splits, numberOfWorkers + 1); + } + else { // no splitter provided create an object pool + refinementOperatorPool = new ParCELRefinementOperatorPool(reasoner, classHierarchy, + startClass, numberOfWorkers + 1, maxNoOfSplits); + } + + refinementOperatorPool.getFactory().setUseDisjunction(false); + refinementOperatorPool.getFactory().setUseNegation(useNegation); + refinementOperatorPool.getFactory().setUseHasValue(useHasValue); + refinementOperatorPool.getFactory().setUseHasData(useHasData); + refinementOperatorPool.getFactory().setCardinalityLimit(cardinalityLimit); + refinementOperatorPool.getFactory().setUseCardinalityRestrictions(useCardinalityRestrictions); + } else { + ParCELRefinementOperatorFactory opFactory; + + // create a splitter and refinement operator pool + // there are two options: i) using object pool, ii) using set of objects (removed from + // this revision) + if (this.splitter != null) { + splitter.setReasoner(reasoner); + splitter.setPositiveExamples(positiveExamples); + splitter.setNegativeExamples(negativeExamples); + splitter.init(); + + Map> splits = splitter.computeSplits(); + + opFactory = new ParCELRefinementOperatorFactory((RhoDRDown) operator, splits); + } else { // no splitter provided create an object pool + opFactory = new ParCELRefinementOperatorFactory((RhoDRDown) operator); + } + + refinementOperatorPool = new ParCELRefinementOperatorPool(opFactory); + refinementOperatorPool.setMaxIdle(numberOfWorkers + 1); + } + } + + protected void createWorkerPool() { + taskQueue = new LinkedBlockingQueue<>(maxTaskQueueLength); + + workerPool = new ThreadPoolExecutor(minNumberOfWorker, maxNumberOfWorker, keepAliveTime, + TimeUnit.MILLISECONDS, taskQueue, new ParCELWorkerThreadFactory()); + + if (logger.isInfoEnabled()) + logger.info("Worker pool created, core pool size: " + workerPool.getCorePoolSize() + + ", max pool size: " + workerPool.getMaximumPoolSize()); + } + + /** + * Get the union of all the best (reduced) partial definitions + * + * @return An union of all reduced partial definitions + */ + public OWLClassExpression getUnionCurrentlyBestDescription() { + List compactedDescriptions = getReducedPartialDefinition().stream() + .map(OENode::getDescription) + .collect(Collectors.toList()); + + return new OWLObjectUnionOfImplExt(compactedDescriptions); + } + + + /** + * Get the union of all the best (reduced) partial definitions using a given reducer + * + * @return An union of all reduced partial definitions + */ + public OWLClassExpression getUnionCurrentlyBestDescription(ParCELReducer reducer) { + List compactedDescriptions = getReducedPartialDefinition(reducer).stream() + .map(OENode::getDescription) + .collect(Collectors.toList()); + + return new OWLObjectUnionOfImplExt(compactedDescriptions); + } + + + /** + * Get the max overall completeness so far + * + * @return max overall completeness + */ + public abstract double getCurrentlyOveralMaxCompleteness(); + + + /** + * Get the set of reduced partial definitions using default reducer + * + * @return set of reduced partial definitions + */ + public abstract SortedSet getReducedPartialDefinition(); + + + /** + * Get the number of reduced partial definitions + * + * @return number of reduced partial definitions + */ + public int getNoOfReducedPartialDefinition() { + return noOfCompactedPartialDefinition; + } + + + /** + * Get the reduced partial definitions using the given reducer + * + * @param reducer Reducer which will be used to reduce the partial definitions + * + * @return reduced partial definitions + */ + public abstract SortedSet getReducedPartialDefinition(ParCELReducer reducer); + + + //=========================================== + // call-back methods for workers + //=========================================== + /** + * Update the max horizontal expansion + * + * @param newHozExp New horizontal expansion + */ + public synchronized void updateMaxHorizontalExpansion(int newHozExp) { + if (maxHorizExp < newHozExp) { + maxHorizExp = newHozExp; + } + } + + public int getMaximumHorizontalExpansion() { + return maxHorizExp; + } + + + /** + * ============================================================================================ + * Callback method for worker when the evaluated node is not a partial definition and weak node + * either
+ * + * NOTE: there is not need for using synchronisation for this method since the thread safe data + * structure is currently using + * + * @param newNodes + * New nodes to add to the search tree + */ + public void newRefinementDescriptions(Set newNodes) { + searchTree.addAll(newNodes); + } + + + /* + * + * Get the learning time in milisecond. Learning time does not include the reduction time + */ + public long getLearningTime() { + return miliLearningTime; + } + + /** + * Get total number of partial definitions found so far + * + * @return Number of partial definitions + */ + public long getNumberOfPartialDefinitions() { + return this.partialDefinitions.size(); + } + + /** + * Add a description into search tree. No synchronization is needed since safe-thread is using + * + * @param des + * Description to be added + * + * @return True is the description can be added (has not been in the search tree/all + * descriptions set + */ + public boolean addDescription(OWLClassExpression des) { + return this.allDescriptions.add(des); + } + + // ------------------------------------------------------- + // setters and getters for learner configuration options + // ------------------------------------------------------- + + //number of workers + public void setNumberOfWorkers(int numberOfWorkers) { + this.numberOfWorkers = numberOfWorkers; + } + + public int getNumberOfWorkers() { + return numberOfWorkers; + } + + //time out (max execution time) + public void setMaxExecutionTimeInSeconds(int maxExecutionTime) { + this.maxExecutionTimeInSeconds = maxExecutionTime; + } + + public long getMaxExecutionTimeInSeconds() { + return maxExecutionTimeInSeconds; + } + + //noise allowed + public void setNoisePercentage(double noise) { + this.noisePercentage = noise; + } + + public double getNoisePercentage() { + return this.noisePercentage; + } + + //max no of splits + public int getMaxNoOfSplits() { + return maxNoOfSplits; + } + + public void setMaxNoOfSplits(int maxNoOfSplits) { + this.maxNoOfSplits = maxNoOfSplits; + } + + //ignored concepts + public Set getIgnoredConcepts() { + return ignoredConcepts; + } + + public void setIgnoredConcepts(Set ignoredConcepts) { + this.ignoredConcepts = ignoredConcepts; + } + + //minimal covered of the partial definitions + public double getMinimalCoverage() { + return minimalCoverage; + } + + public void setMinimalCoverage(double minimalCoverage) { + this.minimalCoverage = minimalCoverage; + } + + public ParCELReducer getReducer() { + return this.reducer; + } + + public String getBaseURI() { + return reasoner.getBaseURI(); + } + + public Map getPrefix() { + return reasoner.getPrefixes(); + } + + public long getTotalNumberOfDescriptionsGenerated() { + return this.allDescriptions.size(); + } + + public boolean getUseHasValue() { + return this.useHasValue; + } + + public void setUseHasValue(boolean useHasValue) { + this.useHasValue = useHasValue; + } + + public boolean getUseHasData() { + return this.useHasData; + } + + public void setUseNegation(boolean useNegation) { + this.useNegation = useNegation; + } + + public boolean getUseNegation() { + return this.useNegation; + } + + public void setUseHasData(boolean useHasData) { + this.useHasData = useHasData; + } + + public void setUseCardinalityRestrictions(boolean useCardinalityRestrictions) { + this.useCardinalityRestrictions = useCardinalityRestrictions; + } + + public boolean getUseCardinalityRestrictions() { + return this.useCardinalityRestrictions; + } + + public void setCardinalityLimit(int cardinalityLimit) { + this.cardinalityLimit = cardinalityLimit; + } + + public int getCardinalityLimit() { + return this.cardinalityLimit; + } + + public void setOperator(RefinementOperator refinementOp) { + this.operator = refinementOp; + } + + public RefinementOperator getOperator() { + return this.operator; + } + + public void setSplitter(ParCELDoubleSplitterAbstract splitter) { + this.splitter = splitter; + } + + public void setStartClass(OWLClassExpression startClass) { + this.startClass = startClass; + } + + @Override + public int getWorkerPoolSize() { + return this.workerPool.getQueue().size(); + } + + /** + * ============================================================================================ + * Stop the learning algorithm: Stop the workers and set the "stop" flag to true + */ + @Override + public void stop() { + + if (!stop) { + stop = true; + workerPool.shutdownNow(); + + //wait until all workers are terminated + try { + //System.out.println("-------------Waiting for worker pool----------------"); + workerPool.awaitTermination(10, TimeUnit.SECONDS); + } + catch (InterruptedException ie) { + logger.error(ie); + } + } + } + + /**=========================================================================================================
+ * Set heuristic will be used + * + * @param newHeuristic + */ + public void setHeuristic(ParCELHeuristic newHeuristic) { + this.heuristic = newHeuristic; + + if (logger.isInfoEnabled()) + logger.info("Changing heuristic to " + newHeuristic.getClass().getName()); + } + + public boolean isTimeout() { + timeout = (this.maxExecutionTimeInSeconds > 0 && (getCurrentCpuMillis()) > this.maxExecutionTimeInSeconds * 1000); + return timeout; + } + + public boolean isDone() { + return done; + } + + @Override + public boolean isRunning() { + return !stop && !done && !timeout; + } + + /** + * ============================================================================================ + * Check if the learner can be terminated + * + * @return True if termination condition is true (manual stop inquiry, complete definition + * found, or timeout), false otherwise + */ + protected boolean isTerminateCriteriaSatisfied() { + return stop || done || isTimeout(); + // (Runtime.getRuntime().totalMemory() >= this.maxHeapSize + // && Runtime.getRuntime().freeMemory() < this.outOfMemory); + } + + /** + * Check whether the learner is terminated by the partial definitions + * + * @return True if the learner is terminated by the partial definitions, false otherwise + */ + public boolean terminatedByPartialDefinitions() { + return this.done; + } + + protected double getNoiseAllowed() { + return noiseAllowed; + } + + /** + * ============================================================================================ + * Get the currently best description in the set of partial definition + */ + @Override + public OWLClassExpression getCurrentlyBestDescription() { + if (!partialDefinitions.isEmpty()) { + return partialDefinitions.iterator().next().getDescription(); + } else + return null; + } + + /** + * ============================================================================================ + * Get all partial definition without any associated information such as accuracy, correctness, + * etc. + */ + @Override + public List getCurrentlyBestDescriptions() { + return PLOENodesToDescriptions(partialDefinitions); + } + + /** + * ============================================================================================ + * Convert a set of PLOENode into a list of descriptions + * + * @param nodes + * Set of PLOENode need to be converted + * + * @return Set of descriptions corresponding to the given set of PLOENode + */ + private List PLOENodesToDescriptions(Set nodes) { + List result = new LinkedList<>(); + for (ParCELExtraNode node : nodes) + result.add(node.getDescription()); + return result; + } + + /** + * ============================================================================================ + * The same as getCurrentBestDescription. An evaluated description is a description with its + * evaluated properties including accuracy and correctness + */ + @Override + public EvaluatedDescription getCurrentlyBestEvaluatedDescription() { + if (!partialDefinitions.isEmpty()) { + ParCELNode firstNode = partialDefinitions.first(); + return new EvaluatedDescription<>(firstNode.getDescription(), new ParCELScore(firstNode)); + } else + return null; + } + + /** + * ============================================================================================ + * Get all partial definitions found so far + */ + @Override + public NavigableSet> getCurrentlyBestEvaluatedDescriptions() { + return extraPLOENodesToEvaluatedDescriptions(partialDefinitions); + } + + /** + * ============================================================================================ + * Method for PLOENode - EvaluatedDescription conversion + * + * @param partialDefs + * Set of ExtraPLOENode nodes which will be converted into EvaluatedDescription + * + * @return Set of corresponding EvaluatedDescription + */ + private NavigableSet> extraPLOENodesToEvaluatedDescriptions( + Set partialDefs) { + TreeSet> result = new TreeSet<>( + new EvaluatedDescriptionComparator()); + for (ParCELExtraNode node : partialDefs) { + result.add(new EvaluatedDescription<>(node.getDescription(), new ParCELScore(node))); + } + return result; + } + /** + * Get all unreduced partial definitions + * + * @return unreduced partial definitions + */ + public Set getPartialDefinitions() { + return partialDefinitions; + } + + + public Collection getSearchTree() { + return searchTree; + } + + public ParCELHeuristic getHeuristic() { + return heuristic; + } + + public int getSearchTreeSize() { + return (searchTree != null ? searchTree.size() : -1); + } + + public long getMiliStarttime() { + return this.miliStarttime; + } + + public long getMiliLearningTime() { + return miliLearningTime; + } + + public double getMaxAccuracy() { + return maxAccuracy; + } + + public int getCurrentlyBestDescriptionLength() { + return bestDescriptionLength; + } + + + @Override + public long getTotalDescriptions() { + return allDescriptions.size(); + } + + @Override + public double getCurrentlyBestAccuracy() { + return ((positiveExamples.size() - uncoveredPositiveExamples.size()) + negativeExamples.size()) / + (double)(positiveExamples.size() + negativeExamples.size()); + } + + @Override + public int getCurrentlyMaxExpansion() { + return this.currentMaxHorizExp; + } + + protected void printSearchTree(ParCELExtraNode node) { + List processingNodes = new LinkedList<>(); + + processingNodes.add(node); + + processingNodes.addAll(node.getCompositeNodes()); + + for (OENode n : processingNodes) { + OENode parent = n.getParent(); + while (parent != null) { + logger.debug(" <-- " + OWLAPIRenderers.toManchesterOWLSyntax(parent.getDescription())); + //" [acc:" + df.format(parent.getAccuracy()) + + //", correctness:" + df.format(parent.getCorrectness()) + ", completeness:" + df.format(parent.getCompleteness()) + + //", score:" + df.format(this.heuristic.getScore(parent)) + "]"); + + //print out the children nodes + Collection children = parent.getChildren(); + for (OENode child : children) { + OENode tmp = child; + logger.debug(" --> " + OWLAPIRenderers.toManchesterOWLSyntax(tmp.getDescription())); + //" [acc:" + df.format(tmp.getAccuracy()) + + //", correctness:" + df.format(tmp.getCorrectness()) + ", completeness:" + df.format(tmp.getCompleteness()) + + //", score:" + df.format(this.heuristic.getScore(tmp)) + "]"); + } + parent = parent.getParent(); + } //while parent is not null + + logger.debug("==============="); + + } + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java new file mode 100644 index 0000000000..870e2390ed --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java @@ -0,0 +1,37 @@ +package org.dllearner.algorithms.parcel; + +import java.util.Comparator; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; + +/** + * Use to compare 2 ParCELExtraNode nodes based on their completeness (coverage). The description + * length and ConceptComparator will be used it they have equal coverage + * + * @author An C. Tran + * + */ +public class ParCELCompletenessComparator implements Comparator { + + @Override + public int compare(ParCELNode node1, ParCELNode node2) { + + int v1 = node1.getCoveredPositiveExamples().size(); + int v2 = node2.getCoveredPositiveExamples().size(); + + if (v1 > v2) + return -1; + else if (v1 < v2) + return 1; + else { + int len1 = new OWLClassExpressionLengthCalculator().getLength(node1.getDescription()); + int len2 = new OWLClassExpressionLengthCalculator().getLength(node2.getDescription()); + if (len1 < len2) + return -1; + else if (len1 > len2) + return 1; + else + return node1.getDescription().compareTo(node2.getDescription()); + } + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCorrectnessComparator.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCorrectnessComparator.java new file mode 100644 index 0000000000..a822b29bd9 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCorrectnessComparator.java @@ -0,0 +1,36 @@ +package org.dllearner.algorithms.parcel; + +import java.util.Comparator; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; + +/** + * Used to compare 2 ParCELExtraNode nodes based on their correctness. The description length and + * ConceptComparator will be used it they have equal coverage + * + * @author An C. Tran + */ +public class ParCELCorrectnessComparator implements Comparator { + + @Override + public int compare(ParCELExtraNode node1, ParCELExtraNode node2) { + double correctness1 = node1.getCorrectness(); + double correctness2 = node2.getCorrectness(); + + if (correctness1 > correctness2) + return -1; // smaller will be on the top + else if (correctness1 < correctness2) + return 1; + else { + int len1 = new OWLClassExpressionLengthCalculator().getLength(node1.getDescription()); + int len2 = new OWLClassExpressionLengthCalculator().getLength(node2.getDescription()); + + if (len1 < len2) + return -1; + else if (len1 > len2) + return 1; + else + return node1.getDescription().compareTo(node2.getDescription()); + } + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java new file mode 100644 index 0000000000..23cd91df14 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java @@ -0,0 +1,37 @@ +package org.dllearner.algorithms.parcel; + +import java.util.Comparator; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; + +/** + * Use to compare 2 ParCELExtraNode nodes based on the number of covered negative examples. The + * description length and ConceptComparator will be used it they have equal coverage + * + * @author An C. Tran + * + */ +public class ParCELCoveredNegativeExampleComparator implements Comparator { + + @Override + public int compare(ParCELExtraNode node1, ParCELExtraNode node2) { + int coveredNeg1 = node1.getCoveredNegativeExamples().size(); + int coveredNeg2 = node2.getCoveredPositiveExamples().size(); + + if (coveredNeg1 > coveredNeg2) + return -1; // smaller will be on the top + else if (coveredNeg1 < coveredNeg2) + return 1; + else { + int len1 = new OWLClassExpressionLengthCalculator().getLength(node1.getDescription()); + int len2 = new OWLClassExpressionLengthCalculator().getLength(node2.getDescription()); + + if (len1 < len2) + return -1; + else if (len1 > len2) + return 1; + else + return node1.getDescription().compareTo(node2.getDescription()); + } + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java new file mode 100644 index 0000000000..ba81048be8 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java @@ -0,0 +1,137 @@ +package org.dllearner.algorithms.parcel; + + +/** + * Implements the heuristic used to expand the search tree. Dimensions used:
+ * + correctness: main value
+ * + horizontal expansion: penalty
+ * + accuracy gained from the parent node: bonus
+ * + refinement nodes: penalty
+ * + concept type + name (org.dllearner.utilities.owl.ConceptComparator) + * + * @author An C. Tran + */ +public class ParCELDefaultHeuristic implements ParCELHeuristic { + + //correct + protected double correctnessFactor = 1.0; + + // penalty for long descriptions + protected double expansionPenaltyFactor = 0.05; //0.01, 0.05 + + // bonus for gained accuracy + protected double gainBonusFactor = 0.2; //0.2; //0.1, 0.2 + + // penalty if a node description has very many refinements since exploring + // such a node is computationally very expensive + protected double nodeRefinementPenalty = 0.0001; + + // award for node with high accuracy + protected double accuracyAwardFactor = 0.5; //0.01 + + + /** + * Compare two node + * + * @param node1 Node to compare + * @param node2 Node to compare + * @return 1 if node1 "greater" than node2 and vice versa + */ + @Override + public int compare(ParCELNode node1, ParCELNode node2) { + double diff = getNodeScore(node1) - getNodeScore(node2); + + if (diff > 0) { // node1 has better score than node2 + return 1; + } else if (diff < 0) { + return -1; + } else { + // syntactic comparison as final comparison criterion + int comp = node1.getDescription().compareTo(node2.getDescription()); +// return comp; + + // this allows duplicate descriptions exists in the set (with dif. horz. value) + if (comp != 0) + return comp; + else + return -1; + } + } + + /** + * Calculate score for a node which is used as the searching heuristic + * + * @param node Node to be scored + * @return Score of the node + */ + protected double getNodeScore(ParCELNode node) { + + // the scoring mainly bases on correctness + double score = node.getCorrectness();// * correctnessFactor; + + // bonus for the accuracy gained + if (!node.isRoot()) { + double parentAccuracy = ((ParCELNode) (node.getParent())).getAccuracy(); + score += (parentAccuracy - node.getAccuracy()) * gainBonusFactor; + } + + // award node with high accuracy + score += node.getAccuracy() * accuracyAwardFactor; + + // penalty for horizontal expansion + score -= node.getHorizontalExpansion() * expansionPenaltyFactor; + //score -= node.getDescription().getLength() * expansionPenaltyFactor; + + score -= node.getRefinementCount() * nodeRefinementPenalty; + + return score; + } + + @Override + public double getScore(ParCELNode node) { + return this.getNodeScore(node); + } + + public double getCorrectnessFactor() { + return correctnessFactor; + } + + public void setCorrectnessFactor(double correctnessFactor) { + this.correctnessFactor = correctnessFactor; + } + + public double getExpansionPenaltyFactor() { + return expansionPenaltyFactor; + } + + public void setExpansionPenaltyFactor(double expansionPenaltyFactor) { + this.expansionPenaltyFactor = expansionPenaltyFactor; + //System.out.println("ExpansionPenaltyFactor changed: " + expansionPenaltyFactor); + } + + public double getGainBonusFactor() { + return gainBonusFactor; + } + + public void setGainBonusFactor(double gainBonusFactor) { + this.gainBonusFactor = gainBonusFactor; + } + + public double getNodeRefinementPenalty() { + return nodeRefinementPenalty; + } + + public void setNodeRefinementPenalty(double nodeRefinementPenalty) { + this.nodeRefinementPenalty = nodeRefinementPenalty; + } + + public double getAccuracyAwardFactor() { + return accuracyAwardFactor; + } + + public void setAccuracyAwardFactor(double accuracyAwardFactor) { + this.accuracyAwardFactor = accuracyAwardFactor; + } + + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionGenerationTimeComparator.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionGenerationTimeComparator.java new file mode 100644 index 0000000000..fc812d6a7c --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionGenerationTimeComparator.java @@ -0,0 +1,40 @@ +package org.dllearner.algorithms.parcel; + +/** + * Compare two node based on their generation time. + * This will be used in the Generation Time Greedy Compactness strategy + * GOLR + * + * @author An C. Tran + */ + +import java.util.Comparator; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; + +public class ParCELDefinitionGenerationTimeComparator implements + Comparator { + + @Override + public int compare(ParCELExtraNode node1, ParCELExtraNode node2) { + double genTime1 = node1.getGenerationTime(); + double genTime2 = node2.getGenerationTime(); + + if (genTime1 < genTime2) + return -1; + else if (genTime1 > genTime2) + return 1; + else { + if (OWLClassExpressionUtils.getLength(node1.getDescription()) < + OWLClassExpressionUtils.getLength(node2.getDescription())) + return -1; + else if (OWLClassExpressionUtils.getLength(node1.getDescription()) > + OWLClassExpressionUtils.getLength(node2.getDescription())) + return 1; + else + return node1.getDescription().compareTo(node2.getDescription()); + } + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionLengthComparator.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionLengthComparator.java new file mode 100644 index 0000000000..8c1339c61f --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefinitionLengthComparator.java @@ -0,0 +1,35 @@ +package org.dllearner.algorithms.parcel; + +import java.util.Comparator; + +import com.google.common.collect.ComparisonChain; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; + +/** + * Compare two node based on their definition length. This will be used in the Definition Length + * Greedy Compactness strategy + * + * @author An C. Tran + * + */ + +public class ParCELDefinitionLengthComparator implements Comparator { + + @Override + public int compare(ParCELExtraNode node1, ParCELExtraNode node2) { + ComparisonChain.start().compare(OWLClassExpressionUtils.getLength(node1.getDescription()), + OWLClassExpressionUtils.getLength(node2.getDescription())) + .compare(node1.getDescription(), node2.getDescription()) + .result(); + int len1 = new OWLClassExpressionLengthCalculator().getLength(node1.getDescription()); + int len2 = new OWLClassExpressionLengthCalculator().getLength(node2.getDescription()); + if (len1 < len2) + return -1; + else if (len1 > len2) + return 1; + else + return node1.getDescription().compareTo(node2.getDescription()); + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELEvaluationResult.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELEvaluationResult.java new file mode 100644 index 0000000000..902263e405 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELEvaluationResult.java @@ -0,0 +1,146 @@ +package org.dllearner.algorithms.parcel; + +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * This class represents the result of an evaluation result return from the ParCEL learning problem + * (ParCELPosNegLP)
+ * Information included in a ParCEL evaluation includes: + *
    + *
  1. - accuracy: double
  2. + *
  3. - correctness: double
  4. + *
  5. - completeness: double
  6. + *
  7. - covered positive examples: Set<Individual>
  8. + *
  9. - covered negative examples: Set<Individual>
  10. + *
+ * + * @author An C. Tran + * + */ +public class ParCELEvaluationResult { + + protected double accuracy = 0.0; + protected double correctness = 0.0; + protected double completeness = 0.0; + protected Set coveredPositiveExamples = null; + protected Set coveredNegativeExamples = null; + + /** + * Default constructor, use default value for all properties + */ + + public ParCELEvaluationResult() { + + } + + + /** + * This use to create an evaluation result that is not for a correct definition. So, we don't + * need to hold the set of covered positive examples + * + * @param accuracy + * @param correctness + */ + public ParCELEvaluationResult(double accuracy, double correctness, double completeness) { + this.accuracy = accuracy; + this.correctness = correctness; + this.completeness = completeness; + } + + /** + * Used to create an evaluation result for a correct definition.
+ * Covered positive examples have to be kept to be used in the result compactness later on.
+ * This is usually used in case of partial definition + * + * @param accuracy + * @param correctness + * @param completeness + * @param coveredPositiveExamples + */ + public ParCELEvaluationResult(double accuracy, double correctness, double completeness, + Set coveredPositiveExamples) { + this.accuracy = accuracy; + this.correctness = correctness; + this.completeness = completeness; + this.coveredPositiveExamples = coveredPositiveExamples; + } + + /** + * Used to create an evaluation result for a correct definition.
+ * Both covered positive examples and covered negative examples will be kept to be used in the + * result compactness later on. + * + * @param accuracy + * @param correctness + * @param completeness + * @param coveredPositiveExamples + * @param coveredNegativeExamples + */ + public ParCELEvaluationResult(double accuracy, double correctness, double completeness, + Set coveredPositiveExamples, Set coveredNegativeExamples) { + + this.accuracy = accuracy; + this.correctness = correctness; + this.completeness = completeness; + this.coveredPositiveExamples = coveredPositiveExamples; + this.coveredNegativeExamples = coveredNegativeExamples; + } + + // --------------------------------------- + // Getters and setters + // --------------------------------------- + public double getAccuracy() { + return accuracy; + } + + public void setAccuracy(double accuracy) { + this.accuracy = accuracy; + } + + public double getCorrectness() { + return correctness; + } + + public void setCorrectness(double correctness) { + this.correctness = correctness; + } + + public double getCompleteness() { + return completeness; + } + + public void setCompleteness(double completeness) { + this.completeness = completeness; + } + + public Set getCoveredPositiveExamples() { + return coveredPositiveExamples; + } + + public void setCoveredPositiveExamples(Set coveredPositiveExamples) { + this.coveredPositiveExamples = coveredPositiveExamples; + } + + public Set getCoveredNegativeExamples() { + return coveredNegativeExamples; + } + + public void setCoveredNegativeExamples(Set coveredNegativeExamples) { + this.coveredNegativeExamples = coveredNegativeExamples; + } + + @Override + public String toString() { + return "ParCELEvaluationResult{" + + "accuracy=" + accuracy + + ", correctness=" + correctness + + ", completeness=" + completeness + + ", coveredPositiveExamples=" + Optional.ofNullable(coveredPositiveExamples).map(Set::size).map(Object::toString).orElse("n/a") + + ", coveredNegativeExamples=" + Optional.ofNullable(coveredNegativeExamples).map(Set::size).map(Objects::toString).orElse("n/a") + + '}'; + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java new file mode 100644 index 0000000000..76758ccdb5 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java @@ -0,0 +1,167 @@ +package org.dllearner.algorithms.parcel; + +import java.util.HashSet; +import java.util.Set; + +import org.dllearner.algorithms.celoe.OENode; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Generation time and node type properties are added. This information is needed by some + * reduction algorithms + * + * @author An C. Tran + * + */ +public class ParCELExtraNode extends ParCELNode { + + protected double generationTime = Double.MIN_VALUE; // time in ms that the node was generated + protected double extraInfo = Double.MIN_VALUE; + protected int type = -1; + + /** + * Nodes in the search tree that constitute this node (in case this node a a combination of a + * description with counter partial definitions) to form a partial definition + */ + final Set compositeNodes = new HashSet<>(); + + + /** + * Constructor + * + * @param parentNode + * @param description + * @param accuracy + */ + /* + public ParCELExtraNode(OENode parentNode, Description description, double accuracy) { + super(parentNode, description, accuracy); + } + */ + + /** + * Constructor + * + * @param parentNode + * @param description + * @param accuracy + * @param correctness + */ + /* + public ParCELExtraNode(OENode parentNode, Description description, double accuracy, + double correctness) { + super(parentNode, description, accuracy, correctness); + } + */ + + + /** + * Create a ParCELExtraNode from an OENode + * @param node + */ + public ParCELExtraNode(ParCELNode node) { + super(node.getParent(), node.getDescription(), node.getAccuracy(), node.getCorrectness(), node.getCompleteness()); + setCoveredPositiveExamples(node.getCoveredPositiveExamples()); + setCoveredNegativeExamples(node.getCoveredNegativeExamples()); + } + + /** + * Create a node with a set of positive examples covered by the description of the node + * + * @param node + * @param cp + */ + public ParCELExtraNode(ParCELNode node, Set cp) { + super(node.getParent(), node.getDescription(), node.getAccuracy(), node.getCorrectness(), node.getCompleteness()); + super.coveredPositiveExamples = cp; + } + + /** + * Constructor with the correctness and the generation time of the description + * + * @param parentNode + * @param description + * @param accuracy + * @param correctness + */ + /* + public ParCELExtraNode(ParCELNode parentNode, Description description, double accuracy, + double correctness) { + super(parentNode, description, accuracy, correctness); + this.coveredPositiveExamples = null; + } + + */ + /** + * Constructor with the set of positive examples covered by the description of the node + * + * @param parentNode + * @param description + * @param accuracy + * @param correctness + * @param cp Covered positive examples + */ + public ParCELExtraNode(ParCELNode parentNode, OWLClassExpression description, double accuracy, + double correctness, double completeness, Set cp) + { + super(parentNode, description, accuracy, correctness, completeness); + super.setCoveredPositiveExamples(cp); + } + + + /** + * Constructor with the set of positive examples covered by the description of the node + * + * @param parentNode + * @param description + * @param accuracy + * @param correctness + * @param cn Covered positive examples + */ + public ParCELExtraNode(ParCELNode parentNode, OWLClassExpression description, double accuracy, + double correctness, double completeness, Set cp, Set cn) + { + super(parentNode, description, accuracy, correctness, completeness); + super.setCoveredPositiveExamples(cp); + super.setCoveredNegativeExamples(cn); + } + + + // ------------------------- + // getters and setters + // ------------------------- + + public double getGenerationTime() { + return generationTime; + } + + public void setGenerationTime(double d) { + this.generationTime = d; + } + + public double getExtraInfo() { + return extraInfo; + } + + public void setExtraInfo(double d) { + this.extraInfo = d; + } + + + public void setType(int t) { + this.type = t; + } + + public int getType() { + return this.type; + } + + public void setCompositeList(Set compositeNodes) { + this.compositeNodes.addAll(compositeNodes); + } + + public Set getCompositeNodes() { + return this.compositeNodes; + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELHeuristic.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELHeuristic.java new file mode 100644 index 0000000000..ace47b3ae7 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELHeuristic.java @@ -0,0 +1,16 @@ +package org.dllearner.algorithms.parcel; + +import java.util.Comparator; + +/** + * Interface for heuristics used in ParCEL + * + * @author An C. Tran + * + */ +public interface ParCELHeuristic extends Comparator { + + int compare(ParCELNode node1, ParCELNode node2); + + double getScore(ParCELNode node); +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java new file mode 100644 index 0000000000..e2a27fde0b --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java @@ -0,0 +1,105 @@ +package org.dllearner.algorithms.parcel; + +import java.text.DecimalFormat; +import java.util.HashSet; +import java.util.Set; + +import org.dllearner.algorithms.celoe.OENode; +import org.dllearner.utilities.owl.OWLAPIRenderers; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Represents a node in the search tree used in the ParCEL
+ * A node includes description and its corresponding properties such as: correctness, accuracy, + * distance between the description the leaning problem, its parent node, etc. + * + * @author An C. Tran + * + */ +public class ParCELNode extends OENode { + + private double correctness = -1.0; + private double completeness = -1.0; + + protected Set coveredPositiveExamples = new HashSet<>(); + protected final Set coveredNegativeExamples = new HashSet<>(); + + private final DecimalFormat dfPercent = new DecimalFormat("0.00%"); + + + public ParCELNode(OENode parentNode, OWLClassExpression description, double accuracy, + double correctness, double completeness) { + super(description, accuracy); + setParent(parentNode); + this.correctness = correctness; + this.completeness = completeness; + } + + + public ParCELNode(OENode parentNode, OWLClassExpression description, + Set coveredPositiveExamples, Set coveredNegativeExamples) { + super(description, 0); + setParent(parentNode); + this.coveredPositiveExamples.addAll(coveredPositiveExamples); + this.coveredNegativeExamples.addAll(coveredNegativeExamples); + } + + public void setCorrectness(double cor) { + this.correctness = cor; + } + + public double getCorrectness() { + return this.correctness; + } + + public void setCompleteness(double comp) { + this.completeness = comp; + } + + public double getCompleteness() { + return this.completeness; + } + + public void setAccuracy(double acc) { + this.accuracy = acc; + } + + public Set getCoveredPositiveExamples() { + return this.coveredPositiveExamples; + } + + public Set getCoveredNegativeExamples() { + return this.coveredNegativeExamples; + } + + public void setCoveredPositiveExamples(Set coveredPositiveExamples) { + if (coveredPositiveExamples != null) + this.coveredPositiveExamples.addAll(coveredPositiveExamples); + else + this.coveredPositiveExamples.clear(); + } + + public void setCoveredNegativeExamples(Set coveredNegativeExamples) { + if (coveredNegativeExamples != null) + this.coveredNegativeExamples.addAll(coveredNegativeExamples); + else + this.coveredNegativeExamples.clear(); + } + + @Override + public String toString() { + String ret = OWLAPIRenderers.toManchesterOWLSyntax(this.getDescription()); + ret += " [acc:" + dfPercent.format(this.getAccuracy()); + ret += ", cor:" + dfPercent.format(this.getCorrectness()); + ret += ", comp:" + dfPercent.format(this.completeness); + ret += ", horz:" + this.horizontalExpansion + "]"; + return ret; + + } + + public void setDescription(OWLClassExpression newDescription) { + this.description = newDescription; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELOntologyUtil.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELOntologyUtil.java new file mode 100644 index 0000000000..76774db1b6 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELOntologyUtil.java @@ -0,0 +1,83 @@ +package org.dllearner.algorithms.parcel; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.OWLOntologyStorageException; + +/** + * Implementation of some utility functions for ontology manipulation + * + * @author An C. Tran + * + */ + +public class ParCELOntologyUtil { + + /** + * Load ontology from file into memery given its path + * + * @param ontologyFilePath + * + * @return Opened ontology + * @throws OWLOntologyCreationException + */ + public static OWLOntology loadOntology(String ontologyFilePath) + throws OWLOntologyCreationException { + OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); + OWLOntology ontology; + + String flash = (System.getProperty("os.name").contains("Windows")) ? "/" : ""; + + File f = new File(ontologyFilePath); + + if (!ontologyFilePath.contains("file:")) + ontologyFilePath = "file:" + flash + f.getAbsolutePath(); + + ontologyFilePath = ontologyFilePath.replace('\\', '/'); + + ontology = manager.loadOntology(IRI.create(ontologyFilePath)); + + return ontology; + } + + /** + * Persist the ontology + * + * @param ontology Ontology which need to be persisted + * + * @throws OWLOntologyStorageException + */ + public static void persistOntology(OWLOntology ontology) throws OWLOntologyStorageException { + OWLOntologyManager manager = ontology.getOWLOntologyManager(); + manager.saveOntology(ontology); + } + + /** + * Save an ontology to another file + * + * @param ontology + * Ontology contains changes + * @param newFilePath + * Path to the new ontology file + * + * @throws OWLOntologyStorageException + * @throws IOException + */ + public static void persistOntology(OWLOntology ontology, String newFilePath) + throws OWLOntologyStorageException, IOException { + OWLOntologyManager manager = ontology.getOWLOntologyManager(); + + File f = new File(newFilePath); + FileOutputStream fo = new FileOutputStream(f); + + manager.saveOntology(ontology, fo); + fo.close(); + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java new file mode 100644 index 0000000000..429feea0f2 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -0,0 +1,640 @@ +package org.dllearner.algorithms.parcel; + +/** + * ParCEL Learning problem: provides correctness, completeness, and accuracy calculation. + * Predictive accuracy calculation is used. + * + * This learning problem uses a different scoring in comparison with DL-Learner PosNegLP + * + * @author An C. Tran + */ + +import java.util.Set; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.TreeSet; + +import org.dllearner.core.*; +import org.dllearner.core.config.ConfigOption; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; + +@ComponentAnn(name = "ParCELPosNegLP", shortName = "parcelPosNegLP", version = 0.1, description = "ParCEL Positive&Negative Learning Problem") +public class ParCELPosNegLP extends AbstractClassExpressionLearningProblem { + + protected Set positiveExamples; + protected Set negativeExamples; + + @ConfigOption(description = "list of positive testing examples") + protected Set positiveTestExamples; + @ConfigOption(description = "list of negative testing examples") + protected Set negativeTestExamples; + + //currently uncovered positive examples + protected Set uncoveredPositiveExamples; + + // private Logger logger = Logger.getLogger(this.getClass()); + + // reasoner component is declared in AbstractLearningProblem class + + /** + * Constructor, used in case that positive and negative examples are provided when this + * component is initialized + * + * @param reasoningService + * Reasoner, provides reasoning service. Used to checking the instance type + * @param positiveExamples + * Set of positive examples + * @param negativeExamples + * Set of negative examples + */ + public ParCELPosNegLP(AbstractReasonerComponent reasoningService, + Set positiveExamples, Set negativeExamples) { + super(reasoningService); + this.positiveExamples = positiveExamples; + this.negativeExamples = negativeExamples; + this.uncoveredPositiveExamples = this.positiveExamples; + } + + /** + * This constructor is used when the learning configuration file is used + * + * @param reasoningService + */ + public ParCELPosNegLP(AbstractReasonerComponent reasoningService) { + super(reasoningService); + } + + /** + * This constructor can be used by SpringDefinition to create bean object Properties of new bean + * may be initialised later using setters + */ + public ParCELPosNegLP() { + super(); + } + + /** + * Get list of positive examples covered by a description + * + * @param description + * Description + * + * @return Set of positive examples covered by the description + */ + protected Set coveredPositiveExamples(OWLClassExpression description) { + Set coveredPositiveExamples = new HashSet<>(); + + for (OWLIndividual example : positiveExamples) + if (reasoner.hasType(description, example)) + coveredPositiveExamples.add(example); + + return coveredPositiveExamples; + } + + /** + * Get list of uncovered positive examples covered by a description + * + * @param description + * Description + * + * @return Set of positive examples covered by the description + */ + protected Set coveredUncoveredPositiveExamples(OWLClassExpression description) { + Set coveredPositiveExamples = new HashSet<>(); + + for (OWLIndividual example : uncoveredPositiveExamples) + if (reasoner.hasType(description, example)) + coveredPositiveExamples.add(example); + + return coveredPositiveExamples; + } + + /** + * Get number of positive examples covered by a description + * + * @param description + * Description + * @return Number if positive examples covered by the description + */ + protected int getNumberCoveredPositiveExamples(OWLClassExpression description) { + return getNumberCoveredPositiveExamples(description, positiveExamples); + } + + protected int getNumberCoveredPositiveTestExamples(OWLClassExpression description) { + return getNumberCoveredPositiveExamples(description, positiveTestExamples); + } + + protected int getNumberCoveredPositiveExamples(OWLClassExpression description, Set allPosExamples) { + int coveredPos = 0; + + for (OWLIndividual example : allPosExamples) { + if (reasoner.hasType(description, example)) + coveredPos++; + } + + return coveredPos; + } + + /** + * Get number of negative examples covered by a description + * + * @param description + * Description to test + * + * @return Number of negative examples covered by the description + */ + protected int getNumberOfCoveredNegativeExamples(OWLClassExpression description) { + return getNumberOfCoveredNegativeExamples(description, negativeExamples); + } + + protected int getNumberOfCoveredNegativeTestExamples(OWLClassExpression description) { + return getNumberOfCoveredNegativeExamples(description, negativeTestExamples); + } + + protected int getNumberOfCoveredNegativeExamples(OWLClassExpression description, Set allNegExamples) { + int coveredNeg = 0; + + for (OWLIndividual example : allNegExamples) { + if (reasoner.hasType(description, example)) { + coveredNeg++; + } + } + + return coveredNeg; + } + + /** + * Calculate predictive accuracy of a description pred-accuracy(D) = + * (covered-positive-examples(D) + uncovered-negative-examples(D)) / all-examples + * + * @param description + * Description which will ve calculated the accuracy + * + * @return Predictive accuracy of a description + */ + protected double accuracy_cal(OWLClassExpression description) { + int cp = this.getNumberCoveredPositiveExamples(description); + int un = this.negativeExamples.size() + - this.getNumberOfCoveredNegativeExamples(description); + + return (cp + un) / (double) (positiveExamples.size() + negativeExamples.size()); + } + + protected double testAccuracy_cal(OWLClassExpression description) { + int cp = this.getNumberCoveredPositiveTestExamples(description); + int un = this.negativeTestExamples.size() + - this.getNumberOfCoveredNegativeTestExamples(description); + + return (cp + un) / (double) (positiveTestExamples.size() + negativeTestExamples.size()); + } + + /** + * Calculate the correctness of a description + * + * @param description + * Description to calculate + * + * @return Correctness of the description + */ + protected double correctness_cal(OWLClassExpression description) { + int un = this.negativeExamples.size() + - this.getNumberOfCoveredNegativeExamples(description); + return un / (double) this.negativeExamples.size(); + } + + /** + * Calculate the completeness of a description + * + * @param description + * Description to calculate + * + * @return Complete if the description + */ + protected double completeness_cal(OWLClassExpression description) { + int cp = this.getNumberCoveredPositiveExamples(description); + return cp / (double) this.positiveExamples.size(); + } + + /** + * Calculate accuracy, completeness and correctness:
+ * correctness(D) = not-covered-examples(D) / all-negative-examples
+ * completeness(D) = covered-positive-examples / all-positive-examples
+ * accuracy(D) = [covered-positive-examples(D) + not-covered-negative-examples(D)] / + * all-examples
+ * Noise has not been supported in the current version + * + * + * @param description + * Description to be calculated accuracy and correctness + * + * @return A ParCELEvaluationResult object. If the description is weak, its accuracy will be -1 + * + * NOTE: do we need "weak" concept with the value of -1? How if we just simply assign 0 + * for it? + */ + public ParCELEvaluationResult getAccuracyAndCorrectness(OWLClassExpression description) { + + int notCoveredPos = 0; + int notCoveredNeg = 0; + Set coveredPositiveExamples = new HashSet<>(); + + for (OWLIndividual example : positiveExamples) { + if (!reasoner.hasType(description, example)) + notCoveredPos++; + else + coveredPositiveExamples.add(example); + } + + if (coveredPositiveExamples.size() > 0) { + + notCoveredNeg = negativeExamples.size() + - getNumberOfCoveredNegativeExamples(description); + + double correctness = (double) notCoveredNeg / (double) negativeExamples.size(); + double completeness = (double) coveredPositiveExamples.size() / positiveExamples.size(); + + // if the description is not a partial definition (correct), set of covered positive + // examples will not be used + if (correctness < 1.0d) + coveredPositiveExamples = null; + + double accuracy = (positiveExamples.size() - notCoveredPos + notCoveredNeg) + / (double) (positiveExamples.size() + negativeExamples.size()); + + // accuracy = (covered positive examples + not covered negative examples) / all examples + // (completeness + correctness) + return new ParCELEvaluationResult(accuracy, correctness, completeness, + coveredPositiveExamples); + + } else { + // a node will be considered as "weak" if it covers none of the positive example and + // the accuracy will be assigned -1 + return new ParCELEvaluationResult(-1, 0, 0); + } + + } + + /** + * In this accuracy calculation, the accuracy value is based on the current uncovered positive + * examples but the covered positive examples returned still takes all positive examples into + * account + * + * @param description + * Description to be calculated + * @return + */ + public ParCELEvaluationResult getAccuracyAndCorrectness21(OWLClassExpression description) { + + int notCoveredNeg = 0; + Set coveredPositiveExamples = new HashSet<>(); + + // create a new set which contains all members of the uncovered positive examples + Set localUncoveredPositiveExamples = null; + + if (this.uncoveredPositiveExamples != null) { + synchronized (this.uncoveredPositiveExamples) { + localUncoveredPositiveExamples = new HashSet<>( + this.uncoveredPositiveExamples); + } + } else + localUncoveredPositiveExamples = new HashSet<>(this.positiveExamples); + + int originalNoOfUncoveredPositiveExamples = localUncoveredPositiveExamples.size(); + + // calculate the covered positive examples, we do + for (OWLIndividual example : positiveExamples) { + if (reasoner.hasType(description, example)) + coveredPositiveExamples.add(example); + } + + int noOfUpdatedCoveredPositiveExamples = localUncoveredPositiveExamples.size(); + localUncoveredPositiveExamples.removeAll(coveredPositiveExamples); + noOfUpdatedCoveredPositiveExamples -= localUncoveredPositiveExamples.size(); + + if (noOfUpdatedCoveredPositiveExamples > 0) { + notCoveredNeg = negativeExamples.size() + - getNumberOfCoveredNegativeExamples(description); + + double correctness = (double) notCoveredNeg / (double) negativeExamples.size(); + + double completeness = (double) coveredPositiveExamples.size() / positiveExamples.size(); + + // double accuracy = (positiveExamples.size() - notCoveredPos + + // notCoveredNeg)/(double)(positiveExamples.size() + negativeExamples.size()); + double accuracy = (noOfUpdatedCoveredPositiveExamples + notCoveredNeg) + / (double) (originalNoOfUncoveredPositiveExamples + negativeExamples.size()); + // accuracy = (covered positive examples + not covered negative examples) / all examples + // (completeness + correctness) + + if (correctness < 1.0d) + coveredPositiveExamples = null; + + return new ParCELEvaluationResult(accuracy, correctness, completeness, + coveredPositiveExamples); + + } else { + // a node will be considered as "weak" if it covers none of the positive example and + // the accuracy will be assigned -1 + return new ParCELEvaluationResult(-1, 0, 0); + } + + } + + + /** + * In this accuracy calculation, the accuracy value is based on the current uncovered positive + * examples but the covered positive examples returned still takes all positive examples into + * account + * + * @param description + * Description to be calculated + * @return + */ + public ParCELEvaluationResult getAccuracyAndCorrectness2(OWLClassExpression description, double noise) { + + int notCoveredNeg = 0; + Set coveredPositiveExamples = new HashSet<>(); + + // create a new set which contains all members of the uncovered positive examples + Set localUncoveredPositiveExamples; + + if (this.uncoveredPositiveExamples != null) { + synchronized (this.uncoveredPositiveExamples) { + localUncoveredPositiveExamples = new HashSet<>( + this.uncoveredPositiveExamples); + } + } else + localUncoveredPositiveExamples = new HashSet<>(this.positiveExamples); + + int originalNoOfUncoveredPositiveExamples = localUncoveredPositiveExamples.size(); + + // calculate the covered positive examples, we do + for (OWLIndividual example : positiveExamples) { + if (reasoner.hasType(description, example)) + coveredPositiveExamples.add(example); + } + + int noOfUpdatedCoveredPositiveExamples = localUncoveredPositiveExamples.size(); + localUncoveredPositiveExamples.removeAll(coveredPositiveExamples); + noOfUpdatedCoveredPositiveExamples -= localUncoveredPositiveExamples.size(); + + if (noOfUpdatedCoveredPositiveExamples > 0) { + notCoveredNeg = negativeExamples.size() + - getNumberOfCoveredNegativeExamples(description); + + double correctness = (double) notCoveredNeg / (double) negativeExamples.size(); + + double completeness = (double) coveredPositiveExamples.size() / positiveExamples.size(); + + // double accuracy = (positiveExamples.size() - notCoveredPos + + // notCoveredNeg)/(double)(positiveExamples.size() + negativeExamples.size()); + double accuracy = (noOfUpdatedCoveredPositiveExamples + notCoveredNeg) + / (double) (originalNoOfUncoveredPositiveExamples + negativeExamples.size()); + // accuracy = (covered positive examples + not covered negative examples) / all examples + // (completeness + correctness) + + if (correctness < 1.0d - noise) + coveredPositiveExamples = null; + + return new ParCELEvaluationResult(accuracy, correctness, completeness, + coveredPositiveExamples); + + } else { + // a node will be considered as "weak" if it covers none of the positive example and + // the accuracy will be assigned -1 + return new ParCELEvaluationResult(-1, 0, 0); + } + + } + + + /** + * In this accuracy calculation, positive examples covered by a new partial definition will be + * remove from all further calculations + * + * @param description + * Description to be calculated + * @return + */ + public ParCELEvaluationResult getAccuracyAndCorrectness3(OWLClassExpression description) { + + int notCoveredNeg = 0; + Set coveredPositiveExamples = new HashSet<>(); + + // create a new set which contains all members of the uncovered positive examples + Set localUncoveredPositiveExamples = null; + + if (this.uncoveredPositiveExamples != null) { + synchronized (this.uncoveredPositiveExamples) { + localUncoveredPositiveExamples = new HashSet<>( + this.uncoveredPositiveExamples); + } + } else + localUncoveredPositiveExamples = new HashSet<>(this.positiveExamples); + + // calculate the covered positive examples, we do + for (OWLIndividual example : localUncoveredPositiveExamples) { + if (reasoner.hasType(description, example)) + coveredPositiveExamples.add(example); + } + + if (coveredPositiveExamples.size() > 0) { + notCoveredNeg = negativeExamples.size() + - getNumberOfCoveredNegativeExamples(description); + + double correctness = (double) notCoveredNeg / (double) negativeExamples.size(); + double completeness = (double) coveredPositiveExamples.size() + / uncoveredPositiveExamples.size(); + + // double accuracy = (positiveExamples.size() - notCoveredPos + + // notCoveredNeg)/(double)(positiveExamples.size() + negativeExamples.size()); + double accuracy = (coveredPositiveExamples.size() + notCoveredNeg) + / (double) (localUncoveredPositiveExamples.size() + negativeExamples.size()); + // accuracy = (covered positive examples + not covered negative examples) / all examples + // (completeness + correctness) + + if (correctness < 1.0d) + coveredPositiveExamples = null; + + return new ParCELEvaluationResult(accuracy, correctness, completeness, + coveredPositiveExamples); + + } else { + // a node will be considered as "weak" if it covers none of the positive example and + // the accuracy will be assigned -1 + return new ParCELEvaluationResult(-1, 0, 0); + } + + } + + public ParCELEvaluationResult getAccuracyAndCorrectness4(OWLClassExpression description, double noise) { + Set coveredPositiveExamples = reasoner.hasType(description, positiveExamples); + Set coveredNegativeExamples = reasoner.hasType(description, negativeExamples); + + if (coveredPositiveExamples.isEmpty()) { + return new ParCELEvaluationResult(-1, 0, 0); + } + + ParCELEvaluationResult result = new ParCELEvaluationResult(); + + int cp = coveredPositiveExamples.size(); + int un = negativeExamples.size() - coveredNegativeExamples.size(); + + result.accuracy = (cp + un) / (double) (positiveExamples.size() + negativeExamples.size()); + result.correctness = un / (double) negativeExamples.size(); + result.completeness = cp / (double) positiveExamples.size(); + + if (result.correctness >= 1.0d - noise) { + result.coveredPositiveExamples = coveredPositiveExamples; + } + + return result; + } + + /** + * Accuracy calculation for the exception learning which provide both covered positive and + * negative examples by the description
+ *
    + *
  1. cp(D) = empty
  2. + *
      + *
    • cn(D) = empty: weak description ==> may be ignored
    • + *
    • cn(D) != empty: counter partial definition, especially used in learning with exceptions
    • + *
    + *
  3. cp(D) != empty
  4. + *
      + *
    • cn(D) = empty: partial definition
    • + *
    • cn(D) != empty: potential description
    • + *
    + *
+ * + * + * @param description + * Description to be calculated + * @return + */ + public ParCELEvaluationResult getAccuracyAndCorrectnessEx(OWLClassExpression description) { + + Set coveredPositiveExamples = new HashSet<>(); + Set coveredNegativeExamples = new HashSet<>(); + + // calculate the set of positive examples covered by the description + for (OWLIndividual example : positiveExamples) { + if (reasoner.hasType(description, example)) + coveredPositiveExamples.add(example); + } + + // calculate the set of negative examples covered by the description + for (OWLIndividual example : negativeExamples) { + if (reasoner.hasType(description, example)) + coveredNegativeExamples.add(example); + } + + ParCELEvaluationResult result = new ParCELEvaluationResult(); + + int cp = coveredPositiveExamples.size(); + int un = negativeExamples.size() - coveredNegativeExamples.size(); + double accuracy = (cp + un) / (double) (positiveExamples.size() + negativeExamples.size()); + + result.accuracy = accuracy; + result.correctness = un / (double) negativeExamples.size(); + result.completeness = cp / (double) positiveExamples.size(); + + if (coveredPositiveExamples.size() > 0) + result.coveredPositiveExamples = coveredPositiveExamples; + + if (coveredNegativeExamples.size() > 0) + result.coveredNegativeExamples = coveredNegativeExamples; + + return result; + + } + + public static String getName() { + return "PDLL pos neg learning problem"; + } + + /** + * PDLLScore = {accuracy, correctness} + */ + @Override + public ParCELScore computeScore(OWLClassExpression description) { + double correctness = this.correctness_cal(description); + double accuracy = this.accuracy_cal(description); + + return new ParCELScore(accuracy, correctness); + } + + @Override + public ParCELScore computeScore(OWLClassExpression description, double noise) { + double correctness = this.correctness_cal(description); + double accuracy = this.accuracy_cal(description); + + return new ParCELScore(accuracy, correctness); + } + + + /** + * Create evaluated description + */ + @Override + public EvaluatedDescription evaluate(OWLClassExpression description) { + ParCELScore score = this.computeScore(description); + + return new EvaluatedDescription(description, score); + } + + public double getAccuracy(OWLClassExpression description) { + return accuracy_cal(description); + } + + public double getTestAccuracy(OWLClassExpression description) { + return testAccuracy_cal(description); + } + + @Override + public double getAccuracyOrTooWeak(OWLClassExpression description, double noise) { + throw new RuntimeException("getAccuracyOrTooWeak() is not supported by PDLLPosNegLP"); + } + + @Override + public void init() throws ComponentInitException { + // super.init(); + } + + public Set getPositiveExamples() { + return this.positiveExamples; + } + + public void setPositiveExamples(Set positiveExamples) { + this.positiveExamples = positiveExamples; + } + + public Set getNegativeExamples() { + return this.negativeExamples; + } + + public void setNegativeExamples(Set negativeExamples) { + this.negativeExamples = negativeExamples; + } + + public void setUncoveredPositiveExamples(Set uncoveredPositiveExamples) { + this.uncoveredPositiveExamples = uncoveredPositiveExamples; + } + + public void setPositiveTestExamples(Set positiveTestExamples) { + this.positiveTestExamples = positiveTestExamples; + } + + public void setNegativeTestExamples(Set negativeTestExamples) { + this.negativeTestExamples = negativeTestExamples; + } + + public Set getPositiveTestExamples() { + return this.positiveTestExamples; + } + + public Set getNegativeTestExamples() { + return this.negativeTestExamples; + } +} + diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java new file mode 100644 index 0000000000..85be1db8c5 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java @@ -0,0 +1,208 @@ +package org.dllearner.algorithms.parcel; + +/** + * Refinement operator factory (RhoDRDown2008) + * + * @author An C. Tran + */ + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.pool2.BasePooledObjectFactory; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.impl.DefaultPooledObject; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterAbstract; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.owl.ClassHierarchy; +import org.dllearner.refinementoperators.RefinementOperator; +import org.dllearner.refinementoperators.RhoDRDown; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLLiteral; +import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; + +public class ParCELRefinementOperatorFactory extends BasePooledObjectFactory { + + private final AbstractReasonerComponent reasoner; + private final ClassHierarchy classHierarchy; + private final OWLClassExpression startClass; + private Map> splits; + private int maxNoOfSplits; + + private int cardinalityLimit = 5; + private boolean useNegation = true; + private boolean useDisjunction = true; + private boolean useHasValue = true; + private boolean useHasData = false; + private boolean useCardinalityRestrictions = true; + + private RhoDRDown operatorPrototype = null; + + final Logger logger = Logger.getLogger(this.getClass()); + + public ParCELRefinementOperatorFactory(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, + OWLClassExpression startClass, int maxNoOfSplits) { + this.reasoner = reasoner; + this.classHierarchy = classHierarchy; + this.startClass = startClass; + this.splits = null; + this.maxNoOfSplits = maxNoOfSplits; + } + + + public ParCELRefinementOperatorFactory(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, + OWLClassExpression startClass, ParCELDoubleSplitterAbstract splitter) { + this.reasoner = reasoner; + this.classHierarchy = classHierarchy; + this.startClass = startClass; + + OWLDataFactory df = new OWLDataFactoryImpl(); + this.splits = splitter.computeSplits().entrySet().stream().collect( + Collectors.toMap( + Map.Entry::getKey, + e -> e.getValue().stream().map(df::getOWLLiteral).collect(Collectors.toList())) + ); + + if (logger.isDebugEnabled()) + logger.debug("Splits is calculated: " + splits); + } + + + public ParCELRefinementOperatorFactory(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, + OWLClassExpression startClass, Map> splits) { + this.reasoner = reasoner; + this.classHierarchy = classHierarchy; + this.startClass = startClass; + + OWLDataFactory df = new OWLDataFactoryImpl(); + this.splits = splits.entrySet().stream().collect( + Collectors.toMap( + Map.Entry::getKey, + e -> e.getValue().stream().map(df::getOWLLiteral).collect(Collectors.toList())) + ); + } + + public ParCELRefinementOperatorFactory(RhoDRDown operatorPrototype) { + reasoner = null; + classHierarchy = null; + startClass = null; + this.operatorPrototype = operatorPrototype.clone(); + } + + public ParCELRefinementOperatorFactory(RhoDRDown operatorPrototype, Map> splits) { + reasoner = null; + classHierarchy = null; + startClass = null; + + OWLDataFactory df = new OWLDataFactoryImpl(); + this.operatorPrototype = operatorPrototype.clone(); + this.operatorPrototype.setSplits( + splits.entrySet().stream().collect( + Collectors.toMap( + Map.Entry::getKey, + e -> e.getValue().stream().map(df::getOWLLiteral).collect(Collectors.toList())) + ) + ); + } + + @Override + public RefinementOperator create() throws Exception { + if (operatorPrototype == null) { + //clone a new class hierarchy to avoid the competition between refinement operators + ClassHierarchy clonedClassHierarchy = classHierarchy.clone(); + + if (logger.isDebugEnabled()) + logger.info("A new refinement operator had been created"); + + //create a new RhoDRDown and return + operatorPrototype = new RhoDRDown(); + operatorPrototype.setReasoner(reasoner); + operatorPrototype.setClassHierarchy(clonedClassHierarchy); + operatorPrototype.setStartClass(startClass); + operatorPrototype.setUseDisjunction(useDisjunction); + operatorPrototype.setUseNegation(useNegation); + operatorPrototype.setUseDataHasValueConstructor(useHasData); // TODO: MY set default back to true + operatorPrototype.setUseHasValueConstructor(useHasValue); + operatorPrototype.setCardinalityLimit(cardinalityLimit); + operatorPrototype.setMaxNrOfSplits(maxNoOfSplits); + operatorPrototype.setCardinalityLimit(cardinalityLimit); + operatorPrototype.setUseCardinalityRestrictions(useCardinalityRestrictions); + + if (this.splits != null) { + operatorPrototype.setSplits(splits); + } + } + + if (!operatorPrototype.isInitialized()) { + operatorPrototype.init(); + } + + RhoDRDown refinementOperator = operatorPrototype.clone(); + + // init the refinement operator; + refinementOperator.init(); + + return refinementOperator; + } + + @Override + public PooledObject wrap(RefinementOperator refinementOperator) { + return new DefaultPooledObject<>(refinementOperator); + } + + + public boolean isUseNegation() { + return useNegation; + } + + + public void setUseNegation(boolean useNegation) { + this.useNegation = useNegation; + } + + + public boolean isUseDisjunction() { + return useDisjunction; + } + + + public void setUseDisjunction(boolean useDisjunction) { + this.useDisjunction = useDisjunction; + } + + public void setUseHasValue(boolean useHasValue) { + this.useHasValue = useHasValue; + } + + public boolean getUseHasValue() { + return this.useHasValue; + } + + public void setUseHasData(boolean useData) { + this.useHasData = useData; + } + + public boolean getUseHasData() { + return this.useHasData; + } + + public int getCardinalityLimit() { + return this.cardinalityLimit; + } + + public void setCardinalityLimit(int cardinality) { + this.cardinalityLimit = cardinality; + } + + public void setUseCardinalityRestrictions(boolean useCardinalityRestrictions) { + this.useCardinalityRestrictions = useCardinalityRestrictions; + } + + public boolean getUseCardinalityRestrictions() { + return this.useCardinalityRestrictions; + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorPool.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorPool.java new file mode 100644 index 0000000000..278cca519e --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorPool.java @@ -0,0 +1,112 @@ +package org.dllearner.algorithms.parcel; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterAbstract; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.owl.ClassHierarchy; +import org.dllearner.refinementoperators.RefinementOperator; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataProperty; + +/** + * Refinement operator pool + * + * @author An C. Tran + */ +public class ParCELRefinementOperatorPool extends GenericObjectPool { + + /** + * Create refinement operator pool given max number of idle object without splitter + * + * @param reasoner + * @param classHierarchy + * @param startclass + * @param maxIdle + */ + public ParCELRefinementOperatorPool(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, + OWLClassExpression startclass, int maxIdle, int maxNoOfSplits) { + super(new ParCELRefinementOperatorFactory(reasoner, classHierarchy, startclass, maxNoOfSplits)); + setMaxIdle(maxIdle); + } + + /** + * Create refinement operator pool given max number of idle object and splitter + * + * @param reasoner + * @param classHierarchy + * @param startclass + * @param splits Splitter used to calculate the splits + * @param maxIdle + */ + public ParCELRefinementOperatorPool(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, OWLClassExpression startclass, + Map> splits, int maxIdle) { + super(new ParCELRefinementOperatorFactory(reasoner, classHierarchy, startclass, splits)); + setMaxIdle(maxIdle); + } + + + public ParCELRefinementOperatorPool(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, OWLClassExpression startclass, + ParCELDoubleSplitterAbstract splitter, int maxIdle) { + super(new ParCELRefinementOperatorFactory(reasoner, classHierarchy, startclass, splitter)); + setMaxIdle(maxIdle); + } + + + public ParCELRefinementOperatorPool(ParCELRefinementOperatorFactory parcelRefinementFactory) { + super(parcelRefinementFactory); + } + + /** + * Create refinement operator pool given max number of idle object, max capacity without splitter + * + * @param reasoner + * @param classHierarchy + * @param startclass + * @param maxIdle + * @param maxIdleCapacity + */ + public ParCELRefinementOperatorPool(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, + OWLClassExpression startclass, int maxIdle, int maxIdleCapacity, + int maxNoOfSplits) { + super(new ParCELRefinementOperatorFactory(reasoner, classHierarchy, startclass, maxNoOfSplits)); + setMaxIdle(maxIdle); + setMaxTotal(maxIdleCapacity); + } + + + /** + * Create refinement operator pool given max number of idle object, max capacity and splitter + * + * @param reasoner + * @param classHierarchy + * @param startclass + * @param splitter + * @param maxIdle + * @param maxIdleCapacity + */ + public ParCELRefinementOperatorPool(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, + OWLClassExpression startclass, ParCELDoubleSplitterAbstract splitter, + int maxIdle, int maxIdleCapacity) { + super(new ParCELRefinementOperatorFactory(reasoner, classHierarchy, startclass, splitter)); + setMaxIdle(maxIdle); + setMaxTotal(maxIdleCapacity); + } + + + public ParCELRefinementOperatorPool(AbstractReasonerComponent reasoner, ClassHierarchy classHierarchy, + OWLClassExpression startclass, Map> splits, + int maxIdle, int maxIdleCapacity) { + super(new ParCELRefinementOperatorFactory(reasoner, classHierarchy, startclass, splits)); + setMaxIdle(maxIdle); + setMaxTotal(maxIdleCapacity); + } + + + public ParCELRefinementOperatorFactory getFactory() { + return (ParCELRefinementOperatorFactory) super.getFactory(); + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELScore.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELScore.java new file mode 100644 index 0000000000..689ebbd2c1 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELScore.java @@ -0,0 +1,38 @@ +package org.dllearner.algorithms.parcel; + +import org.dllearner.core.Score; + +/** + * This class implement methods that will be used to create an EvaluatedDescription + * (this provide information for sorting the node in search tree) + * + * @author An C. Tran + * + */ +@SuppressWarnings("serial") +public class ParCELScore extends Score { + + final double accuracy; + final double correctness; + + public ParCELScore(ParCELNode node) { + this.accuracy = node.getAccuracy(); + this.correctness = node.getCorrectness(); + } + + public ParCELScore(double accuracy, double correctness) { + this.accuracy = accuracy; + this.correctness = correctness; + } + + @Override + public double getAccuracy() { + return this.accuracy; + } + + public double getCorrectness() { + return this.correctness; + } + + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELStringUtilities.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELStringUtilities.java new file mode 100644 index 0000000000..1462b840c5 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELStringUtilities.java @@ -0,0 +1,48 @@ +package org.dllearner.algorithms.parcel; + +import java.util.Map; +import java.util.Map.Entry; + +public class ParCELStringUtilities { + /** + * =====================================================================================
+ * This method is used to add padding "0" before a string so that the string has the expected + * length. + * + * @param s + * String that need to be padded with zero ahead "0" + * + * @return A zero "0" padding string + */ + public static String zeroPad(String s, int len) { + String result = s; + for (int i = s.length(); i < len; i++) + result = "0".concat(result); + + return result; + } + + /** + * =====================================================================================
+ * Shorten an URI by removing all bases or using its prefixes + * + * @param uri + * String need to be shortened + * @param baseURI + * Base URI. Null if we don't want to used base uri + * @param prefixes + * List of prefixes + * @return + */ + public static String replaceString(String uri, String baseURI, Map prefixes) { + if (baseURI != null && uri.startsWith(baseURI)) { + return uri.replace(baseURI, ""); + } else { + if (prefixes != null) { + for (Entry prefix : prefixes.entrySet()) + uri = uri.replace(prefix.getValue(), prefix.getKey()); + } + return uri; + } + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java new file mode 100644 index 0000000000..f913ff784b --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -0,0 +1,185 @@ +package org.dllearner.algorithms.parcel; + +import java.util.HashSet; +import java.util.Map; +import java.util.TreeSet; + +import org.apache.log4j.Logger; +import org.dllearner.refinementoperators.LengthLimitedRefinementOperator; +import org.dllearner.refinementoperators.RefinementOperator; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.mindswap.pellet.exceptions.InternalReasonerException; +import org.semanticweb.owlapi.model.OWLClassExpression; + +/** + * ParCEL worker which find and evaluate the refinements for a given node. + * It returns partial definitions and/or new description to the learner if any. + * + * @author An C. Tran + */ +public class ParCELWorker extends ParCELWorkerAbstract { + + /** + * Constructor for Worker class. A worker needs the following things: i) reducer (reference), + * ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result + * to + * @param refinementOperatorPool Refinement operator pool used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorker(ParCELearner learner, ParCELRefinementOperatorPool refinementOperatorPool, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperatorPool, learningProblem, nodeToProcess, name); + } + + + /** + * Constructor for Worker class. A worker needs the following things: i) reducer (reference), + * ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result + * to + * @param refinementOperator Refinement operator used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorker(ParCELearner learner, RefinementOperator refinementOperator, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperator, learningProblem, nodeToProcess, name); + } + + /** + * Start the worker: Call the methods processNode() for processing the current node given by + * reducer + */ + @Override + public void run() { + + if (logger.isTraceEnabled()) + logger.trace("[ParCEL-Worker] Processing node (" + + ParCELStringUtilities.replaceString(nodeToProcess.toString(), this.baseURI, + this.prefix)); + + + HashSet definitionsFound = new HashSet<>(); // hold the + // partial + // definitions + // if any + HashSet newNodes = new HashSet<>(); // hold the refinements that are + // not partial definitions + // (descriptions) + + int horizExp = nodeToProcess.getHorizontalExpansion(); + + // 1. refine node + TreeSet refinements = refineNode(nodeToProcess); +// System.out.println("ParCEL Worker " + name + ":" + refinements); + + if (refinements != null) { + if (logger.isTraceEnabled()) + logger.trace("Refinement result (" + + refinements.size() + + "): " + + ParCELStringUtilities.replaceString(refinements.toString(), this.baseURI, + this.prefix)); + } + + // 2. process the refinement result: calculate the accuracy and completeness and add the new + // expression into the search tree + while (refinements != null && refinements.size() > 0) { + OWLClassExpression refinement = refinements.pollFirst(); + int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); + + // we ignore all refinements with lower length (may it happen?) + // (this also avoids duplicate children) + if (refinementLength > horizExp) { + + // calculate accuracy, correctness, positive examples covered by the description, + // resulted in a node + long starttime = System.currentTimeMillis(); + ParCELExtraNode addedNode = null; + + try { + addedNode = checkAndCreateNewNode(refinement, nodeToProcess); + } catch (InternalReasonerException e) {} + + // make decision on the new node (new search tree node or new partial definition) + if (addedNode != null) { + + // PARTIAL DEFINITION (correct and not necessary to be complete) + if (addedNode.getCorrectness() >= 1.0d - learner.getNoiseAllowed()) { + addedNode.setGenerationTime(System.currentTimeMillis()); + addedNode.setExtraInfo(learner.getTotalDescriptions()); + definitionsFound.add(addedNode); + } + // DESCRIPTION + else + newNodes.add((ParCELNode) addedNode); + } // if (node != null), i.e. weak description + } + } // while (refinements.size > 0) + + horizExp = nodeToProcess.getHorizontalExpansion(); + + learner.updateMaxHorizontalExpansion(horizExp); + + newNodes.add(nodeToProcess); + + if (definitionsFound.size() > 0) + learner.newPartialDefinitionsFound(definitionsFound); + + learner.newRefinementDescriptions(newNodes); + + } + + /** + * Calculate accuracy, correctness of a description and examples that are covered by this + * description + * + * @param description Description which is being calculated + * @param parentNode The node which contains the description which is used in the refinement that + * result the input description + * @return Null if the description is processed before, or a node which contains the description + */ + private ParCELExtraNode checkAndCreateNewNode(OWLClassExpression description, ParCELNode parentNode) { + + // redundancy check + boolean nonRedundant = learner.addDescription(description); + if (!nonRedundant) + return null; // false, node cannot be added + + // currently, noise is not processed. it should be processed later + ParCELEvaluationResult accurateAndCorrectness = learningProblem + .getAccuracyAndCorrectness4(description, learner.getNoiseAllowed()); +// System.out.println(description + ":" + accurateAndCorrectness); + + // description is too weak, i.e. covered no positive example + if (accurateAndCorrectness.accuracy == -1.0d) + return null; + + ParCELExtraNode newNode = new ParCELExtraNode(parentNode, description, + accurateAndCorrectness.accuracy, accurateAndCorrectness.correctness, + accurateAndCorrectness.completeness, + accurateAndCorrectness.coveredPositiveExamples); + + if (parentNode != null) + parentNode.addChild(newNode); + + return newNode; + + } // addNode() + + + /** + * Get the node which is currently being processed + * + * @return The node currently being processed + */ + public ParCELNode getProcessingNode() { + return this.nodeToProcess; + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java new file mode 100644 index 0000000000..34655cdd37 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java @@ -0,0 +1,162 @@ +package org.dllearner.algorithms.parcel; + +import org.apache.log4j.Logger; +import org.dllearner.refinementoperators.LengthLimitedRefinementOperator; +import org.dllearner.refinementoperators.RefinementOperator; +import org.semanticweb.owlapi.model.OWLClassExpression; + +import java.util.Map; +import java.util.TreeSet; + +public abstract class ParCELWorkerAbstract implements Runnable { + + // name of worker (for debugging purpose) + protected String name; + + // refinement operator used in refinement + protected final ParCELRefinementOperatorPool refinementOperatorPool; + protected RefinementOperator refinementOperator; + + // reducer, used to make the callback to pass the result and get the next description for + // processing + protected final L learner; + + // learning proble, provides accuracy & correctness calculation + protected final ParCELPosNegLP learningProblem; + + // the node to be processed + protected final ParCELNode nodeToProcess; + + protected final Logger logger = Logger.getLogger(this.getClass()); + + // these properties can be referred in Reducer. However, we put it here for faster access + protected final String baseURI; + protected final Map prefix; + + /** + * Constructor for Worker class. A worker needs the following things: i) reducer (reference), + * ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result + * to + * @param refinementOperatorPool Refinement operator pool used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerAbstract(L learner, ParCELRefinementOperatorPool refinementOperatorPool, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + this.learner = learner; + this.refinementOperatorPool = refinementOperatorPool; + this.refinementOperator = null; + + this.learningProblem = learningProblem; + + this.nodeToProcess = nodeToProcess; + this.name = name; + + this.baseURI = learner.getBaseURI(); + this.prefix = learner.getPrefix(); + } + + /** + * Constructor for Worker class. A worker needs the following things: i) reducer (reference), + * ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result + * to + * @param refinementOperator Refinement operator used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerAbstract(L learner, RefinementOperator refinementOperator, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + this.learner = learner; + this.refinementOperator = refinementOperator; + this.refinementOperatorPool = null; + + this.learningProblem = learningProblem; + + this.nodeToProcess = nodeToProcess; + this.name = name; + + this.baseURI = learner.getBaseURI(); + this.prefix = learner.getPrefix(); + } + + /** + * Refine a node using RhoDRDown. The refined node will be increased the max horizontal + * expansion value by 1 + * + * @param node Node to be refined + * @return Set of descriptions that are the results of refinement + */ + protected TreeSet refineNode(ParCELNode node) { + int horizExp = node.getHorizontalExpansion(); + + if (logger.isTraceEnabled()) + logger.trace("[" + this.name + "] Refining: " + + ParCELStringUtilities.replaceString(node.toString(), baseURI, prefix)); + + boolean refirementOperatorBorrowed = false; + + // borrow refinement operator if necessary + if (this.refinementOperator == null) { + if (this.refinementOperatorPool == null) { + logger.error("Neither refinement operator nor refinement operator pool provided"); + return null; + } else { + try { + // logger.info("borrowing a refinement operator (" + + // refinementOperatorPool.getNumIdle() + ")"); + this.refinementOperator = this.refinementOperatorPool.borrowObject(); + refirementOperatorBorrowed = true; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + TreeSet refinements = null; + try { + // TODO that's odd, we should just restrict the whole code to LengthLimitedRefinementOperator + if (refinementOperator instanceof LengthLimitedRefinementOperator) { + refinements = (TreeSet) ((LengthLimitedRefinementOperator) refinementOperator).refine(node.getDescription(), horizExp + 1); + } else { + refinements = (TreeSet) refinementOperator.refine(node.getDescription()); + } + + node.incHorizontalExpansion(); + node.setRefinementCount(refinements.size()); + } catch (Exception e) { + e.printStackTrace(); + } + + // return the refinement operator + if (refirementOperatorBorrowed) { + try { + if (refinementOperator != null) + refinementOperatorPool.returnObject(refinementOperator); + else + logger.error("Cannot return the borrowed refinement operator"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return refinements; + } + + + + /** + * Get the node which is currently being processed + * + * @return The node currently being processed + */ + public ParCELNode getProcessingNode() { + return this.nodeToProcess; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerThreadFactory.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerThreadFactory.java new file mode 100644 index 0000000000..89c93f19de --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerThreadFactory.java @@ -0,0 +1,20 @@ +package org.dllearner.algorithms.parcel; + +import java.util.concurrent.ThreadFactory; + +/** + * ParCEL worker factory + * + * @author An C. Tran + * + */ + +public class ParCELWorkerThreadFactory implements ThreadFactory { + private int count=0; + final String idPrefix = "ParCELWorker-"; + + @Override + public Thread newThread(Runnable r) { + return new Thread(r, idPrefix + (count++)); + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java new file mode 100644 index 0000000000..13f326713b --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -0,0 +1,360 @@ +package org.dllearner.algorithms.parcel; + +/** + * This class implements a Parallel Description Logic Learner (PDLL) using Worker/Reducer model. + * Basic configuration for a PDLL including: + *
    + *
  1. numberOfWorkers: The number of workers. The default value for this parameter is 2. + * Basically, the number of workers should be 2 x number of cores
  2. + *
  3. maxExecutionTimeInSecond: Timeout in ms. By default, there is no timeout for the learning
  4. + *
  5. maxNoOfSplits: Maximal number os split used for numerical data properties. SHABDDoubleSplitter may be used.
  6. + *
+ * + * @author An C. Tran + */ + +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentInitException; +import org.dllearner.utilities.owl.OWLAPIRenderers; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; + +import javax.management.MBeanServer; +import javax.management.ObjectName; +import java.lang.management.ManagementFactory; +import java.util.HashSet; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.RejectedExecutionException; + +@ComponentAnn(name = "ParCEL", shortName = "parcel", version = 0.1, description = "PARallel Class Expression Learning") +public class ParCELearner extends ParCELAbstract implements ParCELearnerMBean { + + /** + * ============================================================================================ + * Constructor for PDLL learning algorithm + * + * @param learningProblem + * Must be a ParCELPosNegLP + * @param reasoningService + * A reasoner + */ + public ParCELearner(ParCELPosNegLP learningProblem, AbstractReasonerComponent reasoningService) { + super(learningProblem, reasoningService); + } + + /** + * This constructor can be used by SpringDefinition to create bean object Properties of new bean + * may be initialised later using setters + */ + public ParCELearner() { + super(); + } + + /** + * ============================================================================================ + * Get the name of this learning algorithm + * + * @return Name of this learning algorithm: PLLearning + */ + public static String getName() { + return "ParCELearner"; + } + + /** + * ============================================================================================ + * Initialize the learning algorithm: + */ + @Override + public void init() throws ComponentInitException { + + // check the learning problem, this learning algorithm support ParCELPosNegLP only + if (!(learningProblem instanceof ParCELPosNegLP)) + throw new ComponentInitException(learningProblem.getClass() + " is not supported by '" + + getName() + "' learning algorithm. Only ParCELPosNegLP is supported."); + + // get the positive and negative examples from the learning problem + positiveExamples = ((ParCELPosNegLP) learningProblem).getPositiveExamples(); + negativeExamples = ((ParCELPosNegLP) learningProblem).getNegativeExamples(); + positiveTestExamples = ((ParCELPosNegLP) learningProblem).getPositiveTestExamples(); + negativeTestExamples = ((ParCELPosNegLP) learningProblem).getNegativeTestExamples(); + + // clone the positive examples for this set to avoid affecting the Learning Problem + // this will be used to check the coverage of the partial definition (completeness) + this.uncoveredPositiveExamples = new HashSet<>(this.positiveExamples); + + // initial heuristic which will be used by reducer to sort the search tree + // the heuristic need to get some constant from the configurator for scoring the description + if (this.heuristic == null) + heuristic = new ParCELDefaultHeuristic(); + + // this will be revised later using least common super class of all observations + if (startClass == null) { + startClass = dataFactory.getOWLThing(); + } + + //TODO check this - what is noise? for positive or negative examples? + //---------------------- + //this.uncoveredPositiveExampleAllowed = (int) Math.ceil(getNoisePercentage() * positiveExamples.size()); + this.uncoveredPositiveExampleAllowed = 0; + noiseAllowed = this.noisePercentage/100d; + //---------------------- + + // initial the existing uncovered positive examples + ((ParCELPosNegLP) this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); + + // ---------------------------------- + // create refinement operator pool + // ---------------------------------- + initOperatorIfAny(); + createRefinementOperatorPool(); + + baseURI = reasoner.getBaseURI(); + prefix = reasoner.getPrefixes(); + + // logging the information (will use slf4j) + if (logger.isInfoEnabled()) { + logger.info("Heuristic used: " + heuristic.getClass()); + logger.info("Training -> Positive examples: " + positiveExamples.size() + + ", negative examples: " + negativeExamples.size()); + logger.info("Testing -> Positive examples: " + positiveTestExamples.size() + + ", negative examples: " + negativeTestExamples.size()); + } + + minNumberOfWorker = maxNumberOfWorker = numberOfWorkers; + + } + + protected void reset() { + // register a MBean for debugging purpose + try { + ObjectName parCELearnerBean = new ObjectName( + "org.dllearner.algorithms.parcel.ParCELearnerMBean:type=ParCELearnerBean"); + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + if (!mbs.isRegistered(parCELearnerBean)) + mbs.registerMBean(this, parCELearnerBean); + } catch (Exception e) { + e.printStackTrace(); + } + + stop = false; + done = false; + timeout = false; + + trainingTime = getCurrentCpuMillis(); + + //allDescriptions = new TreeSet(new ConceptComparator()); + allDescriptions = new ConcurrentSkipListSet<>(); + + searchTree = new ConcurrentSkipListSet<>(heuristic); + + partialDefinitions = new TreeSet<>(new ParCELCorrectnessComparator()); + + maxAccuracy = 0; + noOfCompactedPartialDefinition = 0; + noOfUncoveredPositiveExamples = this.positiveExamples.size(); + } + + /** + * ============================================================================================ + * Start reducer:
+ * 1. Reset the status of reducer (stop, isRunning, done, timeout)
+ * 2. Reset the data structure (using reset() method)
+ * 3. Create a set of workers and add them into the worker pool
+ * NOTE: Each worker will have it own refinement operator
+ * 4. Prepare some data: pos/neg examples, uncovered positive examples, etc.
+ * 5. Start the learning progress:
+ * i) refine nodes in the (tree set)
+ * ii) evaluate nodes in unevaluated nodes (hash set)
+ * + */ + /* + * (non-Javadoc) + * @see org.dllearner.core.LearningAlgorithm#start() + */ + @Override + public void start() { + reset(); + + initSearchTree(); + + createWorkerPool(); + + // start time of the learner + miliStarttime = System.currentTimeMillis(); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + + // ---------------------------------------------------------- + // perform the learning process until the conditions for + // termination meets + // ---------------------------------------------------------- + while (!isTerminateCriteriaSatisfied()) { + + ParCELNode nodeToProcess = searchTree.pollLast(); + + // TODO: why this? why "blocking" concept does not help in this case? + // remove this checking will exploit the heap memory and no definition found + // NOTE: i) instead of using sleep, can we use semaphore here? + // ii) if using semaphore or blocking, timeout checking may not be performed on time? + while ((workerPool.getQueue().size() >= maxTaskQueueLength) && !done) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + //NOTE: the above WHILE loop and the following IF statement require checking "done" + // condition to prevent waiting for the full+finish job or the full+terminating workerpool + + if ((nodeToProcess != null) && !done && !workerPool.isShutdown() && !workerPool.isTerminating()) { + try { + this.createNewTask(nodeToProcess); + } catch (RejectedExecutionException re) { + logger.error(re); + + //if cannot submit the new task, return the node back to the search tree + this.searchTree.add(nodeToProcess); + } + } + } // while the algorithm is not finish + + this.miliLearningTime = System.currentTimeMillis() - miliStarttime; + + stop(); + + // ------------------------------- + // post-learning processing + // ------------------------------- + if (logger.isInfoEnabled()) { + synchronized (partialDefinitions) { + double acc = (this.negativeExamples.size() + this.positiveExamples.size() - + this.uncoveredPositiveExamples.size())/ + (double) (this.positiveExamples.size() + this.negativeExamples.size()); + + if (this.getCurrentlyOveralMaxCompleteness() == 1) + logger.info("Learning finishes in: " + this.miliLearningTime + "ms, with: " + + partialDefinitions.size() + " definitions"); + else if (this.isTimeout()) { + logger.info("Learning timeout in " + this.maxExecutionTimeInSeconds + + "s. Overall completeness: " + + df.format(this.getCurrentlyOveralMaxCompleteness()) + ", accuracy: " + + df.format(acc)); + + logger.info("Uncovered positive examples left " + + this.uncoveredPositiveExamples.size() + + " - " + + ParCELStringUtilities.replaceString( + this.uncoveredPositiveExamples.toString(), this.baseURI, + this.prefix)); + } else { + logger.info("Learning is manually terminated at " + this.miliLearningTime + + "ms. Overall completeness: " + + df.format(this.getCurrentlyOveralMaxCompleteness())); + logger.info("Uncovered positive examples left " + + this.uncoveredPositiveExamples.size() + + " - " + + ParCELStringUtilities.replaceString( + this.uncoveredPositiveExamples.toString(), this.baseURI, + this.prefix)); + } + + logger.info("Total descriptions generated: " + allDescriptions.size() + + ", best description length: " + getCurrentlyBestDescriptionLength() + + ", max expansion length: " + getMaximumHorizontalExpansion()); + + logger.info("Compacted partial definitions:"); + TreeSet compactedDefinitions = (TreeSet) this + .getReducedPartialDefinition(); + this.noOfCompactedPartialDefinition = compactedDefinitions.size(); + int count = 1; + for (ParCELExtraNode def : compactedDefinitions) { + int tpTest = learningProblem instanceof ParCELPosNegLP + ? ((ParCELPosNegLP) learningProblem).getNumberCoveredPositiveTestExamples(def.getDescription()) + : 0; + + logger.info(count++ + ". " + + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + + ", accuracy: " + df.format(def.getAccuracy()) + " / " + computeTestAccuracy(def.getDescription()) + + ", coverage: " + def.getCoveredPositiveExamples().size() + " / " + tpTest + ")"); + + // print out the learning tree + /* + * if (logger.isDebugEnabled()) { OENode parent = def.getParent(); while (parent + * != null) { logger.debug(" <-- " + + * parent.getDescription().toManchesterSyntaxString(baseURI, prefix)); // print + * out the children nodes List children = parent.getChildren(); for + * (OENode child : children) logger.debug(" --> " + + * child.getDescription().toManchesterSyntaxString(baseURI, prefix)); parent = + * parent.getParent(); } } + */ + + } + + printBestConceptsTimesAndAccuracies(); + } + } + + } + + //create a new task given a PDLLNode + private void createNewTask(ParCELNode nodeToProcess) { + workerPool.execute(new ParCELWorker(this, this.refinementOperatorPool, + (ParCELPosNegLP) learningProblem, nodeToProcess, "ParCELTask-" + (noOfTask++))); + } + + /** + * ============================================================================================ + * Get the overall completeness of all partial definition found + * + * @return Overall completeness so far + */ + public double getCurrentlyOveralMaxCompleteness() { + return 1 - (uncoveredPositiveExamples.size() / (double) positiveExamples.size()); + } + + // methods related to the compactness: get compact definition, set compactor + public SortedSet getReducedPartialDefinition(ParCELReducer reducer) { + return reducer.reduce(partialDefinitions, positiveExamples, + uncoveredPositiveExamples.size()); + } + + public SortedSet getReducedPartialDefinition() { + return this.getReducedPartialDefinition(this.reducer); + } + + public void setCompactor(ParCELReducer newCompactor) { + this.reducer = newCompactor; + } + + + // =============== MBean section ===================== + /* + public int getActiveCount() { + return this.workerPool.getActiveCount(); + } + + public long getCompleteTaskCount() { + return this.workerPool.getCompletedTaskCount(); + } + + public long getTaskCount() { + return this.workerPool.getTaskCount(); + } + + public boolean isTerminiated() { + return this.workerPool.isTerminated(); + } + + public boolean isShutdown() { + return this.workerPool.isShutdown(); + } + + public int getUncoveredPositiveExamples() { + return this.noOfUncoveredPositiveExamples; + } + */ +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearnerMBean.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearnerMBean.java new file mode 100644 index 0000000000..c3adb7772a --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearnerMBean.java @@ -0,0 +1,18 @@ +package org.dllearner.algorithms.parcel; + + +/** + * Interface for a ParCELearner Bean + * + * @author An C. Tran + * + */ +public interface ParCELearnerMBean { + + long getTotalDescriptions(); + int getCurrentlyBestDescriptionLength(); + double getCurrentlyBestAccuracy(); + int getWorkerPoolSize(); + int getSearchTreeSize(); + int getCurrentlyMaxExpansion(); +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/celoe/CELOEPartial.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/celoe/CELOEPartial.java new file mode 100644 index 0000000000..7ada3d7ae2 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/celoe/CELOEPartial.java @@ -0,0 +1,1290 @@ +/** + * Copyright (C) 2007 - 2016, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.dllearner.algorithms.parcel.celoe; + +import java.io.File; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import com.google.common.collect.Sets; +import com.jamonapi.Monitor; +import com.jamonapi.MonitorFactory; +import org.dllearner.algorithms.celoe.OEHeuristicRuntime; +import org.dllearner.algorithms.celoe.OENode; +import org.dllearner.core.*; +import org.dllearner.core.config.ConfigOption; +import org.dllearner.core.owl.ClassHierarchy; +import org.dllearner.core.owl.DatatypePropertyHierarchy; +import org.dllearner.core.owl.ObjectPropertyHierarchy; +import org.dllearner.kb.OWLAPIOntology; +import org.dllearner.learningproblems.ClassAsInstanceLearningProblem; +import org.dllearner.learningproblems.ClassLearningProblem; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.learningproblems.PosOnlyLP; +import org.dllearner.reasoning.ClosedWorldReasoner; +import org.dllearner.reasoning.OWLAPIReasoner; +import org.dllearner.reasoning.ReasonerImplementation; +import org.dllearner.reasoning.SPARQLReasoner; +import org.dllearner.refinementoperators.*; +import org.dllearner.utilities.*; +import org.dllearner.utilities.datastructures.SearchTree; +import org.dllearner.utilities.owl.*; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl; +import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; + +/** + * The CELOE (Class Expression Learner for Ontology Engineering) algorithm. + * It adapts and extends the standard supervised learning algorithm for the + * ontology engineering use case. + * + * @author Jens Lehmann + * + */ +@SuppressWarnings("CloneDoesntCallSuperClone") +@ComponentAnn(name="CELOEP", shortName="celoep", version=1.0, description="CELOE is an adapted and extended version of the OCEL algorithm applied for the ontology engineering use case. See http://jens-lehmann.org/files/2011/celoe.pdf for reference.") +public class CELOEPartial extends AbstractCELA implements Cloneable{ + + private static final Logger logger = LoggerFactory.getLogger(CELOEPartial.class); + private static final Marker sparql_debug = MarkerFactory.getMarker("SD"); + + private boolean isRunning = false; + private boolean stop = false; + +// private OEHeuristicStable heuristicStable = new OEHeuristicStable(); +// private OEHeuristicRuntime heuristicRuntime = new OEHeuristicRuntime(); + + @ConfigOption(description = "the refinement operator instance to use") + private LengthLimitedRefinementOperator operator; + + private SearchTree searchTree; + @ConfigOption(defaultValue="celoe_heuristic") + private AbstractHeuristic heuristic; // = new OEHeuristicRuntime(); + // the class with which we start the refinement process + @ConfigOption(defaultValue = "owl:Thing", + description = "You can specify a start class for the algorithm. To do this, you have to use Manchester OWL syntax either with full IRIs or prefixed IRIs.", + exampleValue = "ex:Male or http://example.org/ontology/Female") + private OWLClassExpression startClass; + + // all descriptions in the search tree plus those which were too weak (for fast redundancy check) + private TreeSet descriptions; + + + // if true, then each solution is evaluated exactly instead of approximately + // private boolean exactBestDescriptionEvaluation = false; + @ConfigOption(defaultValue="false", description="Use this if you are interested in only one suggestion and your learning problem has many (more than 1000) examples.") + private boolean singleSuggestionMode; + private OWLClassExpression bestDescription; + private double bestAccuracy = Double.MIN_VALUE; + + private OWLClass classToDescribe; + // examples are either 1.) instances of the class to describe 2.) positive examples + // 3.) union of pos.+neg. examples depending on the learning problem at hand + private Set examples; + + // CELOE was originally created for learning classes in ontologies, but also + // works for other learning problem types + private boolean isClassLearningProblem; + private boolean isEquivalenceProblem; + + // important parameters (non-config options but internal) + private double noise; + + private boolean filterFollowsFromKB = false; + + // less important parameters + // forces that one solution cannot be subexpression of another expression; this option is useful to get diversity + // but it can also suppress quite useful expressions + private boolean forceMutualDifference = false; + + // utility variables + + // statistical variables + private int expressionTests = 0; + private int minHorizExp = 1; + private int maxHorizExp = 0; + private long totalRuntimeNs = 0; + + // TODO: turn those into config options + + + // important: do not initialise those with empty sets + // null = no settings for allowance / ignorance + // empty set = allow / ignore nothing (it is often not desired to allow no class!) + @ConfigOption(defaultValue="false", description="specifies whether to write a search tree") + private boolean writeSearchTree = false; + + @ConfigOption(defaultValue="log/searchTree.txt", description="file to use for the search tree") + private String searchTreeFile = "log/searchTree.txt"; + + @ConfigOption(defaultValue="false", description="specifies whether to replace the search tree in the log file after each run or append the new search tree") + private boolean replaceSearchTree = false; + + @ConfigOption(defaultValue="10", description="Sets the maximum number of results one is interested in. (Setting this to a lower value may increase performance as the learning algorithm has to store/evaluate/beautify less descriptions).") + private int maxNrOfResults = 10; + + @ConfigOption(defaultValue="0.0", description="the (approximated) percentage of noise within the examples") + private double noisePercentage = 0.0; + + @ConfigOption(defaultValue="false", description="If true, then the results will not contain suggestions, which already follow logically from the knowledge base. Be careful, since this requires a potentially expensive consistency check for candidate solutions.") + private boolean filterDescriptionsFollowingFromKB = false; + + @ConfigOption(defaultValue="false", description="If true, the algorithm tries to find a good starting point close to an existing definition/super class of the given class in the knowledge base.") + private boolean reuseExistingDescription = false; + + @ConfigOption(defaultValue="0", description="The maximum number of candidate hypothesis the algorithm is allowed to test (0 = no limit). The algorithm will stop afterwards. (The real number of tests can be slightly higher, because this criterion usually won't be checked after each single test.)") + private int maxClassExpressionTests = 0; + + @ConfigOption(defaultValue="0", description = "The maximum number of candidate hypothesis the algorithm is allowed after an improvement in accuracy (0 = no limit). The algorithm will stop afterwards. (The real number of tests can be slightly higher, because this criterion usually won't be checked after each single test.)") + private int maxClassExpressionTestsAfterImprovement = 0; + + @ConfigOption(defaultValue = "0", description = "maximum execution of the algorithm in seconds after last improvement") + private int maxExecutionTimeInSecondsAfterImprovement = 0; + + @ConfigOption(defaultValue="false", description="specifies whether to terminate when noise criterion is met") + private boolean terminateOnNoiseReached = false; + + @ConfigOption(defaultValue="7", description="maximum depth of description") + private double maxDepth = 7; + + @ConfigOption(defaultValue="false", description="algorithm will terminate immediately when a correct definition is found") + private boolean stopOnFirstDefinition = false; + + private int expressionTestCountLastImprovement; + + + @SuppressWarnings("unused") + private long timeLastImprovement = 0; + @ConfigOption(defaultValue = "false", description = "whether to try and refine solutions which already have accuracy value of 1") + private boolean expandAccuracy100Nodes = false; + private double currentHighestAccuracy; + + // option to keep track of best score during algorithm run + private boolean keepTrackOfBestScore = false; + private SortedMap runtimeVsBestScore = new TreeMap<>(); + + + // PARCEL stuff + private int posSize, negSize; + private HashSet partialDefinitions; + private HashSet unCoveredPos; + private boolean allPosCovered = false; + private long searchtreeSizeForBestDescription = 0; + private long learningtimeForBestDescription = 0; + + public CELOEPartial() {} + + public CELOEPartial(CELOEPartial celoe){ + setReasoner(celoe.reasoner); + setLearningProblem(celoe.learningProblem); + + setAllowedConcepts(celoe.getAllowedConcepts()); + setAllowedObjectProperties(celoe.getAllowedObjectProperties()); + setAllowedDataProperties(celoe.getAllowedDataProperties()); + + setIgnoredConcepts(celoe.ignoredConcepts); + setIgnoredObjectProperties(celoe.getIgnoredObjectProperties()); + setIgnoredDataProperties(celoe.getIgnoredDataProperties()); + + setExpandAccuracy100Nodes(celoe.expandAccuracy100Nodes); + setFilterDescriptionsFollowingFromKB(celoe.filterDescriptionsFollowingFromKB); + setHeuristic(celoe.heuristic); + + setMaxClassExpressionTests(celoe.maxClassExpressionTests); + setMaxClassExpressionTestsAfterImprovement(celoe.maxClassExpressionTestsAfterImprovement); + setMaxDepth(celoe.maxDepth); + setMaxExecutionTimeInSeconds(celoe.getMaxExecutionTimeInSeconds()); + setMaxExecutionTimeInSecondsAfterImprovement(celoe.maxExecutionTimeInSecondsAfterImprovement); + setMaxNrOfResults(celoe.maxNrOfResults); + setNoisePercentage(celoe.noisePercentage); + + LengthLimitedRefinementOperator op = new RhoDRDown((RhoDRDown)celoe.operator); + try { + op.init(); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + setOperator(op); + + + setReuseExistingDescription(celoe.reuseExistingDescription); + setSingleSuggestionMode(celoe.singleSuggestionMode); + setStartClass(celoe.startClass); + setStopOnFirstDefinition(celoe.stopOnFirstDefinition); + setTerminateOnNoiseReached(celoe.terminateOnNoiseReached); + setUseMinimizer(celoe.isUseMinimizer()); + + setWriteSearchTree(celoe.writeSearchTree); + setReplaceSearchTree(celoe.replaceSearchTree); + } + + public CELOEPartial(AbstractClassExpressionLearningProblem problem, AbstractReasonerComponent reasoner) { + super(problem, reasoner); + } + + public static Collection> supportedLearningProblems() { + Collection> problems = new LinkedList<>(); + problems.add(AbstractClassExpressionLearningProblem.class); + return problems; + } + + @Override + public void init() throws ComponentInitException { + baseURI = reasoner.getBaseURI(); + prefixes = reasoner.getPrefixes(); + + if(maxExecutionTimeInSeconds != 0 && maxExecutionTimeInSecondsAfterImprovement != 0) { + maxExecutionTimeInSeconds = Math.min(maxExecutionTimeInSeconds, maxExecutionTimeInSecondsAfterImprovement); + } + + // TODO add comment + ClassHierarchy classHierarchy = initClassHierarchy(); + ObjectPropertyHierarchy objectPropertyHierarchy = initObjectPropertyHierarchy(); + DatatypePropertyHierarchy datatypePropertyHierarchy = initDataPropertyHierarchy(); + + // if no one injected a heuristic, we use a default one + if(heuristic == null) { + heuristic = new OEHeuristicRuntime(); + heuristic.init(); + } + + minimizer = new OWLClassExpressionMinimizer(dataFactory, reasoner); + + if (writeSearchTree) { + File f = new File(searchTreeFile); + if (f.getParentFile() != null) { + f.getParentFile().mkdirs(); + } + Files.clearFile(f); + } + + // start at owl:Thing by default + startClass = OWLAPIUtils.classExpressionPropertyExpanderChecked(this.startClass, reasoner, dataFactory, this::computeStartClass, logger); + + bestEvaluatedDescriptions = new EvaluatedDescriptionSet(maxNrOfResults); + + isClassLearningProblem = (learningProblem instanceof ClassLearningProblem); + + // we put important parameters in class variables + noise = noisePercentage/100d; + + // (filterFollowsFromKB is automatically set to false if the problem + // is not a class learning problem + filterFollowsFromKB = filterDescriptionsFollowingFromKB && isClassLearningProblem; + + // actions specific to ontology engineering + if(isClassLearningProblem) { + ClassLearningProblem problem = (ClassLearningProblem) learningProblem; + classToDescribe = problem.getClassToDescribe(); + isEquivalenceProblem = problem.isEquivalenceProblem(); + + examples = reasoner.getIndividuals(classToDescribe); + } else if(learningProblem instanceof PosOnlyLP) { + examples = ((PosOnlyLP)learningProblem).getPositiveExamples(); + } else if(learningProblem instanceof PosNegLP) { + examples = Sets.union(((PosNegLP)learningProblem).getPositiveExamples(),((PosNegLP)learningProblem).getNegativeExamples()); + posSize = (((PosNegLP)learningProblem).getPositiveExamples()).size(); + negSize = (((PosNegLP)learningProblem).getNegativeExamples()).size(); + } + + // create a refinement operator and pass all configuration + // variables to it + if (operator == null) { + // we use a default operator and inject the class hierarchy for now + operator = new RhoDRDown(); + ((CustomStartRefinementOperator) operator).setStartClass(startClass); + ((ReasoningBasedRefinementOperator) operator).setReasoner(reasoner); + } + if (operator instanceof CustomHierarchyRefinementOperator) { + ((CustomHierarchyRefinementOperator) operator).setClassHierarchy(classHierarchy); + ((CustomHierarchyRefinementOperator) operator).setObjectPropertyHierarchy(objectPropertyHierarchy); + ((CustomHierarchyRefinementOperator) operator).setDataPropertyHierarchy(datatypePropertyHierarchy); + } + + if (!((AbstractRefinementOperator) operator).isInitialized()) + operator.init(); + + initialized = true; + } + + @Override + public void start() { + partialDefinitions = new HashSet<>(); + unCoveredPos = new HashSet<>(); + + stop = false; + isRunning = true; + reset(); + nanoStartTime = System.nanoTime(); + + unCoveredPos.addAll(((PosNegLP)learningProblem).getPositiveExamples()); + allPosCovered = (unCoveredPos.size() == 0); + + currentHighestAccuracy = 0.0; + OENode nextNode; + + logger.info("start class:" + startClass); + addNode(startClass, null); + + while (!terminationCriteriaSatisfied()) { + showIfBetterSolutionsFound(); + + // chose best node according to heuristics + nextNode = getNextNodeToExpand(); + int horizExp = nextNode.getHorizontalExpansion(); + + // apply refinement operator + TreeSet refinements = refineNode(nextNode); + + while(!refinements.isEmpty() && !terminationCriteriaSatisfied()) { + // pick element from set + OWLClassExpression refinement = refinements.pollFirst(); + + // get length of class expression + int length = OWLClassExpressionUtils.getLength(refinement); + + // we ignore all refinements with lower length and too high depth + // (this also avoids duplicate node children) + if(length >= horizExp && OWLClassExpressionUtils.getDepth(refinement) <= maxDepth) { + // add node to search tree + addNode(refinement, nextNode); + } + } + + showIfBetterSolutionsFound(); + + // update the global min and max horizontal expansion values + updateMinMaxHorizExp(nextNode); + + // write the search tree (if configured) + if (writeSearchTree) { + writeSearchTree(refinements); + } + } + + if(singleSuggestionMode) { + bestEvaluatedDescriptions.add(bestDescription, bestAccuracy, learningProblem); + } + + // print some stats + printAlgorithmRunStats(); + + // print solution(s) + logger.info("solutions:\n" + getSolutionString()); + + isRunning = false; + } + + /* + * Compute the start class in the search space from which the refinement will start. + * We use the intersection of super classes for definitions (since it needs to + * capture all instances), but owl:Thing for learning subclasses (since it is + * superfluous to add super classes in this case) + */ + private OWLClassExpression computeStartClass() { + OWLClassExpression startClass = dataFactory.getOWLThing(); + + if(isClassLearningProblem) { + if(isEquivalenceProblem) { + Set existingDefinitions = reasoner.getAssertedDefinitions(classToDescribe); + if(reuseExistingDescription && (existingDefinitions.size() > 0)) { + // the existing definition is reused, which in the simplest case means to + // use it as a start class or, if it is already too specific, generalise it + + // pick the longest existing definition as candidate + OWLClassExpression existingDefinition = null; + int highestLength = 0; + for(OWLClassExpression exDef : existingDefinitions) { + if(OWLClassExpressionUtils.getLength(exDef) > highestLength) { + existingDefinition = exDef; + highestLength = OWLClassExpressionUtils.getLength(exDef); + } + } + + LinkedList startClassCandidates = new LinkedList<>(); + startClassCandidates.add(existingDefinition); + // hack for RhoDRDown + if(operator instanceof RhoDRDown) { + ((RhoDRDown)operator).setDropDisjuncts(true); + } + LengthLimitedRefinementOperator upwardOperator = new OperatorInverter(operator); + + // use upward refinement until we find an appropriate start class + boolean startClassFound = false; + OWLClassExpression candidate; + do { + candidate = startClassCandidates.pollFirst(); + if(((ClassLearningProblem)learningProblem).getRecall(candidate)<1.0) { + // add upward refinements to list + Set refinements = upwardOperator.refine(candidate, OWLClassExpressionUtils.getLength(candidate)); +// System.out.println("ref: " + refinements); + LinkedList refinementList = new LinkedList<>(refinements); +// Collections.reverse(refinementList); +// System.out.println("list: " + refinementList); + startClassCandidates.addAll(refinementList); +// System.out.println("candidates: " + startClassCandidates); + } else { + startClassFound = true; + } + } while(!startClassFound); + startClass = candidate; + + if(startClass.equals(existingDefinition)) { + logger.info("Reusing existing class expression " + OWLAPIRenderers.toManchesterOWLSyntax(startClass) + " as start class for learning algorithm."); + } else { + logger.info("Generalised existing class expression " + OWLAPIRenderers.toManchesterOWLSyntax(existingDefinition) + " to " + OWLAPIRenderers.toManchesterOWLSyntax(startClass) + ", which is used as start class for the learning algorithm."); + } + + if(operator instanceof RhoDRDown) { + ((RhoDRDown)operator).setDropDisjuncts(false); + } + + } else { + Set superClasses = reasoner.getClassHierarchy().getSuperClasses(classToDescribe, true); + if(superClasses.size() > 1) { + startClass = dataFactory.getOWLObjectIntersectionOf(superClasses); + } else if(superClasses.size() == 1){ + startClass = (OWLClassExpression) superClasses.toArray()[0]; + } else { + startClass = dataFactory.getOWLThing(); + logger.warn(classToDescribe + " is equivalent to owl:Thing. Usually, it is not " + + "sensible to learn a class expression in this case."); + } + } + } + } + return startClass; + } + + private OENode getNextNodeToExpand() { + // we expand the best node of those, which have not achieved 100% accuracy + // already and have a horizontal expansion equal to their length + // (rationale: further extension is likely to add irrelevant syntactical constructs) + Iterator it = searchTree.descendingIterator(); + if (logger.isTraceEnabled()) { + for (OENode N:searchTree.getNodeSet()) { + logger.trace(sparql_debug,"`getnext:"+N); + } + } + + while(it.hasNext()) { + OENode node = it.next(); + logger.trace(sparql_debug,"``"+node+node.getAccuracy()); + if (isExpandAccuracy100Nodes() && node.getHorizontalExpansion() < OWLClassExpressionUtils.getLength(node.getDescription())) { + return node; + } else { + if(node.getAccuracy() < 1.0 || node.getHorizontalExpansion() < OWLClassExpressionUtils.getLength(node.getDescription())) { + return node; + } + } + } + + // this should practically never be called, since for any reasonable learning + // task, we will always have at least one node with less than 100% accuracy + throw new RuntimeException("CELOE could not find any node with lesser accuracy."); + } + + // expand node horizontically + private TreeSet refineNode(OENode node) { + logger.trace(sparql_debug,"REFINE NODE " + node); + MonitorFactory.getTimeMonitor("refineNode").start(); + // we have to remove and add the node since its heuristic evaluation changes through the expansion + // (you *must not* include any criteria in the heuristic which are modified outside of this method, + // otherwise you may see rarely occurring but critical false ordering in the nodes set) + searchTree.updatePrepare(node); + int horizExp = node.getHorizontalExpansion(); + TreeSet refinements = (TreeSet) operator.refine(node.getDescription(), horizExp); +// System.out.println("refinements: " + refinements); + node.incHorizontalExpansion(); + node.setRefinementCount(refinements.size()); +// System.out.println("refined node: " + node); + searchTree.updateDone(node); + MonitorFactory.getTimeMonitor("refineNode").stop(); + return refinements; + } + + /** + * Add node to search tree if it is not too weak. + * @return TRUE if node was added and FALSE otherwise + */ + private boolean addNode(OWLClassExpression description, OENode parentNode) { + String sparql_debug_out = ""; + if (logger.isTraceEnabled()) sparql_debug_out = "DESC: " + description; + MonitorFactory.getTimeMonitor("addNode").start(); + + // redundancy check (return if redundant) + boolean nonRedundant = descriptions.add(description); + if(!nonRedundant) { + logger.trace(sparql_debug, sparql_debug_out + "REDUNDANT"); + return false; + } + + // check whether the class expression is allowed + if(!isDescriptionAllowed(description, parentNode)) { + logger.trace(sparql_debug, sparql_debug_out + "NOT ALLOWED"); + return false; + } + + // quality of class expression (return if too weak) + Monitor mon = MonitorFactory.start("lp"); + logger.trace(sparql_debug, sparql_debug_out); + double accuracy = learningProblem.getAccuracyOrTooWeak(description, noise); + logger.trace(sparql_debug, "`acc:"+accuracy); + mon.stop(); + + // issue a warning if accuracy is not between 0 and 1 or -1 (too weak) + if(accuracy > 1.0 || (accuracy < 0.0 && accuracy != -1)) { + throw new RuntimeException("Invalid accuracy value " + accuracy + " for class expression " + description + + ". This could be caused by a bug in the heuristic measure and should be reported to the DL-Learner bug tracker."); + } + + //if the noise is enable and the new description is correct (i.e. correct + noise description) + if (accuracy >= 1) { + //System.out.println("** Partial definition found: " + description.toManchesterSyntaxString(baseURI, prefixes) + + // ", acc:" + dfPercent.format(accuracy-1)); + if (accuracy > 1) + accuracy -= 1; + + double coverage = (accuracy * (posSize + negSize) - negSize)/posSize; + partialDefinitions.add(new PartialDefinition(description, coverage)); + + //update the uncovered positive examples list + Set coveredPosTmp = new HashSet<>(); + for (OWLIndividual ind : unCoveredPos) { + if (reasoner.hasType(description, ind)) + coveredPosTmp.add(ind); + } + + if (coveredPosTmp.size() > 0) { + unCoveredPos.removeAll(coveredPosTmp); + allPosCovered = (unCoveredPos.size() == 0); + } + } + + + expressionTests++; + + // return FALSE if 'too weak' + if(accuracy == -1) { + return false; + } + + OENode node = new OENode(description, accuracy); + searchTree.addNode(parentNode, node); + + // in some cases (e.g. mutation) fully evaluating even a single class expression is too expensive + // due to the high number of examples -- so we just stick to the approximate accuracy + if(singleSuggestionMode) { + if(accuracy > bestAccuracy) { + bestAccuracy = accuracy; + bestDescription = description; + logger.info("more accurate (" + dfPercent.format(bestAccuracy) + ") class expression found: " + descriptionToString(bestDescription)); // + getTemporaryString(bestDescription)); + } + return true; + } + + // maybe add to best descriptions (method keeps set size fixed); + // we need to make sure that this does not get called more often than + // necessary since rewriting is expensive + boolean isCandidate = !bestEvaluatedDescriptions.isFull(); + if(!isCandidate) { + EvaluatedDescription worst = bestEvaluatedDescriptions.getWorst(); + double accThreshold = worst.getAccuracy(); + isCandidate = + (accuracy > accThreshold || + (accuracy >= accThreshold && OWLClassExpressionUtils.getLength(description) < worst.getDescriptionLength())); + } + + if(isCandidate) { + OWLClassExpression niceDescription = rewrite(node.getExpression()); + + if(niceDescription.equals(classToDescribe)) { + return false; + } + + if(!isDescriptionAllowed(niceDescription, node)) { + return false; + } + + // another test: none of the other suggested descriptions should be + // a subdescription of this one unless accuracy is different + // => comment: on the one hand, this appears to be too strict, because once A is a solution then everything containing + // A is not a candidate; on the other hand this suppresses many meaningless extensions of A + boolean shorterDescriptionExists = false; + if(forceMutualDifference) { + for(EvaluatedDescription ed : bestEvaluatedDescriptions.getSet()) { + if(Math.abs(ed.getAccuracy()-accuracy) <= 0.00001 && ConceptTransformation.isSubdescription(niceDescription, ed.getDescription())) { +// System.out.println("shorter: " + ed.getDescription()); + shorterDescriptionExists = true; + break; + } + } + } + +// System.out.println("shorter description? " + shorterDescriptionExists + " nice: " + niceDescription); + + if(!shorterDescriptionExists) { + if(!filterFollowsFromKB || !((ClassLearningProblem)learningProblem).followsFromKB(niceDescription)) { +// System.out.println(node + "->" + niceDescription); + bestEvaluatedDescriptions.add(niceDescription, accuracy, learningProblem); +// System.out.println("acc: " + accuracy); +// System.out.println(bestEvaluatedDescriptions); + } + } + +// bestEvaluatedDescriptions.add(node.getDescription(), accuracy, learningProblem); + +// System.out.println(bestEvaluatedDescriptions.getSet().size()); + } + + return true; + } + + // checks whether the class expression is allowed + private boolean isDescriptionAllowed(OWLClassExpression description, OENode parentNode) { + if(isClassLearningProblem) { + if(isEquivalenceProblem) { + // the class to learn must not appear on the outermost property level + if(occursOnFirstLevel(description, classToDescribe)) { + return false; + } + if(occursOnSecondLevel(description, classToDescribe)) { + return false; + } + } else { + // none of the superclasses of the class to learn must appear on the + // outermost property level + TreeSet toTest = new TreeSet<>(); + toTest.add(classToDescribe); + while(!toTest.isEmpty()) { + OWLClassExpression d = toTest.pollFirst(); + if(occursOnFirstLevel(description, d)) { + return false; + } + toTest.addAll(reasoner.getClassHierarchy().getSuperClasses(d)); + } + } + } else if (learningProblem instanceof ClassAsInstanceLearningProblem) { + return true; + } + + // perform forall sanity tests + if (parentNode != null && + (ConceptTransformation.getForallOccurences(description) > ConceptTransformation.getForallOccurences(parentNode.getDescription()))) { + // we have an additional \forall construct, so we now fetch the contexts + // in which it occurs + SortedSet contexts = ConceptTransformation.getForallContexts(description); + SortedSet parentContexts = ConceptTransformation.getForallContexts(parentNode.getDescription()); + contexts.removeAll(parentContexts); +// System.out.println("parent description: " + parentNode.getDescription()); +// System.out.println("description: " + description); +// System.out.println("contexts: " + contexts); + // we now have to perform sanity checks: if \forall is used, then there + // should be at least on class instance which has a filler at the given context + for(PropertyContext context : contexts) { + // transform [r,s] to \exists r.\exists s.\top + OWLClassExpression existentialContext = context.toExistentialContext(); + boolean fillerFound = false; + if(reasoner instanceof SPARQLReasoner) { + SortedSet individuals = reasoner.getIndividuals(existentialContext); + fillerFound = !Sets.intersection(individuals, examples).isEmpty(); + } else { + for(OWLIndividual instance : examples) { + if(reasoner.hasType(existentialContext, instance)) { + fillerFound = true; + break; + } + } + } + + // if we do not find a filler, this means that putting \forall at + // that position is not meaningful + if(!fillerFound) { + return false; + } + } + } + + // we do not want to have negations of sibling classes on the outermost level + // (they are expressed more naturally by saying that the siblings are disjoint, + // so it is reasonable not to include them in solutions) +// Set siblingClasses = reasoner.getClassHierarchy().getSiblingClasses(classToDescribe); +// for now, we just disable negation + + return true; + } + + // determine whether a named class occurs on the outermost level, i.e. property depth 0 + // (it can still be at higher depth, e.g. if intersections are nested in unions) + private boolean occursOnFirstLevel(OWLClassExpression description, OWLClassExpression cls) { + return !cls.isOWLThing() && (description instanceof OWLNaryBooleanClassExpression && ((OWLNaryBooleanClassExpression) description).getOperands().contains(cls)); +// return description.containsConjunct(cls) || +// (description instanceof OWLObjectUnionOf && ((OWLObjectUnionOf) description).getOperands().contains(cls)); + } + + // determine whether a named class occurs on the outermost level, i.e. property depth 0 + // (it can still be at higher depth, e.g. if intersections are nested in unions) + private boolean occursOnSecondLevel(OWLClassExpression description, OWLClassExpression cls) { +// SortedSet superClasses = reasoner.getSuperClasses(cls); +// if(description instanceof OWLObjectIntersectionOf) { +// List operands = ((OWLObjectIntersectionOf) description).getOperandsAsList(); +// +// for (OWLClassExpression op : operands) { +// if(superClasses.contains(op) || +// (op instanceof OWLObjectUnionOf && !Sets.intersection(((OWLObjectUnionOf)op).getOperands(),superClasses).isEmpty())) { +// for (OWLClassExpression op2 : operands) { +// if((op2 instanceof OWLObjectUnionOf && ((OWLObjectUnionOf)op2).getOperands().contains(cls))) { +// return true; +// } +// } +// } +// } +// +// for (OWLClassExpression op1 : operands) { +// for (OWLClassExpression op2 : operands) { +// if(!op1.isAnonymous() && op2 instanceof OWLObjectUnionOf) { +// for (OWLClassExpression op3 : ((OWLObjectUnionOf)op2).getOperands()) { +// if(!op3.isAnonymous()) {// A AND B with Disj(A,B) +// if(reasoner.isDisjoint(op1.asOWLClass(), op3.asOWLClass())) { +// return true; +// } +// } else {// A AND NOT A +// if(op3 instanceof OWLObjectComplementOf && ((OWLObjectComplementOf)op3).getOperand().equals(op1)) { +// return true; +// } +// } +// } +// } +// } +// } +// } + + return false; + } + + private boolean terminationCriteriaSatisfied() { + return + stop || + (maxClassExpressionTestsAfterImprovement != 0 && (expressionTests - expressionTestCountLastImprovement >= maxClassExpressionTestsAfterImprovement)) || + (maxClassExpressionTests != 0 && (expressionTests >= maxClassExpressionTests)) || + (maxExecutionTimeInSecondsAfterImprovement != 0 && ((System.nanoTime() - nanoStartTime) >= (maxExecutionTimeInSecondsAfterImprovement* 1000000000L))) || + (maxExecutionTimeInSeconds != 0 && ((System.nanoTime() - nanoStartTime) >= (maxExecutionTimeInSeconds* 1000000000L))) || + (terminateOnNoiseReached && (100*getCurrentlyBestAccuracy()>=100-noisePercentage)) || + (stopOnFirstDefinition && (getCurrentlyBestAccuracy() >= 1)); + } + + private void reset() { + // set all values back to their default values (used for running + // the algorithm more than once) + searchTree = new SearchTree<>(heuristic); + descriptions = new TreeSet<>(); + bestEvaluatedDescriptions.getSet().clear(); + expressionTests = 0; + runtimeVsBestScore.clear(); + } + + private void printAlgorithmRunStats() { + if (stop) { + logger.info("Algorithm stopped ("+expressionTests+" descriptions tested). " + searchTree.size() + " nodes in the search tree.\n"); + } else { + totalRuntimeNs = System.nanoTime()-nanoStartTime; + logger.info("Algorithm terminated successfully (time: " + Helper.prettyPrintNanoSeconds(totalRuntimeNs) + ", "+expressionTests+" descriptions tested, " + searchTree.size() + " nodes in the search tree).\n"); + logger.info(reasoner.toString()); + } + } + + private void showIfBetterSolutionsFound() { + if(!singleSuggestionMode && bestEvaluatedDescriptions.getBestAccuracy() > currentHighestAccuracy) { + currentHighestAccuracy = bestEvaluatedDescriptions.getBestAccuracy(); + expressionTestCountLastImprovement = expressionTests; + timeLastImprovement = System.nanoTime(); + long durationInMillis = getCurrentRuntimeInMilliSeconds(); + String durationStr = getDurationAsString(durationInMillis); + + // track new best accuracy if enabled + if(keepTrackOfBestScore) { + runtimeVsBestScore.put(getCurrentRuntimeInMilliSeconds(), currentHighestAccuracy); + } + logger.info("more accurate (" + dfPercent.format(currentHighestAccuracy) + ") class expression found after " + durationStr + ": " + descriptionToString(bestEvaluatedDescriptions.getBest().getDescription())); + } + } + + private void writeSearchTree(TreeSet refinements) { + StringBuilder treeString = new StringBuilder("best node: ").append(bestEvaluatedDescriptions.getBest()).append("\n"); + if (refinements.size() > 1) { + treeString.append("all expanded nodes:\n"); + for (OWLClassExpression ref : refinements) { + treeString.append(" ").append(ref).append("\n"); + } + } + treeString.append(TreeUtils.toTreeString(searchTree)).append("\n"); + + // replace or append + if (replaceSearchTree) { + Files.createFile(new File(searchTreeFile), treeString.toString()); + } else { + Files.appendToFile(new File(searchTreeFile), treeString.toString()); + } + } + + private void updateMinMaxHorizExp(OENode node) { + int newHorizExp = node.getHorizontalExpansion(); + + // update maximum value + maxHorizExp = Math.max(maxHorizExp, newHorizExp); + + // we just expanded a node with minimum horizontal expansion; + // we need to check whether it was the last one + if(minHorizExp == newHorizExp - 1) { + + // the best accuracy that a node can achieve + double scoreThreshold = heuristic.getNodeScore(node) + 1 - node.getAccuracy(); + + for(OENode n : searchTree.descendingSet()) { + if(n != node) { + if(n.getHorizontalExpansion() == minHorizExp) { + // we can stop instantly when another node with min. + return; + } + if(heuristic.getNodeScore(n) < scoreThreshold) { + // we can stop traversing nodes when their score is too low + break; + } + } + } + + // inc. minimum since we found no other node which also has min. horiz. exp. + minHorizExp++; + +// System.out.println("minimum horizontal expansion is now " + minHorizExp); + } + } + + @Override + public OWLClassExpression getCurrentlyBestDescription() { + EvaluatedDescription ed = getCurrentlyBestEvaluatedDescription(); + return ed == null ? null : ed.getDescription(); + } + + @Override + public List getCurrentlyBestDescriptions() { + return bestEvaluatedDescriptions.toDescriptionList(); + } + + @Override + public EvaluatedDescription getCurrentlyBestEvaluatedDescription() { + return bestEvaluatedDescriptions.getBest(); + } + + @Override + public NavigableSet> getCurrentlyBestEvaluatedDescriptions() { + return bestEvaluatedDescriptions.getSet(); + } + + public double getCurrentlyBestAccuracy() { + return bestEvaluatedDescriptions.getBest().getAccuracy(); + } + + @Override + public boolean isRunning() { + return isRunning; + } + + @Override + public void stop() { + stop = true; + } + + public int getMaximumHorizontalExpansion() { + return maxHorizExp; + } + + public int getMinimumHorizontalExpansion() { + return minHorizExp; + } + + /** + * @return the expressionTests + */ + public int getClassExpressionTests() { + return expressionTests; + } + + public LengthLimitedRefinementOperator getOperator() { + return operator; + } + + @Autowired(required=false) + public void setOperator(LengthLimitedRefinementOperator operator) { + this.operator = operator; + } + + public OWLClassExpression getStartClass() { + return startClass; + } + + public void setStartClass(OWLClassExpression startClass) { + this.startClass = startClass; + } + + public boolean isWriteSearchTree() { + return writeSearchTree; + } + + public void setWriteSearchTree(boolean writeSearchTree) { + this.writeSearchTree = writeSearchTree; + } + + public String getSearchTreeFile() { + return searchTreeFile; + } + + public void setSearchTreeFile(String searchTreeFile) { + this.searchTreeFile = searchTreeFile; + } + + public int getMaxNrOfResults() { + return maxNrOfResults; + } + + public void setMaxNrOfResults(int maxNrOfResults) { + this.maxNrOfResults = maxNrOfResults; + } + + public double getNoisePercentage() { + return noisePercentage; + } + + public void setNoisePercentage(double noisePercentage) { + this.noisePercentage = noisePercentage; + } + + public boolean isFilterDescriptionsFollowingFromKB() { + return filterDescriptionsFollowingFromKB; + } + + public void setFilterDescriptionsFollowingFromKB(boolean filterDescriptionsFollowingFromKB) { + this.filterDescriptionsFollowingFromKB = filterDescriptionsFollowingFromKB; + } + + public boolean isReplaceSearchTree() { + return replaceSearchTree; + } + + public void setReplaceSearchTree(boolean replaceSearchTree) { + this.replaceSearchTree = replaceSearchTree; + } + + public boolean isTerminateOnNoiseReached() { + return terminateOnNoiseReached; + } + + public void setTerminateOnNoiseReached(boolean terminateOnNoiseReached) { + this.terminateOnNoiseReached = terminateOnNoiseReached; + } + + public boolean isReuseExistingDescription() { + return reuseExistingDescription; + } + + public void setReuseExistingDescription(boolean reuseExistingDescription) { + this.reuseExistingDescription = reuseExistingDescription; + } + + public AbstractHeuristic getHeuristic() { + return heuristic; + } + + @Autowired(required=false) + public void setHeuristic(AbstractHeuristic heuristic) { + this.heuristic = heuristic; + } + + public int getMaxExecutionTimeInSecondsAfterImprovement() { + return maxExecutionTimeInSecondsAfterImprovement; + } + + public void setMaxExecutionTimeInSecondsAfterImprovement( + int maxExecutionTimeInSecondsAfterImprovement) { + this.maxExecutionTimeInSecondsAfterImprovement = maxExecutionTimeInSecondsAfterImprovement; + } + + public boolean isSingleSuggestionMode() { + return singleSuggestionMode; + } + + public void setSingleSuggestionMode(boolean singleSuggestionMode) { + this.singleSuggestionMode = singleSuggestionMode; + } + + public int getMaxClassExpressionTests() { + return maxClassExpressionTests; + } + + public void setMaxClassExpressionTests(int maxClassExpressionTests) { + this.maxClassExpressionTests = maxClassExpressionTests; + } + + public int getMaxClassExpressionTestsAfterImprovement() { + return maxClassExpressionTestsAfterImprovement; + } + + public void setMaxClassExpressionTestsAfterImprovement( + int maxClassExpressionTestsAfterImprovement) { + this.maxClassExpressionTestsAfterImprovement = maxClassExpressionTestsAfterImprovement; + } + + public double getMaxDepth() { + return maxDepth; + } + + public void setMaxDepth(double maxDepth) { + this.maxDepth = maxDepth; + } + + public boolean isStopOnFirstDefinition() { + return stopOnFirstDefinition; + } + + public void setStopOnFirstDefinition(boolean stopOnFirstDefinition) { + this.stopOnFirstDefinition = stopOnFirstDefinition; + } + + public long getTotalRuntimeNs() { + return totalRuntimeNs; + } + + public HashSet getPartialDefinitions() { + return partialDefinitions; + } + + /** + * @return the expandAccuracy100Nodes + */ + public boolean isExpandAccuracy100Nodes() { + return expandAccuracy100Nodes; + } + + /** + * @param expandAccuracy100Nodes the expandAccuracy100Nodes to set + */ + public void setExpandAccuracy100Nodes(boolean expandAccuracy100Nodes) { + this.expandAccuracy100Nodes = expandAccuracy100Nodes; + } + + /** + * Whether to keep track of the best score during the algorithm run. + * + * @param keepTrackOfBestScore + */ + public void setKeepTrackOfBestScore(boolean keepTrackOfBestScore) { + this.keepTrackOfBestScore = keepTrackOfBestScore; + } + + /** + * @return a map containing time points at which a hypothesis with a better score than before has been found + */ + public SortedMap getRuntimeVsBestScore() { + return runtimeVsBestScore; + } + + /** + * Return a map that contains + *
    + *
  1. entries with time points at which a hypothesis with a better score than before has been found
  2. + *
  3. entries with the current best score for each defined interval time point
  4. + *
+ * + * @param ticksIntervalTimeValue at which time point the current best score is tracked periodically + * @param ticksIntervalTimeUnit the time unit of the periodic time point values + * + * @return the map + * + */ + public SortedMap getRuntimeVsBestScore(long ticksIntervalTimeValue, TimeUnit ticksIntervalTimeUnit) { + SortedMap map = new TreeMap<>(runtimeVsBestScore); + + // add entries for fixed time points if enabled + if(ticksIntervalTimeValue > 0) { + long ticksIntervalInMs = TimeUnit.MILLISECONDS.convert(ticksIntervalTimeValue, ticksIntervalTimeUnit); + + // add t = 0 -> 0 + map.put(0L, 0d); + + for(long t = ticksIntervalInMs; t <= TimeUnit.SECONDS.toMillis(maxExecutionTimeInSeconds); t += ticksIntervalInMs) { + // add value of last entry before this time point + map.put(t, map.get(runtimeVsBestScore.headMap(t).lastKey())); + } + + // add entry for t = totalRuntime + long totalRuntimeMs = Math.min(TimeUnit.SECONDS.toMillis(maxExecutionTimeInSeconds), TimeUnit.NANOSECONDS.toMillis(totalRuntimeNs)); + map.put(totalRuntimeMs, map.get(map.lastKey())); + } + + return map; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + @Override + public Object clone() throws CloneNotSupportedException { + return new CELOEPartial(this); + } + + public static class PartialDefinition { + private String id = ""; + private OWLClassExpression description; + + double coverage = 0.0; + List additionValue = new LinkedList<>(); + + private int maxAdditionalValue = 15; + + public PartialDefinition (OWLClassExpression des, double cov) { + this.description = des; + this.coverage = cov; + this.initialAdditionalValue(); + } + + public OWLClassExpression getDescription() { + return this.description; + } + + private void initialAdditionalValue() { + for (int i=0; i getAdditionValue() { + return this.additionValue; + } + */ + + public double getAdditionValue(int index) { + return this.additionValue.get(index); + } + + } + + public static void main(String[] args) throws Exception{ +// File file = new File("../examples/swore/swore.rdf"); +// OWLClass classToDescribe = new OWLClassImpl(IRI.create("http://ns.softwiki.de/req/CustomerRequirement")); + File file = new File("../examples/father.owl"); + OWLClass classToDescribe = new OWLClassImpl(IRI.create("http://example.com/father#male")); + + OWLOntology ontology = OWLManager.createOWLOntologyManager().loadOntologyFromOntologyDocument(file); + + AbstractKnowledgeSource ks = new OWLAPIOntology(ontology); + ks.init(); + + OWLAPIReasoner baseReasoner = new OWLAPIReasoner(ks); + baseReasoner.setReasonerImplementation(ReasonerImplementation.HERMIT); + baseReasoner.init(); + ClosedWorldReasoner rc = new ClosedWorldReasoner(ks); + rc.setReasonerComponent(baseReasoner); + rc.init(); + + ClassLearningProblem lp = new ClassLearningProblem(rc); +// lp.setEquivalence(false); + lp.setClassToDescribe(classToDescribe); + lp.init(); + + RhoDRDown op = new RhoDRDown(); + op.setReasoner(rc); + op.setUseNegation(false); + op.setUseHasValueConstructor(false); + op.setUseCardinalityRestrictions(true); + op.setUseExistsConstructor(true); + op.setUseAllConstructor(true); + op.init(); + + + + //(male ⊓ (∀ hasChild.⊤)) ⊔ (∃ hasChild.(∃ hasChild.male)) + OWLDataFactory df = new OWLDataFactoryImpl(); + OWLClass male = df.getOWLClass(IRI.create("http://example.com/father#male")); + OWLClassExpression ce = df.getOWLObjectIntersectionOf( + df.getOWLObjectUnionOf( + male, + df.getOWLObjectIntersectionOf( + male, male), + df.getOWLObjectSomeValuesFrom( + df.getOWLObjectProperty(IRI.create("http://example.com/father#hasChild")), + df.getOWLThing()) + ), + df.getOWLObjectAllValuesFrom( + df.getOWLObjectProperty(IRI.create("http://example.com/father#hasChild")), + df.getOWLThing() + ) + ); + System.out.println(ce); + OWLClassExpressionMinimizer min = new OWLClassExpressionMinimizer(df, rc); + ce = min.minimizeClone(ce); + System.out.println(ce); + + CELOEPartial alg = new CELOEPartial(lp, rc); + alg.setMaxExecutionTimeInSeconds(10); + alg.setOperator(op); + alg.setWriteSearchTree(true); + alg.setSearchTreeFile("log/search-tree.log"); + alg.setReplaceSearchTree(true); + alg.init(); + alg.setKeepTrackOfBestScore(true); + + alg.start(); + + SortedMap map = alg.getRuntimeVsBestScore(1, TimeUnit.SECONDS); + System.out.println(MapUtils.asTSV(map, "runtime", "best_score")); + + } + +} \ No newline at end of file diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCorrectnessGreedyReducer.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCorrectnessGreedyReducer.java new file mode 100644 index 0000000000..f5a3d26f9e --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCorrectnessGreedyReducer.java @@ -0,0 +1,94 @@ +package org.dllearner.algorithms.parcel.reducer; + +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELCompletenessComparator; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * This class implements "wise" coverage greedy strategy for compacting the partial definitions In + * this strategy, the partial definitions will be chosen based on their coverage. When a partial + * definition has been chosen, coverage of other partial definition will be recalculated + * + * @author An C. Tran + * + */ + +public class ParCELCorrectnessGreedyReducer { + + Logger logger = Logger.getLogger(this.getClass()); + + + /** + * Compact partial definition with noise allowed + * + * @param counterPartialDefinitions + * Set of partial definitions + * @param negativeExamples + * Set of positive examples (used to check whether partial definition is useful + * + * @return Subset of partial definitions that cover (positive examples \ uncovered positive + * examples) + */ + public SortedSet reduce(SortedSet counterPartialDefinitions, + Set negativeExamples) + { + + Set positiveExamplesTmp = new HashSet<>(negativeExamples); + + TreeSet reducedPartialDefinition = new TreeSet<>( + new ParCELCompletenessComparator()); + + if (counterPartialDefinitions.size() == 0) + return reducedPartialDefinition; + + synchronized (counterPartialDefinitions) { + Object[] partialDefs = counterPartialDefinitions.toArray(); + + // the highest accurate partial definition + // reducedPartialDefinition.add((PDLLExtraNode)partialDefs[0]); + // positiveExamplesTmp.removeAll(((PDLLExtraNode)partialDefs[0]).getCoveredPositiveExamples()); + + for (int i = 0; (positiveExamplesTmp.size() > 0) + && (i < counterPartialDefinitions.size()); i++) { + + // count the number of different positive examples covered + int counti = 0; + for (OWLIndividual indi : ((ParCELExtraNode) partialDefs[i]).getCoveredPositiveExamples()) { + if (positiveExamplesTmp.contains(indi)) + counti++; + } // count the number of different covered positive examples by i + + + for (int j = i + 1; j < counterPartialDefinitions.size(); j++) { + int countj = 0; + + for (OWLIndividual indj : ((ParCELExtraNode) partialDefs[j]).getCoveredPositiveExamples()) + if (positiveExamplesTmp.contains(indj)) + countj++; + + // swap the partial definition so that the "best" partial + // definition will be in the top + if (countj > counti) { + ParCELExtraNode tmp = (ParCELExtraNode) partialDefs[j]; + partialDefs[j] = partialDefs[i]; + partialDefs[i] = tmp; + counti = countj; + } + } + + reducedPartialDefinition.add((ParCELExtraNode) partialDefs[i]); + positiveExamplesTmp.removeAll(((ParCELExtraNode) partialDefs[i]) + .getCoveredPositiveExamples()); + } + } + + return reducedPartialDefinition; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCoverageGreedyReducer.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCoverageGreedyReducer.java new file mode 100644 index 0000000000..5f251d27e5 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELCoverageGreedyReducer.java @@ -0,0 +1,77 @@ +package org.dllearner.algorithms.parcel.reducer; + +import java.util.*; + +import org.dllearner.algorithms.parcel.ParCELCorrectnessComparator; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * This class implements a simple strategy for compacting the partial definition set In this + * strategy, the partial definition will be chosen based on their accuracy. The partial definition + * with the best accuracy will be chosen first and the rests will not be re-calculated before the + * next reduction + * + * @author An C. Tran + * + */ +public class ParCELCoverageGreedyReducer implements ParCELReducer { + + /** + * Compact partial definitions + * + * @param partialDefinitions + * Set of partial definitions + * @param positiveExamples + * Set of positive examples (used to check whether partial definition is useful + * + * @return Subset of partial definitions that cover all positive examples + */ + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples) { + return reduce(partialDefinitions, positiveExamples, 0); + } + + /** + * Compact partial definition with noise allowed + * + * @param partialDefinitions + * Set of partial definitions + * @param positiveExamples + * Set of positive examples (used to check whether partial definition is useful + * @param uncoveredPositiveExamples + * Number of uncovered positive examples allowed + * + * @return Subset of partial definitions that cover (positive examples \ uncovered positive + * examples) + */ + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples, int uncoveredPositiveExamples) { + + Set positiveExamplesTmp = new HashSet<>(positiveExamples); + + TreeSet minimisedPartialDefinition = new TreeSet<>( + new ParCELCorrectnessComparator()); + + Iterator partialDefinitionIterator = partialDefinitions.iterator(); + while ((positiveExamplesTmp.size() > uncoveredPositiveExamples) + && (partialDefinitionIterator.hasNext())) { + ParCELExtraNode node = partialDefinitionIterator.next(); + + int positiveExamplesRemoved = positiveExamplesTmp.size(); + positiveExamplesTmp.removeAll(node.getCoveredPositiveExamples()); + + positiveExamplesRemoved -= positiveExamplesTmp.size(); + + if (positiveExamplesRemoved > 0) { + node.setCorrectness(positiveExamplesRemoved); + minimisedPartialDefinition.add(node); + } + } + + return minimisedPartialDefinition; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELDefinitionLengthReducer.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELDefinitionLengthReducer.java new file mode 100644 index 0000000000..6ac993e651 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELDefinitionLengthReducer.java @@ -0,0 +1,57 @@ +package org.dllearner.algorithms.parcel.reducer; + +import java.util.*; + +import org.dllearner.algorithms.parcel.ParCELDefinitionGenerationTimeComparator; +import org.dllearner.algorithms.parcel.ParCELDefinitionLengthComparator; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Compact set of partial definitions using Definition Length Greedy Reduction strategy + * + * @author An C. Tran + * + */ +public class ParCELDefinitionLengthReducer implements ParCELReducer { + + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples) { + return reduce(partialDefinitions, positiveExamples, 0); + } + + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples, int uncoveredPositiveExamples) { + Set positiveExamplesTmp = new HashSet<>(positiveExamples); + + TreeSet newSortedPartialDefinitions = new TreeSet<>( + new ParCELDefinitionLengthComparator()); + synchronized (partialDefinitions) { + newSortedPartialDefinitions.addAll(partialDefinitions); + } + + TreeSet minimisedPartialDefinition = new TreeSet<>( + new ParCELDefinitionGenerationTimeComparator()); + + Iterator partialDefinitionIterator = newSortedPartialDefinitions.iterator(); + while ((positiveExamplesTmp.size() > uncoveredPositiveExamples) + && (partialDefinitionIterator.hasNext())) { + ParCELExtraNode node = partialDefinitionIterator.next(); + + int positiveExamplesRemoved = positiveExamplesTmp.size(); + positiveExamplesTmp.removeAll(node.getCoveredPositiveExamples()); + + positiveExamplesRemoved -= positiveExamplesTmp.size(); + + if (positiveExamplesRemoved > 0) { + node.setCorrectness(positiveExamplesRemoved); + minimisedPartialDefinition.add(node); + } + } + + return minimisedPartialDefinition; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELGenerationTimeReducer.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELGenerationTimeReducer.java new file mode 100644 index 0000000000..cee2dc6dc9 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELGenerationTimeReducer.java @@ -0,0 +1,60 @@ +package org.dllearner.algorithms.parcel.reducer; + +import java.util.*; + +import org.dllearner.algorithms.parcel.ParCELDefinitionGenerationTimeComparator; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Compact two a partial definitions using Generation Time Greedy strategy + * + * @author An C. Tran + * + */ + +public class ParCELGenerationTimeReducer implements ParCELReducer { + + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples) { + return reduce(partialDefinitions, positiveExamples, 0); + } + + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples, int uncoveredPositiveExamples) { + Set positiveExamplesTmp = new HashSet<>(positiveExamples); + + TreeSet newSortedPartialDefinitions = new TreeSet<>( + new ParCELDefinitionGenerationTimeComparator()); + + synchronized (partialDefinitions) { + newSortedPartialDefinitions.addAll(partialDefinitions); + } + + TreeSet minimisedPartialDefinition = new TreeSet<>( + new ParCELDefinitionGenerationTimeComparator()); + + Iterator partialDefinitionIterator = newSortedPartialDefinitions.iterator(); + + while ((positiveExamplesTmp.size() > uncoveredPositiveExamples) + && (partialDefinitionIterator.hasNext())) { + ParCELExtraNode node = partialDefinitionIterator.next(); + + int positiveExamplesRemoved = positiveExamplesTmp.size(); + positiveExamplesTmp.removeAll(node.getCoveredPositiveExamples()); + + positiveExamplesRemoved -= positiveExamplesTmp.size(); + + if (positiveExamplesRemoved > 0) { + node.setCorrectness(positiveExamplesRemoved); + minimisedPartialDefinition.add(node); + } + } + + return minimisedPartialDefinition; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer.java new file mode 100644 index 0000000000..4e63a8f505 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer.java @@ -0,0 +1,115 @@ +package org.dllearner.algorithms.parcel.reducer; + +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELCompletenessComparator; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * This class implements "wise" coverage greedy strategy for compacting the partial definitions In + * this strategy, the partial definitions will be chosen based on their coverage. When a partial + * definition has been chosen, coverage of other partial definition will be recalculated + * + * @author An C. Tran + * + */ + +public class ParCELImprovedCoverageGreedyReducer implements ParCELReducer { + + Logger logger = Logger.getLogger(this.getClass()); + + /** + * Compact partial definition with noise allowed + * + * @param partialDefinitions + * Set of partial definitions + * @param positiveExamples + * Set of positive examples (used to check whether partial definition is useful + * + * @return Subset of partial definitions that cover all positive examples + */ + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples) + { + return this.reduce(partialDefinitions, positiveExamples, 0); + } + + /** + * Compact partial definition with noise allowed + * + * @param partialDefinitions + * Set of partial definitions + * @param positiveExamples + * Set of positive examples (used to check whether partial definition is useful + * @param uncoveredPositiveExamplesAllowed + * Number of uncovered positive examples allowed + * + * @return Subset of partial definitions that cover (positive examples \ uncovered positive + * examples) + */ + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples, int uncoveredPositiveExamplesAllowed) + { + + Set positiveExamplesTmp = new HashSet<>(positiveExamples); + + TreeSet reducedPartialDefinition = new TreeSet<>( + new ParCELCompletenessComparator()); + + if (partialDefinitions.size() == 0) + return reducedPartialDefinition; + + synchronized (partialDefinitions) { + Object[] partialDefs = partialDefinitions.toArray(); + + // the highest accurate partial definition + // reducedPartialDefinition.add((PDLLExtraNode)partialDefs[0]); + // positiveExamplesTmp.removeAll(((PDLLExtraNode)partialDefs[0]).getCoveredPositiveExamples()); + + for (int i = 0; (positiveExamplesTmp.size() > uncoveredPositiveExamplesAllowed) + && (i < partialDefinitions.size()); i++) { + + // count the number of different positive examples covered + int counti = 0; + for (OWLIndividual indi : ((ParCELExtraNode) partialDefs[i]).getCoveredPositiveExamples()) { + if (positiveExamplesTmp.contains(indi)) + counti++; + } // count the number of different covered positive examples by i + + + for (int j = i + 1; j < partialDefinitions.size(); j++) { + int countj = 0; + + for (OWLIndividual indj : ((ParCELExtraNode) partialDefs[j]).getCoveredPositiveExamples()) + if (positiveExamplesTmp.contains(indj)) + countj++; + + // TODO: revise this code: Swapping should be done only one + // time at the end + // swap the partial definition so that the "best" partial + // definition will be in the top + if (countj > counti) { + ParCELExtraNode tmp = (ParCELExtraNode) partialDefs[j]; + partialDefs[j] = partialDefs[i]; + partialDefs[i] = tmp; + counti = countj; + } + } + + reducedPartialDefinition.add((ParCELExtraNode) partialDefs[i]); + positiveExamplesTmp.removeAll(((ParCELExtraNode) partialDefs[i]) + .getCoveredPositiveExamples()); + } + } + + return reducedPartialDefinition; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java new file mode 100644 index 0000000000..17464392e0 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java @@ -0,0 +1,205 @@ +package org.dllearner.algorithms.parcel.reducer; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELCompletenessComparator; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * This class implements "wise" coverage greedy strategy for compacting the partial definitions In + * this strategy, the partial definitions will be chosen based on their coverage. When a partial + * definition has been chosen, coverage of other partial definition will be recalculated + * + * @author An C. Tran + * + */ + +public class ParCELImprovedCoverageGreedyReducer_V2 implements ParCELReducer { + + Logger logger = Logger.getLogger(this.getClass()); + + /** + * Compact partial definition with noise allowed + * + * @param partialDefinitions + * Set of partial definitions + * @param positiveExamples + * Set of positive examples (used to check whether partial definition is useful + * + * @return Subset of partial definitions that cover all positive examples + */ + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples) + { + return this.reduce(partialDefinitions, positiveExamples, 0); + } + + /** + * Compact partial definition with noise allowed + * + * @param partialDefinitions + * Set of partial definitions + * @param positiveExamples + * Set of positive examples (used to check whether partial definition is useful + * @param uncoveredPositiveExamples + * Number of uncovered positive examples allowed + * + * @return Subset of partial definitions that cover (positive examples \ uncovered positive + * examples) + */ + @Override + public SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples, int uncoveredPositiveExamples) + { + + Set coveredPositiveExamples = new HashSet<>(); + int coverageThreshold = positiveExamples.size() - uncoveredPositiveExamples; + + TreeSet reducedPartialDefinition = new TreeSet<>( + new ParCELCompletenessComparator()); + + if (partialDefinitions.size() == 0) + return reducedPartialDefinition; + + synchronized (partialDefinitions) { + Map scoringResult = new HashMap<>(); + + //factors, that are used to adjust the scores of dimensions + double lengthFactor = 0.3; + double relativeCoverageFactor = 1.0; + + int maxLength = 0; + int maxCoverage = 0; + + //get the global information such as max length, etc. + for (ParCELExtraNode pdef : partialDefinitions) { + //max length + int curLength = new OWLClassExpressionLengthCalculator().getLength(pdef.getDescription()); + if (curLength > maxLength) + maxLength = curLength; + + //max coverage + int curCoverage = pdef.getCoveredPositiveExamples().size(); + if (maxCoverage < curCoverage) + maxCoverage = curCoverage; + } + + Object[] partialDefs = partialDefinitions.toArray(); + + // the highest accurate partial definition + // reducedPartialDefinition.add((PDLLExtraNode)partialDefs[0]); + // positiveExamplesTmp.removeAll(((PDLLExtraNode)partialDefs[0]).getCoveredPositiveExamples()); + + //==================================== + for (int i=0; (coveredPositiveExamples.size() < coverageThreshold) && + (i < partialDefs.length); i++) + { + + //------------------ + //count the number of positive examples covered by the partial definition i + //------------------ + int counti = ((ParCELExtraNode)partialDefs[i]).getCoveredPositiveExamples().size(); + + for (OWLIndividual ind : ((ParCELExtraNode)partialDefs[i]).getCoveredPositiveExamples()) { + if (coveredPositiveExamples.size() == 0) + break; + + //decrease the number of coverage if the ind is in the covered positive examples list + if (coveredPositiveExamples.contains(ind)) + counti--; + } + + int maxIndex = i; + int maxLocalCoverage = counti; //this should be replaced by a function instead + + //------------------ + //count the number of positive examples covered by the rest partial definitions + //------------------ + for (int j=i+1; j reduce(SortedSet partialDefinitions, + Set positiveExamples); + + /** + * Compact a set of partial definitions with noise (a number of uncovered positive examples are + * allowed) + * + * @param partialDefinitions + * Set of partial definitions + * @param positiveExamples + * Set of positive examples (used to check the completeness) + * @param uncoveredPositiveExamples + * Number of positive examples can be uncovered + * + * @return "Minimal" set of partial definitions + */ + SortedSet reduce(SortedSet partialDefinitions, + Set positiveExamples, int uncoveredPositiveExamples); +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterAbstract.java new file mode 100644 index 0000000000..17b32f92de --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterAbstract.java @@ -0,0 +1,82 @@ +package org.dllearner.algorithms.parcel.split; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentInitException; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * This is the interface for data type property splitting strategies in ParCEL: Given a set of + * positive and negative examples and a reasoner with the ontology loaded, calculate the splits for + * data type properties in the ontology + * + * @author An C. Tran + * + */ + +public interface ParCELDoubleSplitterAbstract { + + + void init() throws ComponentInitException; + + + /** + * Calculate the split + * + * @return A list of mapped data type properties and their splits + */ + Map> computeSplits(); + + + /** + * Get the reasoner used by the splitter + * + * @return The reasoner + */ + AbstractReasonerComponent getReasoner(); + + + /** + * Set the reasoner for the splitter + * + * @param reasoner + */ + void setReasoner(AbstractReasonerComponent reasoner); + + + /** + * Get the positive examples used by the splitter + * + * @return Set of positive examples + */ + Set getPositiveExamples(); + + + /** + * Set the positive examples will be used to calculate the splits + * + * @param positiveExamples + */ + void setPositiveExamples(Set positiveExamples); + + + /** + * Get the positive examples used by the splitter + * + * @return Set of negative examples + */ + Set getNegativeExamples(); + + + /** + * Assign the negative example set + * + * @param negativeExamples + */ + void setNegativeExamples(Set negativeExamples); + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterV1.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterV1.java new file mode 100644 index 0000000000..279f2bf824 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ParCELDoubleSplitterV1.java @@ -0,0 +1,390 @@ +package org.dllearner.algorithms.parcel.split; + +import java.util.*; +import java.util.stream.Collectors; + +import org.apache.log4j.Logger; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentInitException; +import org.semanticweb.owlapi.model.*; + +/** + * This class implements a splitting strategy for datatype property. In this strategy, the splitted + * value will be generate in a manner such that there is no range which contains both positive + * and negative examples to avoid the learning get stuck in its specialisation + * + *
+ * + * NOTE: values for a data property can be queried from the ontology. However, to find know that + * a value "relates" to positive or negative examples, we need to build a dependence graph because + * a value may not related directly with the value but it may be indirectly related through some + * object properties. + * + *
+ * Procedure: + *
    + *
  1. filter out a list of numeric datatype properties,
  2. + *
  3. build a relation graph that connects each value with positive/negative examples related to it,
  4. + *
  5. apply splitting strategy on the list of values (along with its positive.negative examples)
  6. + *
+ * + * @author An C. Tran + * + */ + +@ComponentAnn(name = "ParCEL double splitter v1", shortName = "parcelSplitterV1", version = 0) +public class ParCELDoubleSplitterV1 implements ParCELDoubleSplitterAbstract { + + private AbstractReasonerComponent reasoner = null; + private Set positiveExamples = null; + private Set negativeExamples = null; + + private Set numericDatatypeProperties; + private Set intDatatypeProperties; + private Set doubleDatatypeProperties; + + private final Logger logger = Logger.getLogger(this.getClass()); + + public ParCELDoubleSplitterV1() { + + } + + /** + * Create a Splitter given a reasoner, positive and negative examples + * + * @param reasoner A reasoner with ontology loaded before + * @param positiveExamples Set of positive examples + * @param negativeExamples Set of negative examples + */ + public ParCELDoubleSplitterV1(AbstractReasonerComponent reasoner, + Set positiveExamples, + Set negativeExamples) { + this.reasoner = reasoner; + + this.positiveExamples = positiveExamples; + this.negativeExamples = negativeExamples; + } + + /** + * Initialise the Splitter + * + * @throws ComponentInitException + * @throws OWLOntologyCreationException + */ + public void init() throws ComponentInitException { + if (this.reasoner == null) + throw new ComponentInitException("There is no reasoner for initialising the Splitter"); + + if (this.positiveExamples == null) + throw new ComponentInitException( + "There is no positive examples for initialising the Splitter"); + + if (this.negativeExamples == null) + throw new ComponentInitException( + "There is no negative examples for initialising the Splitter"); + + // get a list of double data type properties for filtering out other properties + this.numericDatatypeProperties = new HashSet<>(reasoner.getDoubleDatatypeProperties()); + + //get a list of integer datatype properties + this.numericDatatypeProperties.addAll(reasoner.getIntDatatypeProperties()); + + this.intDatatypeProperties = new HashSet<>(reasoner.getIntDatatypeProperties()); + this.doubleDatatypeProperties = new HashSet<>(reasoner.getDoubleDatatypeProperties()); + + if (logger.isInfoEnabled()) + logger.info("Splitter created: " + this.getClass().getSimpleName() + "..."); + + } + + public Map> Test() { + Map relations = new HashMap<>(); + + for (OWLIndividual ind : positiveExamples) { + Map individualRelations = getInstanceValueRelation(ind, true, new HashSet<>()); // TODO shouldn't the set be global + + individualRelations.forEach((dp, values) -> relations.merge(dp, values, (set1, set2) -> { + set1.addAll(set2); + return set1; + })); + } + + // generate relation for negative examples + for (OWLIndividual ind : negativeExamples) { + Map individualRelations = getInstanceValueRelation(ind, false, new HashSet<>()); // TODO shouldn't the set be global + + individualRelations.forEach((dp, values) -> relations.merge(dp, values, (set1, set2) -> { + set1.addAll(set2); + return set1; + })); + } + + Map> splits = new TreeMap<>(); + + // - - - . + + + + + . = . = . = . + . = . = . - . = . - - - + relations.forEach((dp, propertyValues) -> { + if(!propertyValues.isEmpty()) { + List values = new ArrayList<>(); + + int priorType = propertyValues.first().getType(); + double priorValue = propertyValues.first().getValue(); + + for (ValueCount currentValueCount : propertyValues) { + int currentType = currentValueCount.getType(); + double currentValue = currentValueCount.getValue(); + + // check if a new value should be generated: when the type changes or the + // current value belongs to both pos. and neg. + if ((currentType == 3) || (currentType != priorType)) { + //calculate the middle/avg. value + //TODO: how to identify the splitting strategy here? For examples: time,... + values.add((priorValue + currentValue) / 2.0); + + //Double newValue = new Double(new TimeSplitter().calculateSplit((int)priorValue, (int)currentValue)); + //if (!values.contains(newValue)) + // values.add(newValue); + + //values.add((priorValue + currentValue) / 2.0); + } + + // update the prior type and value after process the current element + priorType = currentValueCount.getType(); + priorValue = currentValueCount.getValue(); + + } + + // add processed property into the result set (splits) + //splits.put(dp, values); + + //logger.info("Test: " + dp.toString() + " " + dp.getSignature().toString() + " " + dp.getDataPropertiesInSignature().toString() + " " + dp.getDatatypesInSignature().toString()) ; + if (logger.isInfoEnabled()) + logger.info("Splitting: " + dp + ", no of values: " + relations.get(dp).size() + + ", splits: " + values.size()); + } + }); + + if (logger.isInfoEnabled()) + logger.info("Splitting result: " + splits); + + return splits; + } + + /** + * Compute splits for all double data properties in the ontology + * + * @return A map of datatype properties and their splitting values + */ + public Map> computeSplits() { + // ------------------------------------------------- + // generate relations for positive examples + // ------------------------------------------------- + + Map relations = new HashMap<>(); + + for (OWLIndividual ind : positiveExamples) { + Map individualRelations = getInstanceValueRelation(ind, true, new HashSet<>()); // TODO shouldn't the set be global + + individualRelations.forEach((dp, values) -> relations.merge(dp, values, (set1, set2) -> { + set1.addAll(set2); + return set1; + })); + } + + // generate relation for negative examples + for (OWLIndividual ind : negativeExamples) { + Map individualRelations = getInstanceValueRelation(ind, false, new HashSet<>()); // TODO shouldn't the set be global + + individualRelations.forEach((dp, values) -> relations.merge(dp, values, (set1, set2) -> { + set1.addAll(set2); + return set1; + })); + } + + + // ------------------------------------------------- + // calculate the splits for each data property + // ------------------------------------------------- + + Map> splits = new TreeMap<>(); + + // - - - . + + + + + . = . = . = . + . = . = . - . = . - - - + relations.forEach((dp, propertyValues) -> { + if(!propertyValues.isEmpty()) { + List values = new ArrayList<>(); + + int priorType = propertyValues.first().getType(); + double priorValue = propertyValues.first().getValue(); + + for (ValueCount currentValueCount : propertyValues) { + int currentType = currentValueCount.getType(); + double currentValue = currentValueCount.getValue(); + + // check if a new value should be generated: when the type changes or the + // current value belongs to both pos. and neg. + if ((currentType == 3) || (currentType != priorType)) { + //calculate the middle/avg. value + //TODO: how to identify the splitting strategy here? For examples: time,... + values.add((priorValue + currentValue) / 2.0); + + //Double newValue = new Double(new TimeSplitter().calculateSplit((int)priorValue, (int)currentValue)); + //if (!values.contains(newValue)) + // values.add(newValue); + + //values.add((priorValue + currentValue) / 2.0); + } + + // update the prior type and value after process the current element + priorType = currentValueCount.getType(); + priorValue = currentValueCount.getValue(); + + } + + // add processed property into the result set (splits) + splits.put(dp, values); + + //logger.info("Test: " + dp.toString() + " " + dp.getSignature().toString() + " " + dp.getDataPropertiesInSignature().toString() + " " + dp.getDatatypesInSignature().toString()) ; + if (logger.isInfoEnabled()) + logger.info("Splitting: " + dp + ", no of values: " + relations.get(dp).size() + + ", splits: " + values.size()); + } + }); + + if (logger.isInfoEnabled()) + logger.info("Splitting result: " + splits); + + return splits; + } + + /** + * Find the related values of an individual + * + * @param individual + * The individual need to be seek for the related values + * @param positiveExample + * True if the given individual is a positive example and false otherwise + * @param visitedIndividuals + * Set of individuals that had been visited when finding the related values for the + * given individual + * + * @return A map from data property to its related values that had been discovered from the + * given individual + */ + private Map getInstanceValueRelation(OWLIndividual individual, + boolean positiveExample, + Set visitedIndividuals) { + +// if (visitedIndividuals == null) +// visitedIndividuals = new HashSet<>(); + + // if the individual visited + if (visitedIndividuals.contains(individual)) + return null; + else + visitedIndividuals.add(individual); + + Map relations = new HashMap<>(); + + // get all data property values of the given individual + Map> dataPropertyValues = reasoner.getDataPropertyRelationships(individual); + + // get all object properties value of the given individual + Map> objectPropertyValues = reasoner.getObjectPropertyRelationships(individual); + + // --------------------------------------- + // process data properties + // NOTE: filter the double data property + // --------------------------------------- +// dataPropertyValues.entrySet().stream() +// .filter(numericDatatypeProperties::contains) +// .forEach(dp -> { +// ValueCountSet values = new ValueCountSet(); +// dataPropertyValues.get(dp).stream() +// .map(OWLLiteral::getLiteral) +// .map(Double::parseDouble) +// .map(val -> new ValueCount(val, positiveExample)) +// .forEach(values::add); +// relations.computeIfPresent(dp, ) +// }); + for (OWLDataProperty dp : dataPropertyValues.keySet()) { + if(this.reasoner.getDatatype(dp) != null && this.reasoner.getDatatype(dp).toString() == "int") + { + logger.info("test"); + } + if(this.reasoner.getDatatype(dp) != null && this.reasoner.getDatatype(dp).isInteger()) + { + logger.info("INT"); + } + if(this.reasoner.getDatatype(dp) != null && this.reasoner.getDatatype(dp).isFloat()) + { + logger.info("FLOAT"); + } + if (this.numericDatatypeProperties.contains(dp)) { + + // process values of each data property: create a ValueCount object and add it into + // the result + ValueCountSet values = new ValueCountSet(); + for (OWLLiteral lit : dataPropertyValues.get(dp)) { + ValueCount newValue = new ValueCount(Double.parseDouble(lit.getLiteral()), positiveExample); + values.add(newValue); + } + + relations.merge(dp, values, (set1, set2) -> { + set1.addAll(set2); + return set1; + }); + } + } + + // process each object property: call this method recursively + objectPropertyValues.forEach((op, individuals) -> + individuals.forEach(ind -> { + Map subRelations = getInstanceValueRelation(ind, + positiveExample, visitedIndividuals); + + // sub-relation == null if the ind had been visited + if (subRelations != null) { + for (OWLDataProperty dp : subRelations.keySet()) { + // if the data property exist, update its values + relations.merge(dp, subRelations.get(dp), (set1, set2) -> { + set1.addAll(set2); + return set1; + }); + } + } + } + ) + ); + + return relations; + } + + + //----------------------------- + // getters and setters + //----------------------------- + public AbstractReasonerComponent getReasoner() { + return reasoner; + } + + public void setReasoner(AbstractReasonerComponent reasoner) { + this.reasoner = reasoner; + } + + public Set getPositiveExamples() { + return positiveExamples; + } + + public void setPositiveExamples(Set positiveExamples) { + this.positiveExamples = positiveExamples; + } + + public Set getNegativeExamples() { + return negativeExamples; + } + + public void setNegativeExamples(Set negativeExamples) { + this.negativeExamples = negativeExamples; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCount.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCount.java new file mode 100644 index 0000000000..a9f94b29b0 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCount.java @@ -0,0 +1,113 @@ +package org.dllearner.algorithms.parcel.split; + +/** + * This class represents a value and number of its occurrences. This can be used to count the + * number of time a value is used. In addition, each value may belong to a positive or negative example or to + * both. getType() method return the type of the value. 0 for error (nether pos nor + * neg), 1 for positive, 2 for negative, and 3 for both + * + * @author An C. Tran + */ + +public class ValueCount implements Comparable { + private double value; + private int count; + boolean isPositive; + boolean isNegative; + + public ValueCount(double value) { + this.value = value; + this.count = 1; + this.isPositive = false; + this.isNegative = false; + } + + public ValueCount(double value, boolean isPos) { + this.value = value; + this.count = 1; + this.isPositive = isPos; + this.isNegative = !(isPos); + } + + public ValueCount(double value, int count, boolean isPos) { + this.value = value; + this.count = count; + this.isPositive = isPos; + this.isNegative = !(isPos); + } + + public ValueCount(double value, boolean isPos, boolean isNeg) { + this.value = value; + this.count = 1; + this.isPositive = isPos; + this.isNegative = isNeg; + } + + public ValueCount(double value, int count, boolean isPos, boolean isNeg) { + this.value = value; + this.count = count; + this.isPositive = isPos; + this.isNegative = isNeg; + } + + public double getValue() { + return this.value; + } + + public void setValue(double value) { + this.value = value; + } + + public int getCount() { + return this.count; + } + + public void setCount(int count) { + this.count = count; + } + + public boolean isPositive() { + return this.isPositive; + } + + public boolean isNegative() { + return this.isNegative; + } + + public void setPositive(boolean pos) { + this.isPositive = pos; + } + + public void setNegative(boolean neg) { + this.isNegative = neg; + } + + /** + * Get the "convention type" of the value: 0 for positive, 1 for negative, and 2 for both + * + * @return 0 for error (nether pos nor neg), 1 for positive, 2 for negative, and 3 for either + */ + public int getType() { + int type = 0; + + if (isPositive) + type += 1; + + if (isNegative) + type += 2; + + return type; + } + + @Override + public int compareTo(ValueCount v) { + + // if ((this.isPositive == v.isPositive) && (this.isNegative == v.isNegative)) + return Double.compare(this.value, v.value); + // return (this.value > v.value ? 1 : -1); + } + + public String toString() { + return ("[" + this.value + ":" + this.count + ":" + this.getType() + "]"); + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCountSet.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCountSet.java new file mode 100644 index 0000000000..c46590643f --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/split/ValueCountSet.java @@ -0,0 +1,60 @@ +package org.dllearner.algorithms.parcel.split; + +import java.util.Iterator; +import java.util.TreeSet; + +/** + * This class implements a set of value and its count (ValueCount), i.e. the number of times the + * value was added. When a value (ValueCount instance) is added, if the value has been added, this + * value is not be added again but its count is increase. For examples, if we add ([1, 1], [2, 1], + * [1, 2], [2, 1], [1, 1]), the set will contains 1 with its count is 4 and 2 with its count is 2 + * (NOTE: the pair [n, m] represents the value n with its count m. The "count" value represents the + * number of times the value has been used + * + * @author An C. Tran + */ + +@SuppressWarnings("serial") +public class ValueCountSet extends TreeSet { + + public ValueCountSet() { + super(); + } + + public boolean add(ValueCount value) { + Iterator iterator = super.iterator(); + + // check for the existence of a value in the set. + // if it does exist, its count will be increased + while (iterator.hasNext()) { + ValueCount v = iterator.next(); + if (v.getValue() == value.getValue()) { + v.setCount(v.getCount() + value.getCount()); + v.setPositive(v.isPositive() || value.isPositive()); + v.setNegative(v.isNegative() || value.isNegative()); + return false; + } + } + + // if the value has not been in the set, add it into the set + super.add(value); + return true; + } + + // this method is used to test the working of this class + public static void main(String[] args) { + ValueCountSet mySet = new ValueCountSet(); + + mySet.add(new ValueCount(1)); + mySet.add(new ValueCount(1)); + mySet.add(new ValueCount(2)); + mySet.add(new ValueCount(1)); + + //mySet.remove(new ValueCount(1, 10, true, true)); + + for (ValueCount v : mySet) { + System.out.println(v); + } + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java new file mode 100644 index 0000000000..9cd2e1aa17 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java @@ -0,0 +1,186 @@ +package org.dllearner.algorithms.parcelex; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.core.AbstractReasonerComponent; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Abstract class for all ParCELEx (ParCEL with Exceptions or Two-way ParCEL) algorithms family + * This algorithm learn both positive example and negative examples in the same + * + * @author An C. Tran + * + */ +public abstract class ParCELExAbstract extends ParCELAbstract { + + /** + * partial definition (they should be sorted by the completeness so that we can get the best + * partial definition at any time. Otherwise, we can use a hashset here for a better performance + */ + protected SortedSet counterPartialDefinitions = null; + + protected int[] partialDefinitionType = new int[5]; + protected int counterPartialDefinitionUsed = 0; + + /** + * Holds the covered negative examples, this will be updated when the worker found a partial definition + * since the callback method "partialDefinitionFound" is synchronized, + * there is no need to create a thread-safe for this set + */ + protected HashSet coveredNegativeExamples; + + + //--------------------------------------------------------- + //flags to indicate the status of the application + //--------------------------------------------------------- + /** + * Reducer found a complete counter definition? + */ + protected volatile boolean counterDone = false; + + //some properties for statistical purpose + protected int descriptionTested; //total number of descriptions tested (generated and calculated accuracy, correctess,...) + + /** + * + * Default constructor + */ + public ParCELExAbstract() { + super(); + } + + /** + * + * Constructor for the learning algorithm + * + * @param learningProblem A learning problem which provides the accuracy calculation for the learner + * @param reasoningService A reasoner which will be used by the learner + */ + public ParCELExAbstract(ParCELPosNegLP learningProblem, AbstractReasonerComponent reasoningService) { + super(learningProblem, reasoningService); + } + + + /** + * This will be called by the workers to pass the new counter partial definitions to the learner + * + * @param definitions New counter partial definition + */ + public abstract void newCounterPartialDefinitionsFound(Set definitions); + + + /** + * Aggregate the information related to the counter partial definitions: + *
    + *
  • total number of counter partial definitions used
  • + *
  • number of counter partial definitions used group by counter partial definition type
  • + *
+ */ + public void aggregateCounterPartialDefinitionInf() { + // ----------------------------------------------------- + // calculate some data for analysing the algorithm + // ----------------------------------------------------- + + // number of each type of partial definition + Arrays.fill(this.partialDefinitionType, 0); + + if (this.partialDefinitions == null) { + logger.error("partial definition set is null"); + return; + } + + for (ParCELExtraNode def : this.partialDefinitions) { + int type = def.getType(); + if (type >= this.partialDefinitionType.length) + logger.error("partial definition type " + type + " is not supported"); + else + this.partialDefinitionType[type]++; + } + + // number of partial definition had been used + this.counterPartialDefinitionUsed = 0; + for (ParCELExtraNode def : this.counterPartialDefinitions) { + if (def.getType() > 0) + this.counterPartialDefinitionUsed++; + } + } + + + /** + * Get all counter partial definitions generated + * + * @return All counter partial definitions generated + */ + public SortedSet getCounterPartialDefinitions() { + return this.counterPartialDefinitions; + } + + + /** + * Get the number of partial definitions of a certain type + * + * @param type Partial definition type + * + * @return Number of the counter partial definitions of the given type + */ + public int getNumberOfPartialDefinitions(int type) { + if (type < this.partialDefinitionType.length) + return this.partialDefinitionType[type]; + else + return -1; + } + + + /** + * Get total number of counter partial definitions + * + * @return Total number of counter partial definitions (not reduced) + */ + public int getNumberOfCounterPartialDefinitions() { + return (this.counterPartialDefinitions == null? 0 : this.counterPartialDefinitions.size()); + } + + + /** + * Get the number of counter partial definition used (in combination with descriptions to constitute + * the partial definitions) + * + * @return Number of the partial definitions used (combined with the descriptions to create the partial definitions) + */ + public int getNumberOfCounterPartialDefinitionUsed() { + return this.counterPartialDefinitionUsed; + } + + + /** + * Check whether the learner terminated by the counter partial definitions + * + * @return True if the learner is terminated by the counter partial definitions, false otherwise + */ + public boolean terminatedByCounterDefinitions() { + return this.counterDone; + } + + + /**=========================================================================================================
+ * Check if the learner can be terminated + * + * @return True if termination condition is true (asked to stop, complete definition found, or timeout), + * false otherwise + */ + @Override + protected boolean isTerminateCriteriaSatisfied() { + return stop || + done || + counterDone || + timeout; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExCombineCounterPartialDefinition.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExCombineCounterPartialDefinition.java new file mode 100644 index 0000000000..4a2b3fe7ab --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExCombineCounterPartialDefinition.java @@ -0,0 +1,134 @@ +package org.dllearner.algorithms.parcelex; + +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; + +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELNode; +import org.semanticweb.owlapi.model.OWLIndividual; + + +/** + * + * This class provide utility functions for combination of description and counter partial definitions. + * + * NOTE: This should be move to the utility class? + * + * @author An C. Tran + * + */ + +public class ParCELExCombineCounterPartialDefinition { + + /** + * Combine a description and a give set of counter partial definition into a partial definition + * if possible
+ * Steps: + *
    + * While the covered negative examples of the description is not empty and there exists + * definitions in the list" + *
      + *
    1. Choose the best definition in the list
    2. + *
    3. Remove all negative examples covered by the description that are also covered by the + * best definition
    4. + *
    5. Remove the definition out of the list of definitions
    6. + *
    + *
+ * + * @param description + * Description which will be combined (if possible) + * @param counterPartialDefinitions + * Set of counter partial definitions + * + * @return A set combinable partial definitions if exists, null otherwise + */ + public static Set getCombinable(ParCELNode description, + SortedSet counterPartialDefinitions) { + + if (counterPartialDefinitions == null || counterPartialDefinitions.isEmpty()) + return null; + + Set combinableCounterPartialDefinitions = new HashSet<>(); + + // this set holds the set of negative examples covered by the description + // all operations on the set of covered negative examples will be performed on this set to + // avoid changing the description + HashSet coveredNegativeExamples = new HashSet<>(description.getCoveredNegativeExamples()); + + + Object[] partialDefinitionsArr; + synchronized (counterPartialDefinitions) { + partialDefinitionsArr = counterPartialDefinitions.toArray(); + } + + // for each loop, choose the best counter partial definition which can reduce the remaining + // covered negative examples of the description + int i = 0; + for (i = 0; i < partialDefinitionsArr.length; i++) { + + ParCELExtraNode currentNode = (ParCELExtraNode) partialDefinitionsArr[i]; + + // get the number of common covered negative examples between description and the + // partial definition i + int maxIntersection = countIntersection(coveredNegativeExamples, + currentNode.getCoveredNegativeExamples()); + int maxIntersectionIndex = i; + + // compare the number of intersection of the first element with the rest + for (int j = i + 1; j < partialDefinitionsArr.length; j++) { + int intersectionJ = countIntersection(coveredNegativeExamples, + ((ParCELExtraNode) partialDefinitionsArr[j]).getCoveredNegativeExamples()); + + if (intersectionJ > maxIntersection) { + maxIntersection = intersectionJ; + maxIntersectionIndex = j; + } + } + + // swap the best counter partial definition into the top + if (maxIntersectionIndex != i) { + ParCELExtraNode tmpNode = currentNode; + currentNode = (ParCELExtraNode) partialDefinitionsArr[maxIntersectionIndex]; + partialDefinitionsArr[maxIntersectionIndex] = tmpNode; + } + + // remove the negative examples covered by the "best" counter partial definition + coveredNegativeExamples.removeAll(currentNode.getCoveredNegativeExamples()); + + // add the best definition in the current iteration into the result set + combinableCounterPartialDefinitions.add(currentNode); + + // check for the termination of the loop: The covered negative examples of the + // description is empty + if (coveredNegativeExamples.isEmpty()) + break; + } + + // check if the new partial definition is found, change the description + if (i >= partialDefinitionsArr.length) + return null; + else + return combinableCounterPartialDefinitions; + } + + /** + * Count the number of common elements between two sets + * + * @param set1 The 1st set of individual + * @param set2 The 2nd set of individual + * + * @return Number of common elements of two sets + */ + private static int countIntersection(Set set1, Set set2) { + int count = 0; + + for (OWLIndividual ind : set2) { + if (set1.contains(ind)) + count++; + } + + return count; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExNodeTypes.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExNodeTypes.java new file mode 100644 index 0000000000..4fd2592e2a --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExNodeTypes.java @@ -0,0 +1,67 @@ +package org.dllearner.algorithms.parcelex; + + +/** + * This class declares constants representing types of definitions and how they were created + *
    + *
  1. types: partial / counter partial definition
  2. + *
  3. created by: directly from the refinement, combined with cpdef (for pdef), online / lazy, etc.
  4. + *
+ * + * This is used in ParCELEx to keep the type of partial definition to use in other tasks such as + * reduction, statistic, etc. + * + * @author An C. Tran + * + */ + +public class ParCELExNodeTypes { + + /** + * The new created and unused counter partial definition + */ + public static final int COUNTER_PARTIAL_DEFINITION_UNUSED = 0; + + + /** + * Partial definition which is created directly from the refinement + */ + public static final int PARTIAL_DEFINITION_DIRECT_REFINED = 1; + + + /** + * Counter partial definition which had been combined with descriptions to + * constitute the partial definitions + */ + public static final int COUNTER_PARTIAL_DEFINITION_USED = 1; + + + /** + * Partial definition which is created by the combination of a description in refinements and counter partial definition(s) + * on the fly (that means it is created in the worker, after the refinement) + */ + public static final int PARTIAL_DEFINITION_ONLINE_COMBINATION = 3; + + + /** + * Partial definition which is created by the combination of a description and counter partial definition(s) + * after the learning finishes (Lazy combination) + */ + public static final int PARTIAL_DEFINITION_LAZY_COMBINATION = 2; + + + /** + * Partial definition which is created by the combination of the refined node and the new counter partial + * definition + */ + public static final int PARTIAL_DEFINITION_REFINED_NODE = 4; + + + /** + * Partial definition which is created by the combination of the refined node and the new counter partial + * definition + */ + public static final int POTENTIAL_PARTIAL_DEFINITION = 5; + + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExUtilities.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExUtilities.java new file mode 100644 index 0000000000..40afb9d847 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExUtilities.java @@ -0,0 +1,73 @@ +package org.dllearner.algorithms.parcelex; + +import java.util.*; + +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.core.owl.OWLObjectIntersectionOfImplExt; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.semanticweb.owlapi.model.OWLClassExpression; + + +/** + * This class contains some utility functions for ParCELEx algorithm such as group the partial definitions, + * calculate intersection between a description and a set of counter partial definitions, etc. + * + * @author An C. Tran + * + */ +public class ParCELExUtilities { + + /** + * Group the counter partial definitions in a partial definition using ConceptComparator + * so that the "relevant" counter partial definitions will ordered near each other for readability + * + * @param definition A definition (description) + * @return Description with the member counter partial definitions are grouped + */ + public static org.semanticweb.owlapi.model.OWLClassExpression groupDefinition(OWLClassExpression definition) { + + // TODO check if we need to keep track of proper lists, i.e. D and D and D + List children = new ArrayList<>(OWLClassExpressionUtils.getChildren(definition)); + + List counterPartialDefinitions = new LinkedList<>(); + List partialDefinitions = new LinkedList<>(); + for (OWLClassExpression def : children) { + if (def.toString().toLowerCase().contains("not ")) + counterPartialDefinitions.add(def); + else + partialDefinitions.add(def); + } + + Collections.sort(counterPartialDefinitions); + Collections.sort(partialDefinitions); + + partialDefinitions.addAll(counterPartialDefinitions); + + OWLClassExpression result = new OWLObjectIntersectionOfImplExt(partialDefinitions); + + return result; + } + + + /** + * Create an Intersection object given a description and a set of descriptions + * + * @param description A description + * @param counterDefinitions Set of descriptions + * + * @return An Intersection object of the given description and the set of descriptions + */ + public static OWLClassExpression createIntersection(OWLClassExpression description, Set counterDefinitions, boolean setUsed) { + LinkedList descriptionList = new LinkedList<>(); + + descriptionList.add(description); + for (ParCELExtraNode node : counterDefinitions) { + descriptionList.add(node.getDescription()); + if (setUsed) + node.setType(ParCELExNodeTypes.COUNTER_PARTIAL_DEFINITION_USED); + } + + return new OWLObjectIntersectionOfImplExt(descriptionList); + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java new file mode 100644 index 0000000000..485f5c899c --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java @@ -0,0 +1,105 @@ +package org.dllearner.algorithms.parcelex; + +import org.dllearner.algorithms.parcel.*; +import org.dllearner.refinementoperators.RefinementOperator; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataFactory; +import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; + +public abstract class ParCELExWorkerAbstract extends ParCELWorkerAbstract { + + protected OWLDataFactory df = new OWLDataFactoryImpl(); + + /** + * Constructor for Worker class. A worker needs the following things: i) reducer (reference), + * ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result + * to + * @param refinementOperatorPool Refinement operator pool used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELExWorkerAbstract(L learner, ParCELRefinementOperatorPool refinementOperatorPool, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperatorPool, learningProblem, nodeToProcess, name); + } + + /** + * Constructor for Worker class. A worker needs the following things: i) reducer (reference), + * ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result + * to + * @param refinementOperator Refinement operator used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELExWorkerAbstract(L learner, RefinementOperator refinementOperator, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperator, learningProblem, nodeToProcess, name); + } + + /** + * ============================================================================================ + * =============
+ * Calculate accuracy, correctness of a description and examples that are covered by this + * description
+ * This version is used in the learning with exception + * + * @param description + * Description which is being calculated + * @param parentNode + * The node which contains the description which is used in the refinement that + * result the input description + * + * @return Null if the description is processed before, or a node which contains the description + */ + protected ParCELExtraNode checkAndCreateNewNodeV2(OWLClassExpression description, ParCELNode parentNode) { + + // redundancy check + boolean nonRedundant = learner.addDescription(description); + if (!nonRedundant) + return null; // false, node cannot be added + + /** + *
    + *
  1. cp(D) = empty
  2. + *
      + *
    • cn(D) = empty: weak description ==> may be ignored
    • + *
    • cn(D) != empty: counter partial definition, especially used in learning with + * exceptions
    • + *
    + *
  3. cp(D) != empty
  4. + *
      + *
    • cn(D) = empty: partial definition
    • + *
    • cn(D) != empty: potential description
    • + *
    + *
+ */ + ParCELEvaluationResult evaluationResult = learningProblem + .getAccuracyAndCorrectnessEx(description); + + // cover no positive example && no negative example ==> weak description + if ((evaluationResult.getCompleteness() == 0) && (evaluationResult.getCorrectness() == 1)) + return null; + + ParCELExtraNode newNode = new ParCELExtraNode(parentNode, description, + evaluationResult.getAccuracy(), evaluationResult.getCorrectness(), + evaluationResult.getCompleteness(), evaluationResult.getCoveredPositiveExamples()); + + // newNode.setCorrectness(evaluationResult.getCorrectness()); + // newNode.setCompleteness(evaluationResult.getCompleteness()); + // newNode.setCoveredPositiveExamples(evaluationResult.getCoveredPossitiveExamples()); + newNode.setCoveredNegativeExamples(evaluationResult.getCoveredNegativeExamples()); + + if (parentNode != null) + parentNode.addChild(newNode); + + return newNode; + + } // addNode() + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java new file mode 100644 index 0000000000..3f6203b023 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java @@ -0,0 +1,154 @@ +package org.dllearner.algorithms.parcelex; + +import org.dllearner.algorithms.parcel.*; +import org.dllearner.refinementoperators.RefinementOperator; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.semanticweb.owlapi.model.OWLClassExpression; + +import java.util.HashSet; +import java.util.TreeSet; + + +/** + * ParCELEx Worker which refines the given nodes and + * evaluate the refinement result. It will return partial definitions + * and/or new description to the reducer if any. + * + * This worker uses Lazy Combination strategy + * + * @author An C. Tran + * + */ +public class ParCELWorkerExV1 extends ParCELExWorkerAbstract { + + /**=========================================================================================================
+ * Constructor for Worker class. A worker needs the following things: + * i) reducer (reference), ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result to + * @param refinementOperatorPool Refinement operator pool used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerExV1(ParCELExAbstract learner, ParCELRefinementOperatorPool refinementOperatorPool, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperatorPool, learningProblem, nodeToProcess, name); + } + + + + /**=========================================================================================================
+ * Constructor for Worker class. A worker needs the following things: + * i) reducer (reference), ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result to + * @param refinementOperator Refinement operator used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerExV1(ParCELearnerExV1 learner, RefinementOperator refinementOperator, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperator, learningProblem, nodeToProcess, name); + } + + + + /**=========================================================================================================
+ * Start the worker: Call the methods processNode() for processing the current node given by reducer + */ + @Override + public void run() { + + if (logger.isTraceEnabled()) + logger.trace("[PLLearning] Processing node (" + ParCELStringUtilities.replaceString(nodeToProcess.toString(), this.baseURI, this.prefix)); + + + TreeSet refinements; //will hold the refinement result (set of Descriptions) + + HashSet newPartialDefinitions = new HashSet<>(); //hold the partial definitions if any + HashSet newCounterPartialDefinitions = new HashSet<>(); + + HashSet newNodes = new HashSet<>(); //hold the refinements that are not partial definitions + + int horizExp = nodeToProcess.getHorizontalExpansion(); + + //1. refine node + refinements = refineNode(nodeToProcess); + + if (refinements != null) { + if (logger.isTraceEnabled()) + logger.trace("[PLLearning] Refinement result (" + refinements.size() + "): " + + ParCELStringUtilities.replaceString(refinements.toString(), this.baseURI, this.prefix)); + + + //2. process the refinement result: calculate the accuracy and completeness and add the new expression into the search tree + while (refinements.size() > 0) { + OWLClassExpression refinement = refinements.pollFirst(); + int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); + + + // we ignore all refinements with lower length (may it happen?) + // (this also avoids duplicate node children) + if(refinementLength > horizExp) { + + //calculate accuracy, correctness, positive examples covered by the description, resulted in a node + ParCELExtraNode newNode = checkAndCreateNewNodeV2(refinement, nodeToProcess); + + //check for the type of new node: weak description, partial definition, counter partial definition or potential description + if (newNode != null) { + + /* + * - completeness(D) = 0, i.e. cp(D) = empty: + * + correctness(D) = 1, i.e. cn(D) = empty ==> weak description + * + correctness(D) < 1, i.e. cn(D) != empty ==> counter partial definition + * - completeness(D) > 0, i.e. cp(D) != empty + * + correctness(D) = 1, i.e. cn(D) = empty ==> partial definition + * + correctness(D) < 1, i.e. cn(D) != empty ==> potential description + */ + newNode.setGenerationTime(learner.getMiliStarttime() - System.currentTimeMillis()); + if (newNode.getCompleteness() == 0.0d) { + + //COUNTER PARTIAL DEFINITION + if (newNode.getCorrectness() < 1d) { + newNode.setType(0); + newNode.setDescription(df.getOWLObjectComplementOf(newNode.getDescription())); + newCounterPartialDefinitions.add(newNode); + } + //else: weak description ==> ignore the description: do nothing + } + else { //i.e. completeness > 0 + + //PARTIAL DEFINITION + if (newNode.getCorrectness() == 1.0d) { + newNode.setType(1); + newPartialDefinitions.add(newNode); + } + //DESCRIPTION + else { + newNodes.add(newNode); + } + } + + } //if (node != null) + } + } // while (refinements.size > 0) + + horizExp = nodeToProcess.getHorizontalExpansion(); + learner.updateMaxHorizontalExpansion(horizExp); + } + + newNodes.add(nodeToProcess); + + + if (newPartialDefinitions.size() > 0) + learner.newPartialDefinitionsFound(newPartialDefinitions); + + if (newCounterPartialDefinitions.size() > 0) + learner.newCounterPartialDefinitionsFound(newCounterPartialDefinitions); + + learner.newRefinementDescriptions(newNodes); //don't need to check for empty since newNodes is never empty + + } +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java new file mode 100644 index 0000000000..4cf39876b4 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java @@ -0,0 +1,175 @@ +package org.dllearner.algorithms.parcelex; + +import org.dllearner.algorithms.parcel.*; +import org.dllearner.refinementoperators.RefinementOperator; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.mindswap.pellet.exceptions.InternalReasonerException; +import org.semanticweb.owlapi.model.OWLClassExpression; + +import java.util.HashSet; +import java.util.TreeSet; + + +/** + * Worker class which will do the refinement on the given nodes and + * evaluate the refinement result. It will return partial definitions + * and/or new description to the reducer if any. + * + * @author An C. Tran + * + */ +public class ParCELWorkerExV12 extends ParCELExWorkerAbstract { + + /**=========================================================================================================
+ * Constructor for Worker class. A worker needs the following things: + * i) reducer (reference), ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result to + * @param refinementOperatorPool Refinement operator pool used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerExV12(ParCELExAbstract learner, ParCELRefinementOperatorPool refinementOperatorPool, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperatorPool, learningProblem, nodeToProcess, name); + } + + + + /**=========================================================================================================
+ * Constructor for Worker class. A worker needs the following things: + * i) reducer (reference), ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result to + * @param refinementOperator Refinement operator used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerExV12(ParCELearnerExV1 learner, RefinementOperator refinementOperator, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperator, learningProblem, nodeToProcess, name); + } + + + + /**=========================================================================================================
+ * Start the worker: Call the methods processNode() for processing the current node given by reducer + */ + @Override + public void run() { + + if (logger.isTraceEnabled()) + logger.trace("[PLLearning] Processing node (" + ParCELStringUtilities.replaceString(nodeToProcess.toString(), this.baseURI, this.prefix)); + + + TreeSet refinements; //will hold the refinement result (set of Descriptions) + + HashSet newPartialDefinitions = new HashSet<>(); //hold the partial definitions if any + HashSet newCounterPartialDefinitions = new HashSet<>(); + HashSet newPotentialPartialDefinitions = new HashSet<>(); + + HashSet newNodes = new HashSet<>(); //hold the refinements that are not partial definitions + + int horizExp = nodeToProcess.getHorizontalExpansion(); + + //1. refine node + refinements = refineNode(nodeToProcess); + + if (refinements != null) { + if (logger.isTraceEnabled()) + logger.trace("[PLLearning] Refinement result (" + refinements.size() + "): " + + ParCELStringUtilities.replaceString(refinements.toString(), this.baseURI, this.prefix)); + + + //2. process the refinement result: calculate the accuracy and completeness and add the new expression into the search tree + while (refinements.size() > 0) { + OWLClassExpression refinement = refinements.pollFirst(); + int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); + + + // we ignore all refinements with lower length (may it happen?) + // (this also avoids duplicate node children) + if(refinementLength > horizExp) { + + //calculate accuracy, correctness, positive examples covered by the description, resulted in a node + ParCELExtraNode newNode = null; + + try { + newNode = checkAndCreateNewNodeV2(refinement, nodeToProcess); + } catch (InternalReasonerException e) {} + + //check for the type of new node: weak description, partial definition, counter partial definition or potential description + if (newNode != null) { + + /* + * - completeness(D) = 0, i.e. cp(D) = empty: + * + correctness(D) = 1, i.e. cn(D) = empty ==> weak description + * + correctness(D) < 1, i.e. cn(D) != empty ==> counter partial definition + * - completeness(D) > 0, i.e. cp(D) != empty + * + correctness(D) = 1, i.e. cn(D) = empty ==> partial definition + * + correctness(D) < 1, i.e. cn(D) != empty ==> potential description + */ + + if (newNode.getCompleteness() == 0.0d) { + + //COUNTER PARTIAL DEFINITION + if (newNode.getCorrectness() < 1d) { + newNode.setType(ParCELExNodeTypes.COUNTER_PARTIAL_DEFINITION_UNUSED); + newNode.setGenerationTime(learner.getMiliStarttime() - System.currentTimeMillis()); + newNode.setDescription(df.getOWLObjectComplementOf(newNode.getDescription())); + newCounterPartialDefinitions.add(newNode); + } + //else: weak description ==> ignore the description: do nothing + } + else { //i.e. completeness > 0 + + //PARTIAL DEFINITION + if (newNode.getCorrectness() == 1.0d) { + newNode.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); + newNode.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_DIRECT_REFINED); + newPartialDefinitions.add(newNode); + } + //DESCRIPTION + else { + //TODO: check if the description may become a partial definition + + //given the current counter partial definition set + + if (ParCELExCombineCounterPartialDefinition.getCombinable(newNode, learner.getCounterPartialDefinitions()) != null) { + newNode.setType(ParCELExNodeTypes.POTENTIAL_PARTIAL_DEFINITION); + newPotentialPartialDefinitions.add(newNode); + } + //else + newNodes.add(newNode); + } + } + + } //if (node != null) + } + } // while (refinements.size > 0) + + horizExp = nodeToProcess.getHorizontalExpansion(); + learner.updateMaxHorizontalExpansion(horizExp); + } + + newNodes.add(nodeToProcess); + + + if (newPartialDefinitions.size() > 0) + learner.newPartialDefinitionsFound(newPartialDefinitions); + + if (newCounterPartialDefinitions.size() > 0) + learner.newCounterPartialDefinitionsFound(newCounterPartialDefinitions); + + + if (newPotentialPartialDefinitions.size() > 0) + ((ParCELearnerExV12)learner).newPotentialPartialDefinition(newPotentialPartialDefinitions); + + + learner.newRefinementDescriptions(newNodes); //don't need to check for empty since newNodes is never empty + + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java new file mode 100644 index 0000000000..9094e5e78b --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java @@ -0,0 +1,213 @@ +package org.dllearner.algorithms.parcelex; + +import org.dllearner.algorithms.parcel.*; +import org.dllearner.refinementoperators.RefinementOperator; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.semanticweb.owlapi.model.OWLClassExpression; + +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; + + +/** + * Worker class which will do the refinement on the given nodes and + * evaluate the refinement result. It will return partial definitions + * and/or new description to the reducer if any. + * + * This worker uses Online Combination strategy, i.e. it combine refinements with current + * counter partial definition set to create more cpdef + * + * @author actran + * + */ +public class ParCELWorkerExV2 extends ParCELExWorkerAbstract { + + + /**=========================================================================================================
+ * Constructor for Worker class. A worker needs the following things: + * i) reducer (reference), ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result to + * @param refinementOperatorPool Refinement operator pool used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerExV2(ParCELearnerExV2 learner, ParCELRefinementOperatorPool refinementOperatorPool, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperatorPool, learningProblem, nodeToProcess, name); + } + + + + /**=========================================================================================================
+ * Constructor for Worker class. A worker needs the following things: + * i) reducer (reference), ii) refinement operator, iii) start description, iv) worker name + * + * @param learner A reference to reducer which will be used to make a callback to return the result to + * @param refinementOperator Refinement operator used to refine the given node + * @param learningProblem A learning problem used to calculate description accuracy, correctness, etc. + * @param nodeToProcess Node will being processed + * @param name Name of the worker, assigned by reduce (for tracing purpose only) + */ + public ParCELWorkerExV2(ParCELearnerExV2 learner, RefinementOperator refinementOperator, + ParCELPosNegLP learningProblem, ParCELNode nodeToProcess, String name) { + super(learner, refinementOperator, learningProblem, nodeToProcess, name); + } + + + + /**=========================================================================================================
+ * Start the worker: Refine the given node and evaluate the refinements + *
+ * This method will call back the learner to return: + *
    + *
  1. New descriptions
  2. + *
  3. New partial definitions
  4. + *
  5. New counter partial definition
  6. + *
+ * + * NOTE: Partial definition generation time in this learner is used to represent the definition "type": + *
+ * 1: partial definitions that are generated directly by the refinement
+ * 2: partial definitions that are generated by the combination of the descriptions in the search tree + * and the counter partial definitions after the learning finishes + * 3: partial definitions that are generated by the combination of new refinement and the counter partial definitions + * 4: partial definitions that are generated by the combination of the input node and the counter partial definitions in the refinement + */ + @Override + public void run() { + + if (logger.isTraceEnabled()) + logger.trace("[PLLearning] Processing node (" + ParCELStringUtilities.replaceString(nodeToProcess.toString(), this.baseURI, this.prefix)); + + + TreeSet refinements; //will hold the refinement result (set of Descriptions) + + HashSet newPartialDefinitions = new HashSet<>(); //hold the partial definitions if any + HashSet newCounterPartialDefinitions = new HashSet<>(); + + HashSet newNodes = new HashSet<>(); //hold the refinements that are not partial definitions + + int horizExp = nodeToProcess.getHorizontalExpansion(); + + //1. refine node + refinements = refineNode(nodeToProcess); + + + if (refinements != null) { + if (logger.isTraceEnabled()) + logger.trace("[PLLearning] Refinement result (" + refinements.size() + "): " + + ParCELStringUtilities.replaceString(refinements.toString(), this.baseURI, this.prefix)); + + + //2. process the refinement result: calculate the accuracy and completeness and add the new expression into the search tree + while (refinements.size() > 0) { + OWLClassExpression refinement = refinements.pollFirst(); + int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); + + + // we ignore all refinements with lower length (may it happen?) + // (this also avoids duplicate node children) + if(refinementLength > horizExp) { + + //calculate accuracy, correctness, positive examples covered by the description, resulted in a node + ParCELExtraNode newNode = checkAndCreateNewNodeV2(refinement, nodeToProcess); + + //check for the type of new node: weak description, partial definition, counter partial definition or potential description + if (newNode != null) { + + /* + * - completeness(D) = 0, i.e. cp(D) = empty: + * + correctness(D) = 1, i.e. cn(D) = empty ==> weak description + * + correctness(D) < 1, i.e. cn(D) != empty ==> counter partial definition + * - completeness(D) > 0, i.e. cp(D) != empty + * + correctness(D) = 1, i.e. cn(D) = empty ==> partial definition + * + correctness(D) < 1, i.e. cn(D) != empty ==> potential description + */ + + if (newNode.getCompleteness() == 0.0d) { + + //COUNTER PARTIAL DEFINITION: completeness=0 (cp=0) and correctness<1 (cn>0) + //NOTE: Note that the counter partial will be return in the negative form + if (newNode.getCorrectness() < 1d) { + newNode.setType(ParCELExNodeTypes.COUNTER_PARTIAL_DEFINITION_UNUSED); //0 + newNode.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); + newNode.setExtraInfo(learner.getTotalDescriptions()); + newNode.setDescription(df.getOWLObjectComplementOf(newNode.getDescription())); + newCounterPartialDefinitions.add(newNode); + } + } + else { + //PARTIAL DEFINITION + if (newNode.getCorrectness() == 1.0d) { + newNode.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); + newNode.setExtraInfo(learner.getTotalDescriptions()); + newNode.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_DIRECT_REFINED); //1 + newPartialDefinitions.add(newNode); + } + //DESCRIPTION + else { + + //check for the combination with the current counter partial definition set + Set combinableCounterPartialDefinitions = + ParCELExCombineCounterPartialDefinition.getCombinable(newNode, learner.getCurrentCounterPartialDefinitions()); + + //PARTIAL DEFINITION + //the new description may be combined with the counter partial definitions to become a partial definition + if (combinableCounterPartialDefinitions != null) { + //for (ParCELExtraNode def : combinableCounterPartialDefinitions) { + newNode.setDescription(ParCELExUtilities.createIntersection(newNode.getDescription(), + combinableCounterPartialDefinitions, true)); + //def.setType(ParCELExNodeTypes.COUNTER_PARTIAL_DEFINITION_USED); //2 - to mark the counter definition had been used to generate the partial definition + //} + + //3 - means the partial definition is the result of the combination of a new refined description and a counter partial definition + newNode.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_ONLINE_COMBINATION); + newNode.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); + newNode.setExtraInfo(learner.getTotalDescriptions()); + newPartialDefinitions.add(newNode); + } + else //the new node cannot be combined ==> this is a DESCRIPTION + newNodes.add(newNode); + } + } + } //if (node != null) + } + } // while (refinements.size > 0) + + horizExp = nodeToProcess.getHorizontalExpansion(); + learner.updateMaxHorizontalExpansion(horizExp); + } + + //process the input node: check if is it potentially a partial definition + Set combinableCounterPartialDefinitions = + ParCELExCombineCounterPartialDefinition.getCombinable(nodeToProcess, learner.getCurrentCounterPartialDefinitions()); + + if (combinableCounterPartialDefinitions != null) { + //for (ParCELExtraNode def : combinableCounterPartialDefinitions) + nodeToProcess.setDescription(ParCELExUtilities.createIntersection( + nodeToProcess.getDescription(), combinableCounterPartialDefinitions, true)); + + ParCELExtraNode newPD = new ParCELExtraNode(nodeToProcess); + newPD.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); + newPD.setExtraInfo(learner.getTotalDescriptions()); + newPD.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_REFINED_NODE); //4 - (refined node + counter pdef) + newPartialDefinitions.add(newPD); + } + else + newNodes.add(nodeToProcess); + + + if (newPartialDefinitions.size() > 0) + learner.newPartialDefinitionsFound(newPartialDefinitions); + + if (newCounterPartialDefinitions.size() > 0) + learner.newCounterPartialDefinitionsFound(newCounterPartialDefinitions); + + learner.newRefinementDescriptions(newNodes); //don't need to check for empty since newNodes is never empty + + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java new file mode 100644 index 0000000000..bf85d65fa7 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java @@ -0,0 +1,499 @@ +package org.dllearner.algorithms.parcelex; + +/** + * This class implements a extended version of PDLL which make use of the partial definitions, i.e. + * descriptions that cover none of the positive examples and some (>0) negative examples. + * + * In this implementation, the counter partial definitions will be used in the two cases: + * 1. For the learning termination: The learner will be terminated if one of the following conditions is reached: + * - all positive examples covered by the partial definitions + * - all negative examples covered by the counter partial definitions + * - timeout is reached + * 2. For getting more partial definition from the combination of counter partial definitions and the descriptions in the search tree + * + * @author An C. Tran + */ + +import org.dllearner.algorithms.parcel.*; +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentInitException; +import org.dllearner.utilities.owl.OWLAPIRenderers; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; + +import java.util.*; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; + +@ComponentAnn(name="ParCELearnerExV1", shortName="parcelearnerExV1", version=0.1, description="Parallel Class Expression Logic Learning") +public class ParCELearnerExV1 extends ParCELExAbstract { + + private int noOfCompactedPartialDefinition = 0; + + + /** + * Descriptions that can be combined with the counter partial definitions to become partial definitions + */ + SortedSet potentialPartialDefinitions; + + + /**=========================================================================================================
+ * Constructor for the learning algorithm + * + * @param learningProblem Must be a PDLLPosNegLP + * @param reasoningService A reasoner + */ + public ParCELearnerExV1(ParCELPosNegLP learningProblem, AbstractReasonerComponent reasoningService) { + super(learningProblem, reasoningService); + } + + + /** + * This constructor can be used by SpringDefinition to create bean object + * Properties of new bean may be initialised later using setters + */ + public ParCELearnerExV1() { + super(); + } + /**=========================================================================================================
+ * Get the name of this learning algorithm + * + * @return Name of this learning algorithm: PLLearning + */ + public static String getName() { + return "PLLearningReducer"; + } + + + /**=========================================================================================================
+ * Initial the learning algorithm + * - Create distance data + * - Prepare positive and negative examples (get from the learning problem (PLLearningPosNegLP) + * - Create a class hierarchy for refinement operator (for fast class herarchy checking) + * - Create expansion heuristic, which will be used to choose the expansion node in the search tree + * - Create refinement operator (RhoDRDown) + */ + @Override + public void init() throws ComponentInitException { + + //get the negative and positive examples + if (!(learningProblem instanceof ParCELPosNegLP)) + throw new ComponentInitException(learningProblem.getClass() + " is not supported by '" + getName() + "' learning algorithm"); + + + //get the positive and negative examples from the learning problem + positiveExamples = ((ParCELPosNegLP)learningProblem).getPositiveExamples(); + negativeExamples = ((ParCELPosNegLP)learningProblem).getNegativeExamples(); + + + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(this.positiveExamples); + + //initial heuristic which will be used by reducer to sort the search tree (expansion strategy) + //the heuristic need to get some constant from the configurator for scoring the description + heuristic = new ParCELDefaultHeuristic(); + + startClass = dataFactory.getOWLThing(); //this will be revise later using least common super class of all observations + + + this.uncoveredPositiveExampleAllowed = (int)Math.ceil(getNoisePercentage()*positiveExamples.size()); + + //initialise the existing uncovered positive examples + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); + + //---------------------------------- + //create refinement operator pool + //---------------------------------- + createRefinementOperatorPool(); + + baseURI = reasoner.getBaseURI(); + prefix = reasoner.getPrefixes(); + + + //logging the information (will use slf4j) + if (logger.isInfoEnabled()) { + logger.info("[pllearning] - Heuristic used: " + heuristic.getClass()); + logger.info("[pllearning] - Positive examples: " + positiveExamples.size() + ", negative examples: " + negativeExamples.size()); + } + + minNumberOfWorker = maxNumberOfWorker = numberOfWorkers; + + } //init() + + + + /**=========================================================================================================
+ * Start reducer + * 1. Reset the status of reducer (stop, isRunning, done, timeout)
+ * 2. Reset the data structure (using reset() method)
+ * 3. Create a set of workers and add them into the worker pool
+ * NOTE: Each worker will have it own refinement operator
+ * 4. Prepare some data: pos/neg examples, uncovered positive examples, etc.
+ * 5. Start the learning progress:
+ * i) refine nodes in the (tree set)
+ * ii) evaluate nodes in unevaluated nodes (hash set)
+ * + */ + @Override + public void start() { + reset(); + + initSearchTree(); + + createWorkerPool(); + + + //start time of reducer, statistical purpose only + miliStarttime = System.currentTimeMillis(); + + //---------------------------------------------------------- + // perform the learning process until the conditions for + // termination meets + //---------------------------------------------------------- + while (!isTerminateCriteriaSatisfied()) { + + ParCELNode nodeToProcess = searchTree.pollLast(); + + //TODO: why this? why "blocking" concept does not help in this case? + //remove this checking will exploit the heap memory and no definition found + //NOTE: i) instead of using sleep, can we use semaphore here? + // ii) if using semaphore or blocking, timeout checking may not be performed on time? + while ((workerPool.getQueue().size() >= maxTaskQueueLength)) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if ((nodeToProcess != null) && !workerPool.isShutdown() && !workerPool.isTerminating()) { + try { + this.createNewTask(nodeToProcess); + } + catch (RejectedExecutionException re) { + logger.error(re); + this.searchTree.add(nodeToProcess); + } + } + } //while the algorithm is not finish + + this.miliLearningTime = System.currentTimeMillis() - miliStarttime; + + stop(); + + //----------------------------------------------------------------------- + //try to combine descriptions in the search tree with the counter partial + //definition to find more partial definition + //----------------------------------------------------------------------- + + int newPartialDefCount = 0; + + //potential partial definitions + synchronized (this.potentialPartialDefinitions) { + logger.info("Processing potential partial definition: " + this.potentialPartialDefinitions.size()); + + for (ParCELExtraNode ppd : this.potentialPartialDefinitions) { + Set combinableCounterPartialDefinitions = + ParCELExCombineCounterPartialDefinition.getCombinable(ppd, this.counterPartialDefinitions); + + //new partial definition found if the description can be combined with the set of counter partial definitions + if (combinableCounterPartialDefinitions != null) { + + ParCELExtraNode newPD = new ParCELExtraNode(ppd); + + + //LinkedList tmpCounterDes = new LinkedList(); + //tmpCounterDes.add(ppd.getDescription()); + + //for (ParCELExtraNode def : combinableCounterPartialDefinitions) { + //tmpCounterDes.add(def.getDescription()); + //newPD.setDescription(new Intersection(newPD.getDescription(), def.getDescription())); + //def.setType(1); + //} + + newPD.setDescription(ParCELExUtilities.createIntersection(ppd.getDescription(), + combinableCounterPartialDefinitions, true)); + + this.uncoveredPositiveExamples.removeAll(ppd.getCoveredPositiveExamples()); + + newPD.setCompositeList(combinableCounterPartialDefinitions); + + newPD.setGenerationTime(System.currentTimeMillis() - miliStarttime); + newPD.setType(2); + + if (allDescriptions.add(newPD.getDescription())) { + partialDefinitions.add(newPD); + newPartialDefCount++; + } + + } //new partial definition found + } + } + + + //descriptions in the search tree + synchronized (this.searchTree) { + + if (logger.isInfoEnabled()) + logger.info("Finding partial defintions from the search tree: " + this.searchTree.size()); + + List newSearchTree = new ArrayList<>(this.searchTree); + newSearchTree.sort(new ParCELCompletenessComparator()); + + + for (ParCELNode des : newSearchTree) { + + synchronized (this.counterPartialDefinitions) { + Set combinableCounterPartialDefinitions = + ParCELExCombineCounterPartialDefinition.getCombinable(des, this.counterPartialDefinitions); + + //new partial definition found if the description can be combined with the set of counter partial definitions + if (combinableCounterPartialDefinitions != null) { + + ParCELExtraNode newPD = new ParCELExtraNode(des); + + + //LinkedList tmpCounterDes = new LinkedList(); + //tmpCounterDes.add(des.getDescription()); + + //for (ParCELExtraNode def : combinableCounterPartialDefinitions) { + //tmpCounterDes.add(def.getDescription()); + //newPD.setDescription(new Intersection(newPD.getDescription(), def.getDescription())); + //def.setType(1); + //} + + newPD.setDescription(ParCELExUtilities.createIntersection(des.getDescription(), + combinableCounterPartialDefinitions, true)); + + this.uncoveredPositiveExamples.removeAll(des.getCoveredPositiveExamples()); + + newPD.setCompositeList(combinableCounterPartialDefinitions); + + //PDLLExtraNode newPD = new PDLLExtraNode(des); + newPD.setGenerationTime(System.currentTimeMillis() - miliStarttime); + newPD.setType(2); + + if (allDescriptions.add(newPD.getDescription())) { + partialDefinitions.add(newPD); + newPartialDefCount++; + } + + } //new partial definition found + } //synch counter partial definition for processing + + } //for each description in the search tree + + } //synch search tree + + if (logger.isInfoEnabled()) + logger.info(newPartialDefCount + " new partial definition found"); + + + //------------------------------------ + // post-learning processing: + // reduce the partial definitions + //------------------------------------ + if (logger.isInfoEnabled()) { + synchronized (partialDefinitions) { + if (this.getCurrentlyOveralMaxCompleteness() == 1) + logger.info("Learning finishes in: " + this.miliLearningTime + "ms, with: " + partialDefinitions.size() + " definitions"); + else if (this.isTimeout()) { + logger.info("Learning timeout in " + this.maxExecutionTimeInSeconds + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); + logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); + } + else { + logger.info("Learning is manually terminated at " + this.miliLearningTime + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); + logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); + } + + logger.info("**Reduced partial definitions:"); + TreeSet compactedDefinitions = (TreeSet) this.getReducedPartialDefinition(); + this.noOfCompactedPartialDefinition = compactedDefinitions.size(); + int count = 1; + for (ParCELExtraNode def : compactedDefinitions) { + logger.info(count++ + ". " + OWLAPIRenderers.toManchesterOWLSyntax(ParCELExUtilities.groupDefinition(def.getDescription())).replace("and (not", "\nand (not") + //def.getDescription().toManchesterSyntaxString(baseURI, prefix) + + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + + ", accuracy: " + df.format(def.getAccuracy()) + + ", type: " + def.getType() + ")"); + + //print out the learning tree + if (logger.isDebugEnabled()) { + printSearchTree(def); + } + } + } + } + + super.aggregateCounterPartialDefinitionInf(); + + } + + + + + private void createNewTask(ParCELNode nodeToProcess) { + workerPool.execute(new ParCELWorkerExV1(this, this.refinementOperatorPool, + (ParCELPosNegLP)learningProblem, nodeToProcess, "PDLLTask-" + (noOfTask++))); + } + + /** + * This function is used to process the counter partial definitions: description which + */ + @Override + public void newCounterPartialDefinitionsFound(Set counterPartialDefinitions) { + + for (ParCELExtraNode def : counterPartialDefinitions) { + + //calculate the "actual" number of negative examples covered by the new definition + int numberOfNewCoveredNegativeExamples; + int numberOfCoveredNegativeExamples; ///for avoiding synchronized coveredNegativeExamples later on + + synchronized (this.coveredNegativeExamples) { + numberOfNewCoveredNegativeExamples = this.coveredNegativeExamples.size(); + this.coveredNegativeExamples.addAll(def.getCoveredNegativeExamples()); + numberOfNewCoveredNegativeExamples = this.coveredNegativeExamples.size() - numberOfNewCoveredNegativeExamples; + numberOfCoveredNegativeExamples = this.coveredNegativeExamples.size(); + } + + //process the counter partial definition if it covers at least 1 new negative example + if (numberOfNewCoveredNegativeExamples > 0) { + + //add the new counter partial definition into the set of counter partial definitions + synchronized (this.counterPartialDefinitions) { + this.counterPartialDefinitions.add(def); + } + + //NOTE: when a partial definition found, we update the set of uncovered positive examples for the Learning Problem + // but there is no need to do it for the counter partial definition, i.e. no update for covered negative examples + if (logger.isTraceEnabled() || logger.isDebugEnabled()) { + logger.trace("COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() + ); + } else if (logger.isInfoEnabled()) { + logger.info("COUNTER PARTIAL definition found. Total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size()); + } + + //complete counter definition found + if (this.coveredNegativeExamples.size() >= this.negativeExamples.size()) { + this.counterDone = true; + //this.stop(); + } + } + + } + + } + + /**=========================================================================================================
+ * Reset all necessary properties for a new learning + * 1. Create new search tree + * 2. Create an empty description set, which hold all generated description (to avoid redundancy) + * 3. Create an empty + */ + private void reset() { + stop = false; + done = false; + timeout = false; + counterDone = false; + + this.noOfCompactedPartialDefinition = 0; + + this.searchTree = new ConcurrentSkipListSet<>(heuristic); + + //allDescriptions = new TreeSet(new ConceptComparator()); + this.allDescriptions = new ConcurrentSkipListSet<>(); + + this.partialDefinitions = new TreeSet<>(new ParCELCompletenessComparator()); + this.counterPartialDefinitions = new TreeSet<>(new ParCELCoveredNegativeExampleComparator()); + this.potentialPartialDefinitions = new TreeSet<>(new ParCELCompletenessComparator()); + + //clone the positive examples for this set + this.uncoveredPositiveExamples = new HashSet<>(); + this.uncoveredPositiveExamples.addAll(this.positiveExamples); //create a copy of positive examples used to check the completeness + + this.coveredNegativeExamples = new HashSet<>(); + + descriptionTested = 0; + maxAccuracy = 0; + + //create a start node in the search tree + allDescriptions.add(startClass); //currently, start class is always Thing + + } + + + /**=========================================================================================================
+ * Stop the learning algorithm: Stop the workers and set the "stop" flag to true + */ + @Override + public void stop() { + + if (!stop) { + stop = true; + + List waitingTasks = workerPool.shutdownNow(); + + try { + workerPool.awaitTermination(0, TimeUnit.SECONDS); + } + catch (InterruptedException ie) { + logger.error(ie); + } + + //put the unexecuted tasks back to the search tree + synchronized (this.searchTree) { + logger.debug("Put incompleted task back to the search tree: " + waitingTasks.size()); + for (Runnable node : waitingTasks) + searchTree.add(((ParCELWorkerExV1)node).getProcessingNode()); + } + } + } + + + + /**=========================================================================================================
+ * Get the overall completeness of all partial definition found + * + * @return Overall completeness so far + */ + public double getCurrentlyOveralMaxCompleteness() { + return 1 - (uncoveredPositiveExamples.size()/(double)positiveExamples.size()); + } + + //methods related to the compactness: get compact definition, set compactor + public SortedSet getReducedPartialDefinition(ParCELReducer reducer) { + return reducer.reduce(partialDefinitions, positiveExamples, uncoveredPositiveExamples.size()); + } + + + public SortedSet getReducedPartialDefinition() { + return this.getReducedPartialDefinition(this.reducer); + } + + + public void setCompactor(ParCELReducer newReducer) { + this.reducer = newReducer; + } + + + //------------------------------------------ + // getters for learning results + //------------------------------------------ + public int getClassExpressionTests() { + return descriptionTested; + } + + //------------------------------------------------ + // setters and getters for configuration options + //------------------------------------------------ + public int getNoOfReducedPartialDefinition() { + return this.noOfCompactedPartialDefinition; + } + + public SortedSet getCurrentCounterPartialDefinitions() { + return this.counterPartialDefinitions; + } + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java new file mode 100644 index 0000000000..b45fb4c0d2 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -0,0 +1,868 @@ +package org.dllearner.algorithms.parcelex; + +/** + * This class implements a extended version of PDLL which make use of the partial definitions, i.e. + * descriptions that cover none of the positive examples and some (>0) negative examples. + * + * In this implementation, the counter partial definitions will be used in the two cases: + * 1. For the learning termination: The learner will be terminated if one of the following conditions is reached: + * - all positive examples covered by the partial definitions + * - all negative examples covered by the counter partial definitions + * - timeout is reached + * 2. For getting more partial definition from the combination of counter partial definitions and the descriptions in the search tree + * + * @author An C. Tran + */ + +import java.text.DecimalFormat; +import java.util.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.text.*; + +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELCompletenessComparator; +import org.dllearner.algorithms.parcel.ParCELDefaultHeuristic; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELCoveredNegativeExampleComparator; +import org.dllearner.algorithms.parcel.ParCELHeuristic; +import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer; +//import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer_V2; + +import org.dllearner.algorithms.parcel.ParCELNode; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.dllearner.algorithms.parcel.ParCELRefinementOperatorPool; +import org.dllearner.algorithms.parcel.ParCELStringUtilities; +import org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterAbstract; +import org.dllearner.algorithms.celoe.OENode; +import org.dllearner.algorithms.parcel.ParCELWorkerThreadFactory; +import org.dllearner.core.*; +import org.dllearner.core.owl.ClassHierarchy; +import org.dllearner.refinementoperators.RefinementOperator; + +import org.dllearner.utilities.owl.OWLAPIRenderers; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.springframework.beans.factory.annotation.Autowired; +import org.dllearner.algorithms.parcel.ParCELearnerMBean; + +@ComponentAnn(name="ParCELearnerExV12", shortName="parcelearnerExV12", version=0.1, description="Parallel Class Expression Logic Learning with Exception") +public class ParCELearnerExV12 extends ParCELExAbstract implements ParCELearnerMBean { + + private static Logger logger = Logger.getLogger(ParCELearnerExV12.class); + + //configuration for worker pool + protected final int maxTaskQueueLength = 1000; + + /** + * Descriptions that can be combined with the counter partial definitions to become partial definitions + */ + protected ConcurrentSkipListSet potentialPartialDefinitions; + + + /**=========================================================================================================
+ * Constructor for the learning algorithm + * + * @param learningProblem Must be a PDLLPosNegLP + * @param reasoningService A reasoner + */ + public ParCELearnerExV12(ParCELPosNegLP learningProblem, AbstractReasonerComponent reasoningService) { + super(learningProblem, reasoningService); + + //default compactor used by this algorithm + this.reducer = new ParCELImprovedCoverageGreedyReducer(); + } + + + /** + * This constructor can be used by SpringDefinition to create bean object + * Properties of new bean may be initialised later using setters + */ + public ParCELearnerExV12() { + super(); + //this.compactor = new PDLLGenerationTimeCompactor(); + this.reducer = new ParCELImprovedCoverageGreedyReducer(); + //this.compactor = new PDLLDefinitionLengthCompactor(); + } + /**=========================================================================================================
+ * Get the name of this learning algorithm + * + * @return Name of this learning algorithm: PLLearning + */ + public static String getName() { + return "PLLearningReducer"; + } + + private double getCurrentAccuracy() + { + double acc = (this.negativeExamples.size() + this.positiveExamples.size() - + this.uncoveredPositiveExamples.size())/ + (double) (this.positiveExamples.size() + this.negativeExamples.size()); + return acc; + } + + /**=========================================================================================================
+ * Initial the learning algorithm + * - Create distance data + * - Prepare positive and negative examples (get from the learning problem (PLLearningPosNegLP) + * - Create a class hierarchy for refinement operator (for fast class herarchy checking) + * - Create expansion heuristic, which will be used to choose the expansion node in the search tree + * - Create refinement operator (RhoDRDown) + */ + @Override + public void init() throws ComponentInitException { + + //get the negative and positive examples + if (!(learningProblem instanceof ParCELPosNegLP)) + throw new ComponentInitException(learningProblem.getClass() + " is not supported by '" + getName() + "' learning algorithm"); + + + //get the positive and negative examples from the learning problem + positiveExamples = ((ParCELPosNegLP)learningProblem).getPositiveExamples(); + negativeExamples = ((ParCELPosNegLP)learningProblem).getNegativeExamples(); + positiveTestExamples = ((ParCELPosNegLP) learningProblem).getPositiveTestExamples(); + negativeTestExamples = ((ParCELPosNegLP) learningProblem).getNegativeTestExamples(); + + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(this.positiveExamples); + + //initial heuristic which will be used by reducer to sort the search tree (expansion strategy) + //the heuristic need to get some constant from the configurator for scoring the description + if (heuristic == null) { + heuristic = new ParCELDefaultHeuristic(); + } + + //this will be revise later using least common super class of all observations + if (startClass == null) { + startClass = dataFactory.getOWLThing(); + } + + this.uncoveredPositiveExampleAllowed = (int)Math.ceil((getNoisePercentage()/100)*positiveExamples.size()); + logger.info("Uncovered positive examples allowed (noise): " + this.uncoveredPositiveExampleAllowed); + + //initialise the existing uncovered positive examples + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); + + //---------------------------------- + //create refinement operator pool + //---------------------------------- + initOperatorIfAny(); + createRefinementOperatorPool(); + + baseURI = reasoner.getBaseURI(); + prefix = reasoner.getPrefixes(); + + + //logging the information (will use slf4j) + if (logger.isInfoEnabled()) { + logger.info("[pllearning] - Heuristic used: " + heuristic.getClass()); + logger.info("[pllearning] - Positive examples: " + positiveExamples.size() + ", negative examples: " + negativeExamples.size()); + } + + minNumberOfWorker = maxNumberOfWorker = numberOfWorkers; + + trainingTime = System.currentTimeMillis(); + + } //init() + + + + /**=========================================================================================================
+ * Start reducer + * 1. Reset the status of reducer (stop, isRunning, done, timeout)
+ * 2. Reset the data structure (using reset() method)
+ * 3. Create a set of workers and add them into the worker pool
+ * NOTE: Each worker will have it own refinement operator
+ * 4. Prepare some data: pos/neg examples, uncovered positive examples, etc.
+ * 5. Start the learning progress:
+ * i) refine nodes in the (tree set)
+ * ii) evaluate nodes in unevaluated nodes (hash set)
+ * + */ + @Override + public void start() { + + // register a MBean for debugging purpose + /* + try { + ObjectName parCELExV1Bean = new ObjectName( + "org.dllearner.algorithms.parcel.ParCELearnerMBean:type=ParCELearnerExV1Bean"); + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + if (!mbs.isRegistered(parCELExV1Bean)) + mbs.registerMBean(this, parCELExV1Bean); + } catch (Exception e) { + e.printStackTra + */ + + stop = false; + done = false; + timeout = false; + counterDone = false; + + this.noOfCompactedPartialDefinition = 0; + + reset(); + + initSearchTree(); + + ParCELNode startNode = searchTree.first(); + startNode.setCoveredPositiveExamples(positiveExamples); + startNode.setCoveredNegativeExamples(negativeExamples); + + createWorkerPool(); + + //start time of reducer, statistical purpose only + miliStarttime = System.currentTimeMillis(); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + + //---------------------------------------------------------- + // perform the learning process until the conditions for + // termination meets + //---------------------------------------------------------- + while (!isTerminateCriteriaSatisfied()) { + + //------------------- + //check for timeout + //------------------- + timeout = (this.maxExecutionTimeInSeconds > 0 && (getCurrentCpuMillis()) > this.maxExecutionTimeInSeconds*1000); + + if (timeout) + break; + + ParCELNode nodeToProcess; + + nodeToProcess = searchTree.pollLast(); + + //TODO: why this? why "blocking" concept does not help in this case? + //remove this checking will exploit the heap memory and no definition found + //NOTE: i) instead of using sleep, can we use semaphore here? + // ii) if using semaphore or blocking, timeout checking may not be performed on time? + while ((workerPool.getQueue().size() >= maxTaskQueueLength)) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if ((nodeToProcess != null) && !workerPool.isShutdown() && !workerPool.isTerminating()) { + try { + this.createNewTask(nodeToProcess); + } + catch (RejectedExecutionException re) { + logger.error(re); + this.searchTree.add(nodeToProcess); + } + } + } //while the algorithm is not finish + + this.miliLearningTime = System.currentTimeMillis() - miliStarttime; + + stop(); + + //----------------------------------------------------------------------- + //try to combine descriptions in the search tree with the counter partial + //definition to find more partial definition + //----------------------------------------------------------------------- + + int newPartialDefCount = 0; + + //potential partial definitions + /* + synchronized (this.potentialPartialDefinitions) { + logger.info("Processing potential partial definition: " + this.potentialPartialDefinitions.size()); + + for (ParCELExtraNode ppd : this.potentialPartialDefinitions) { + Set combinableCounterPartialDefinitions = + ParCELCombineCounterPartialDefinition.getCombinable(ppd, this.counterPartialDefinitions); + + //new partial definition found if the description can be combined with the set of counter partial definitions + if (combinableCounterPartialDefinitions != null) { + + ParCELExtraNode newPD = new ParCELExtraNode(ppd); + + + LinkedList tmpCounterDes = new LinkedList(); + tmpCounterDes.add(ppd.getDescription()); + + for (ParCELExtraNode def : combinableCounterPartialDefinitions) { + tmpCounterDes.add(def.getDescription()); + //newPD.setDescription(new Intersection(newPD.getDescription(), def.getDescription())); + def.setType(1); + } + + newPD.setDescription(new Intersection(tmpCounterDes)); + + this.uncoveredPositiveExamples.removeAll(ppd.getCoveredPositiveExamples()); + + newPD.setCompositeList(combinableCounterPartialDefinitions); + + newPD.setGenerationTime(System.currentTimeMillis() - miliStarttime); + newPD.setType(2); + + if (allDescriptions.add(newPD.getDescription())) { + partialDefinitions.add(newPD); + newPartialDefCount++; + } + + } //new partial definition found + } //for + } //synchronise potential partial definitions + */ + + //descriptions in the search tree + synchronized (this.searchTree) { + + if (logger.isInfoEnabled()) + logger.info("Finding partial defintions from the search tree: " + this.searchTree.size()); + + List newSearchTree = new ArrayList<>(this.searchTree); + newSearchTree.sort(new ParCELCompletenessComparator()); + + + for (ParCELNode des : newSearchTree) { + + synchronized (this.counterPartialDefinitions) { + Set combinableCounterPartialDefinitions = + ParCELExCombineCounterPartialDefinition.getCombinable(des, this.counterPartialDefinitions); + + //new partial definition found if the description can be combined with the set of counter partial definitions + if (combinableCounterPartialDefinitions != null) { + + ParCELExtraNode newPD = new ParCELExtraNode(des); + + + /* + LinkedList tmpCounterDes = new LinkedList(); + tmpCounterDes.add(des.getDescription()); + + for (ParCELExtraNode def : combinableCounterPartialDefinitions) { + tmpCounterDes.add(def.getDescription()); + //newPD.setDescription(new Intersection(newPD.getDescription(), def.getDescription())); + def.setType(1); + } + */ + + newPD.setDescription(ParCELExUtilities.createIntersection(des.getDescription(), + combinableCounterPartialDefinitions, true)); + + this.uncoveredPositiveExamples.removeAll(des.getCoveredPositiveExamples()); + + newPD.setCompositeList(combinableCounterPartialDefinitions); + + //PDLLExtraNode newPD = new PDLLExtraNode(des); + newPD.setGenerationTime(System.currentTimeMillis() - miliStarttime); + newPD.setType(2); + + if (allDescriptions.add(newPD.getDescription())) { + partialDefinitions.add(newPD); + newPartialDefCount++; + } + + } //new partial definition found + } //synch counter partial definition for processing + + } //for each description in the search tree + + } //synch search tree + + if (logger.isInfoEnabled()) + logger.info(newPartialDefCount + " new partial definition found"); + + + //------------------------------------ + // post-learning processing: + // reduce the partial definitions + //------------------------------------ + if (logger.isInfoEnabled()) { + synchronized (partialDefinitions) { + if (this.getCurrentlyOveralMaxCompleteness() == 1) + logger.info("Learning finishes in: " + this.miliLearningTime + "ms, with: " + partialDefinitions.size() + " definitions"); + else if (this.isTimeout()) { + logger.info("Learning timeout in " + this.maxExecutionTimeInSeconds + "s. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); + logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); + } + else { + logger.info("Learning is manually terminated at " + this.miliLearningTime + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); + logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); + } + + logger.info("**Reduced partial definitions:"); + TreeSet compactedDefinitions = (TreeSet) this.getReducedPartialDefinition(); + this.noOfCompactedPartialDefinition = compactedDefinitions.size(); + int count = 1; + for (ParCELExtraNode def : compactedDefinitions) { + logger.info(count++ + ". " + OWLAPIRenderers.toManchesterOWLSyntax(ParCELExUtilities.groupDefinition(def.getDescription())).replace("and (not", "\nand (not") + //def.getDescription().toManchesterSyntaxString(baseURI, prefix) + + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + + ", accuracy: " + df.format(def.getAccuracy()) + " / " + computeTestAccuracy(def.getDescription()) + + ", type: " + def.getType() + ")"); + + //print out the learning tree + if (logger.isDebugEnabled()) { + List processingNodes = new LinkedList<>(); + + processingNodes.add(def); + + processingNodes.addAll(def.getCompositeNodes()); + + for (OENode n : processingNodes) { + OENode parent = n.getParent(); + while (parent != null) { + logger.debug(" <-- " + OWLAPIRenderers.toManchesterOWLSyntax(parent.getDescription())); + //" [acc:" + df.format(parent.getAccuracy()) + + //", correctness:" + df.format(parent.getCorrectness()) + ", completeness:" + df.format(parent.getCompleteness()) + + //", score:" + df.format(this.heuristic.getScore(parent)) + "]"); + + //print out the children nodes + Collection children = parent.getChildren(); + for (OENode child : children) { + OENode tmp = child; + logger.debug(" --> " + OWLAPIRenderers.toManchesterOWLSyntax(tmp.getDescription())); + //" [acc:" + df.format(tmp.getAccuracy()) + + //", correctness:" + df.format(tmp.getCorrectness()) + ", completeness:" + df.format(tmp.getCompleteness()) + + //", score:" + df.format(this.heuristic.getScore(tmp)) + "]"); + } + parent = parent.getParent(); + } //while parent is not null + + logger.debug("==============="); + + } //for end of printing the learning tree + + } //if in the debug mode: Print the learning tree + + } + + printBestConceptsTimesAndAccuracies(); + } + } + + super.aggregateCounterPartialDefinitionInf(); + + } //start() + + + private void createNewTask(ParCELNode nodeToProcess) { + workerPool.execute(new ParCELWorkerExV12(this, this.refinementOperatorPool, + (ParCELPosNegLP)learningProblem, nodeToProcess, "PDLLTask-" + (noOfTask++))); + } + + + + /**=========================================================================================================
+ * Callback method for worker when a partial definition found + * (callback for an evaluation request from reducer)
+ * If a definition (partial) found, do the following tasks:
+ * 1. Add the definition into the partial definition set
+ * 2. Update: uncovered positive examples, max accuracy, best description length + * 2. Check for the completeness of the learning. If yes, stop the learning
+ * + * @param definitions New partial definitions + */ + @Override + public void newPartialDefinitionsFound(Set definitions) { + + for (ParCELExtraNode def : definitions) { + + //NOTE: in the previous version, this node will be added back into the search tree + // it is not necessary since in DLLearn, a definition may be revised to get a better one but + // in this approach, we do not refine partial definition. + + //remove uncovered positive examples by the positive examples covered by the new partial definition + int uncoveredPositiveExamplesRemoved; + int uncoveredPositiveExamplesSize; //for avoiding synchronized uncoveredPositiveExamples later on + + synchronized (uncoveredPositiveExamples) { + uncoveredPositiveExamplesRemoved = this.uncoveredPositiveExamples.size(); + this.uncoveredPositiveExamples.removeAll(def.getCoveredPositiveExamples()); + uncoveredPositiveExamplesSize = this.uncoveredPositiveExamples.size(); + } + + uncoveredPositiveExamplesRemoved -= uncoveredPositiveExamplesSize; + + if (uncoveredPositiveExamplesRemoved > 0) { + + //set the generation time for the new partial definition + def.setGenerationTime(System.currentTimeMillis() - miliStarttime); + synchronized (partialDefinitions) { + partialDefinitions.add(def); + } + + //update the uncovered positive examples for the learning problem + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); + + if (logger.isTraceEnabled()) { + logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + ); + } + else if (logger.isDebugEnabled()) + logger.debug("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + ); + else if (logger.isInfoEnabled()) { + logger.info("PARTIAL definition found. Uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info(timeStamp + ": " + def); + + double acc = this.getCurrentAccuracy(); + double actualTrainingTime = getCurrentCpuMillis() / 1000.0; + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double testAcc = computeTestAccuracy(bestDescription); + + logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); + + recordBestConceptTimeAndAccuracy(actualTrainingTime, acc, testAcc); + } + + //update the max accuracy and max description length + if (def.getAccuracy() > this.maxAccuracy) { + this.maxAccuracy = def.getAccuracy(); + this.bestDescriptionLength = new OWLClassExpressionLengthCalculator().getLength(def.getDescription()); + } + + //check if the complete definition found + if (uncoveredPositiveExamplesSize <= uncoveredPositiveExampleAllowed) { + this.done = true; + //stop(); + } + + + } + + + } //for each partial definition + + } //definitionFound() + + + /** + * This will be called by the workers to return the descriptions that can be combined with the + * counter partial definitions to create partial definitions + * + * @param potentialPartialDefinitions Descriptions that are + */ + public void newPotentialPartialDefinition(Set potentialPartialDefinitions) { + + //for each potential partial definition, update list of positive examples + // that are covered by the partial definitions + + for (ParCELExtraNode def : potentialPartialDefinitions) { + if (this.potentialPartialDefinitions.add(def.getDescription())) { + synchronized (uncoveredPositiveExamples) { + this.uncoveredPositiveExamples.removeAll(def.getCoveredPositiveExamples()); + + } + this.potentialPartialDefinitions.add(def.getDescription()); + + int uncoveredPositiveExamplesSize = uncoveredPositiveExamples.size(); + + //if (logger.isInfoEnabled()) + // logger.info("POTENTIAL PARTIAL DEFINITION found." + "Uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + //else if (logger.isDebugEnabled()) + // logger.debug("POTENTIAL PARTIAL DEFINITION found. " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + // "Uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + + + //check if the complete definition found + if (uncoveredPositiveExamplesSize <= uncoveredPositiveExampleAllowed) + this.done = true; + } + else + logger.info("Potential partial definition existed :" + def.getDescription()); + } + + } + + + /** + * This function is used to process the counter partial definitions: description which + */ + @Override + public void newCounterPartialDefinitionsFound(Set counterPartialDefinitions) { + + for (ParCELExtraNode def : counterPartialDefinitions) { + + //calculate the "actual" number of negative examples covered by the new definition + int numberOfNewCoveredNegativeExamples; + int numberOfCoveredNegativeExamples; ///for avoiding synchronized coveredNegativeExamples later on + + synchronized (this.coveredNegativeExamples) { + numberOfNewCoveredNegativeExamples = this.coveredNegativeExamples.size(); + this.coveredNegativeExamples.addAll(def.getCoveredNegativeExamples()); + numberOfNewCoveredNegativeExamples = this.coveredNegativeExamples.size() - numberOfNewCoveredNegativeExamples; + numberOfCoveredNegativeExamples = this.coveredNegativeExamples.size(); + } + + //process the counter partial definition if it covers at least 1 new negative example + if (numberOfNewCoveredNegativeExamples > 0) { + + //add the new counter partial definition into the set of counter partial definitions + synchronized (this.counterPartialDefinitions) { + this.counterPartialDefinitions.add(def); + } + + //NOTE: when a partial definition found, we update the set of uncovered positive examples for the Learning Problem + // but there is no need to do it for the counter partial definition, i.e. no update for covered negative examples + if (logger.isTraceEnabled()) { + logger.trace("COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() + ); + } + else if (logger.isDebugEnabled()) + logger.debug("COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() + ); + else if (logger.isInfoEnabled()) { + logger.info("COUNTER PARTIAL definition found. Total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size()); + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info(timeStamp + ": " + def); + + double acc = this.getCurrentAccuracy(); + double actualTrainingTime = getCurrentCpuMillis() / 1000.0; + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double testAcc = computeTestAccuracy(bestDescription); + + logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); + + recordBestConceptTimeAndAccuracy(actualTrainingTime, acc, testAcc); + } + + //complete counter definition found + if (this.coveredNegativeExamples.size() >= this.negativeExamples.size()) { + this.counterDone = true; + //this.stop(); + } + } + + } + + } + + /**=========================================================================================================
+ * Callback method for worker to call when it gets an evaluated node which is neither a partial definition + * nor a weak description
+ * + * NOTE: there is not need for using synchronisation for this method since the thread safe + * data structure is currently using + * + * @param newNodes New nodes to add to the search tree + */ + @Override + public void newRefinementDescriptions(Set newNodes) { + searchTree.addAll(newNodes); + } + + + /**=========================================================================================================
+ * Reset all necessary properties for a new learning + * 1. Create new search tree + * 2. Create an empty description set, which hold all generated description (to avoid redundancy) + * 3. Create an empty + */ + private void reset() { + this.searchTree = new ConcurrentSkipListSet<>(heuristic); + + //allDescriptions = new TreeSet(new ConceptComparator()); + this.allDescriptions = new ConcurrentSkipListSet<>(); + + this.partialDefinitions = new TreeSet<>(new ParCELCompletenessComparator()); + this.counterPartialDefinitions = new TreeSet<>(new ParCELCoveredNegativeExampleComparator()); + this.potentialPartialDefinitions = new ConcurrentSkipListSet<>(); + + //clone the positive examples for this set + this.uncoveredPositiveExamples = new HashSet<>(); + this.uncoveredPositiveExamples.addAll(this.positiveExamples); //create a copy of positive examples used to check the completeness + + this.coveredNegativeExamples = new HashSet<>(); + + descriptionTested = 0; + maxAccuracy = 0; + } + + /**=========================================================================================================
+ * Stop the learning algorithm: Stop the workers and set the "stop" flag to true + */ + @Override + public void stop() { + + if (!stop) { + stop = true; + + List waitingTasks = workerPool.shutdownNow(); + + try { + workerPool.awaitTermination(10, TimeUnit.SECONDS); + } + catch (InterruptedException ie) { + logger.error(ie); + } + + //put the unexecuted tasks back to the search tree + synchronized (this.searchTree) { + logger.debug("Put incompleted task back to the search tree: " + waitingTasks.size()); + for (Runnable node : waitingTasks) + searchTree.add(((ParCELWorkerExV12)node).getProcessingNode()); + } + } + } + + + /**=========================================================================================================
+ * Get the overall completeness of all partial definition found + * + * @return Overall completeness so far + */ + public double getCurrentlyOveralMaxCompleteness() { + return 1 - (uncoveredPositiveExamples.size()/(double)positiveExamples.size()); + } + + + + //methods related to the compactness: get compact definition, set compactor + public SortedSet getReducedPartialDefinition(ParCELReducer reducer) { + return reducer.reduce(partialDefinitions, positiveExamples, uncoveredPositiveExamples.size()); + } + + + public SortedSet getReducedPartialDefinition() { + return this.getReducedPartialDefinition(this.reducer); + } + + + public void setCompactor(ParCELReducer newReducer) { + this.reducer = newReducer; + } + + + //------------------------------------------ + // getters for learning results + //------------------------------------------ + + public double getMaxAccuracy() { + return maxAccuracy; + } + + + public int getCurrentlyBestDescriptionLength() { + return bestDescriptionLength; + } + + + @Override + public boolean isRunning() { + return !stop && !done && !timeout; + } + + + public int getClassExpressionTests() { + return descriptionTested; + } + + + public int getSearchTreeSize() { + return (searchTree!= null? searchTree.size() : -1); + } + + + public Set getPartialDefinitions() { + return partialDefinitions; + } + + + /* + public Set getSearchTree() { + return searchTree; + } + */ + + public Collection getSearchTree() { + return searchTree; + } + + + public ParCELHeuristic getHeuristic() { + return heuristic; + } + + + public boolean isTimeout() { + return timeout; + } + + + public boolean isDone() { + return done; + } + + + public long getLearningTime() { + return miliLearningTime; + } + + //------------------------------------------------ + // setters and getters for configuration options + //------------------------------------------------ + + public int getNoOfReducedPartialDefinition() { + return this.noOfCompactedPartialDefinition; + } + + @Override + public boolean terminatedByCounterDefinitions() { + return this.counterDone; + } + + @Override + public boolean terminatedByPartialDefinitions() { + return this.done; + } + + + public SortedSet getCurrentCounterPartialDefinitions() { + return this.counterPartialDefinitions; + } + + @Override + public long getTotalNumberOfDescriptionsGenerated() { + return allDescriptions.size(); + } + + @Override + public long getTotalDescriptions() { + + return allDescriptions.size(); + } + + @Override + public double getCurrentlyBestAccuracy() { + return ((positiveExamples.size() - uncoveredPositiveExamples.size()) + negativeExamples.size()) / + (double)(positiveExamples.size() + negativeExamples.size()); + } + + @Override + public int getWorkerPoolSize() { + return this.workerPool.getQueue().size(); + } + + @Override + public int getCurrentlyMaxExpansion() { + // TODO Auto-generated method stub + return this.maxHorizExp; + } + + +} diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java new file mode 100644 index 0000000000..b3e165a1da --- /dev/null +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java @@ -0,0 +1,606 @@ +package org.dllearner.algorithms.parcelex; + +/** + * This class implements a extended version of PDLL which make use of the partial definitions, i.e. + * descriptions that cover none of the positive examples and some (>0) negative examples. + * + * In this implementation, the counter partial definitions will be used directly by the workers to check if they can be used + * to combine with the new description to become a partial definition. + * + * Therefore, there is no usage of the counter partial definition in the learner side + * + * @author An C. Tran + */ + +import java.util.*; +import java.util.concurrent.*; + +import org.dllearner.algorithms.celoe.OENode; +import org.dllearner.algorithms.parcel.*; +import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer; +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentInitException; +import org.dllearner.core.owl.ClassHierarchy; +import org.dllearner.utilities.owl.OWLAPIRenderers; +import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLDataProperty; + + +@ComponentAnn(name="ParCELearnerExV2", shortName="parcelLearnerExV2", version=0.1, description="Parallel Class Expression Logic Learning with Exception V2") +public class ParCELearnerExV2 extends ParCELExAbstract implements ParCELearnerMBean { + + private int noOfReducedPartialDefinition = 0; + + + /**=========================================================================================================
+ * Constructor for the learning algorithm + * + * @param learningProblem Must be a PDLLPosNegLP + * @param reasoningService A reasoner + */ + public ParCELearnerExV2(ParCELPosNegLP learningProblem, AbstractReasonerComponent reasoningService) { + super(learningProblem, reasoningService); + } + + + /** + * This constructor can be used by SpringDefinition to create bean object + * Properties of new bean may be initialised later using setters + */ + public ParCELearnerExV2() { + super(); + //this.compactor = new PDLLGenerationTimeCompactor(); + this.reducer = new ParCELImprovedCoverageGreedyReducer(); + //this.compactor = new PDLLDefinitionLengthCompactor(); + //this.reducer = new ParCELPredScoreReducer(); + } + /**=========================================================================================================
+ * Get the name of this learning algorithm + * + * @return Name of this learning algorithm: PLLearning + */ + public static String getName() { + return "ParCELLearnerExV2"; + } + + + /**=========================================================================================================
+ * Initial the learning algorithm + * - Create distance data + * - Prepare positive and negative examples (get from the learning problem (PLLearningPosNegLP) + * - Create a class hierarchy for refinement operator (for fast class herarchy checking) + * - Create expansion heuristic, which will be used to choose the expansion node in the search tree + * - Create refinement operator (RhoDRDown) + */ + @Override + public void init() throws ComponentInitException { + + //get the negative and positive examples + if (!(learningProblem instanceof ParCELPosNegLP)) + throw new ComponentInitException(learningProblem.getClass() + " is not supported by '" + getName() + "' learning algorithm"); + + + //get the positive and negative examples from the learning problem + positiveExamples = ((ParCELPosNegLP)learningProblem).getPositiveExamples(); + negativeExamples = ((ParCELPosNegLP)learningProblem).getNegativeExamples(); + + + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(this.positiveExamples); + + //initial heuristic which will be used by reducer to sort the search tree (expansion strategy) + //the heuristic need to get some constant from the configurator for scoring the description + if (heuristic == null) + heuristic = new ParCELDefaultHeuristic(); + + startClass = dataFactory.getOWLThing(); //this will be revise later using least common super class of all observations + + + this.uncoveredPositiveExampleAllowed = (int)Math.ceil(getNoisePercentage()*positiveExamples.size()); + + //initialise the existing uncovered positive examples + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); + + //---------------------------------- + //create refinement operator pool + //---------------------------------- + if (operator == null) { + //----------------------------------------- + //prepare for refinement operator creation + //----------------------------------------- + Set usedConcepts = new TreeSet<>(reasoner.getClasses()); + + + //remove the ignored concepts out of the list of concepts will be used by refinement operator + if (this.ignoredConcepts != null) { + try { + usedConcepts.removeAll(ignoredConcepts); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + ClassHierarchy classHiearachy = (ClassHierarchy) reasoner.getClassHierarchy().cloneAndRestrict(usedConcepts); + Map> splits = null; + + //create a splitter and refinement operator pool + //there are two options: i) using object pool, ii) using set of objects (removed from this revision) + if (this.splitter != null) { + splitter.setReasoner(reasoner); + splitter.setPositiveExamples(positiveExamples); + splitter.setNegativeExamples(negativeExamples); + splitter.init(); + + splits = splitter.computeSplits(); + + //i) option 1: create an object pool + refinementOperatorPool = new ParCELRefinementOperatorPool(reasoner, classHiearachy, startClass, splits, numberOfWorkers + 1); + + } + else { //no splitter provided + //i) option 1: create an object pool + refinementOperatorPool = new ParCELRefinementOperatorPool(reasoner, classHiearachy, startClass, numberOfWorkers + 1, maxNoOfSplits); + } + + refinementOperatorPool.getFactory().setUseDisjunction(false); + refinementOperatorPool.getFactory().setUseNegation(false); + refinementOperatorPool.getFactory().setUseHasValue(this.getUseHasValue()); + + } + + baseURI = reasoner.getBaseURI(); + prefix = reasoner.getPrefixes(); + //new DecimalFormat(); + + + //logging the information (will use slf4j) + if (logger.isInfoEnabled()) { + logger.info("[pllearning] - Heuristic used: " + heuristic.getClass()); + logger.info("[pllearning] - Positive examples: " + positiveExamples.size() + ", negative examples: " + negativeExamples.size()); + } + + minNumberOfWorker = maxNumberOfWorker = numberOfWorkers; + + } //init() + + + + /**=========================================================================================================
+ * Start reducer + * 1. Reset the status of reducer (stop, isRunning, done, timeout)
+ * 2. Reset the data structure (using reset() method)
+ * 3. Create a set of workers and add them into the worker pool
+ * NOTE: Each worker will have it own refinement operator
+ * 4. Prepare some data: pos/neg examples, uncovered positive examples, etc.
+ * 5. Start the learning progress:
+ * i) refine nodes in the (tree set)
+ * ii) evaluate nodes in unevaluated nodes (hash set)
+ * + */ + @Override + public void start() { + + reset(); + + initSearchTree(); + + createWorkerPool(); + + + //start time of reducer, statistical purpose only + miliStarttime = System.currentTimeMillis(); + + //---------------------------------------------------------- + // perform the learning process until the conditions for + // termination meets + //---------------------------------------------------------- + while (!isTerminateCriteriaSatisfied()) { + + //------------------- + //check for timeout + //------------------- + timeout = (this.maxExecutionTimeInSeconds > 0 && (System.currentTimeMillis() - miliStarttime) > this.maxExecutionTimeInSeconds*1000); + + if (timeout) + break; + + + ParCELNode nodeToProcess; + + nodeToProcess = searchTree.pollLast(); + + //TODO: why this? why "blocking" concept does not help in this case? + //remove this checking will exploit the heap memory and no definition found + //NOTE: i) instead of using sleep, can we use semaphore here? + // ii) if using semaphore or blocking, timeout checking may not be performed on time? + while ((workerPool.getQueue().size() >= maxTaskQueueLength)) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if ((nodeToProcess != null) && !workerPool.isShutdown() && !workerPool.isTerminating()) { + try { + this.createNewTask(nodeToProcess); + } + catch (RejectedExecutionException re) { + logger.error(re); + this.searchTree.add(nodeToProcess); + } + } + } //while the algorithm is not finish + + + this.miliLearningTime = System.currentTimeMillis() - miliStarttime; + + stop(); + + + //----------------------------------------------------------------------- + //try to combine descriptions in the search tree with the counter partial + //definition to find more partial definition + //----------------------------------------------------------------------- + /* + synchronized (this.searchTree) { + + if (logger.isInfoEnabled()) + logger.info("Processing counter partial definition: " + this.counterPartialDefinitions.size() + ", " + this.searchTree.size()); + + List newSearchTree = new ArrayList(this.searchTree); + Collections.sort(newSearchTree, new ParCELCompletenessComparator()); + + if (logger.isInfoEnabled()) + logger.info("Finding new partial definition from COUNTER partial definition: "); + + int newPartialDefCount = 0; + + for (ParCELNode des : newSearchTree) { + synchronized (this.counterPartialDefinitions) { + + Set combinableCounterPartialDefinitions = + ParCELExCombineCounterPartialDefinition.getCombinable(des, this.counterPartialDefinitions); + + if (combinableCounterPartialDefinitions != null) { + + //List counterList = new LinkedList(); + //counterList.add(des.getDescription()); + + //for (ParCELExtraNode def : combinableCounterPartialDefinitions) + //counterList.add(def.getDescription()); + //des.setDescription(new Intersection(des.getDescription(), def.getDescription())); + //des.setDescription(new Intersection(counterList)); + des.setDescription(ParCELExUtilities.createIntersection(des.getDescription(), + combinableCounterPartialDefinitions, true)); + + ParCELExtraNode newPD = new ParCELExtraNode(des); + newPD.setGenerationTime(System.currentTimeMillis() - miliStarttime); + newPD.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_LAZY_COMBINATION); //type 2 + //newPD.setCompositeList(combinableCounterPartialDefinitions); + partialDefinitions.add(newPD); + } //new partial definition found + } //synch counter partial definition + } //for each description in the search tree + + if (logger.isInfoEnabled()) + logger.info(newPartialDefCount + " new partial definition found"); + + } //synch search tree + */ + + + //------------------------------- + //post-learning processing + //------------------------------- + + if (logger.isInfoEnabled()) { + synchronized (partialDefinitions) { + if (this.getCurrentlyOveralMaxCompleteness() == 1) + logger.info("Learning finishes in: " + this.miliLearningTime + "ms, with: " + partialDefinitions.size() + " definitions"); + else if (this.isTimeout()) { + logger.info("Learning timeout in " + this.maxExecutionTimeInSeconds + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); + logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); + } + else { + logger.info("Learning is manually terminated at " + this.miliLearningTime + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); + logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); + } + + logger.info("**Reduced partial definitions:"); + TreeSet compactedDefinitions = (TreeSet) this.getReducedPartialDefinition(); + this.noOfReducedPartialDefinition = compactedDefinitions.size(); + int count = 1; + for (ParCELExtraNode def : compactedDefinitions) { + logger.info(count++ + ". " + OWLAPIRenderers.toManchesterOWLSyntax(ParCELExUtilities.groupDefinition(def.getDescription())).replace("and (not", "\nand (not") + //def.getDescription().toManchesterSyntaxString(baseURI, prefix) + + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + + ", accuracy: " + df.format(def.getAccuracy()) + + ", type: " + def.getType() + ")"); + + //test the new representation of the partial definition + //in which the counter partials will be group for readability + //logger.info("Definition after grouped: " + ParCELEx2DefinitionGrouping.groupDefinition(def.getDescription()).toManchesterSyntaxString(baseURI, prefix).replace("and (not", "\nand (not")); + + //print out the learning tree + if (logger.isTraceEnabled()) { + ParCELNode parent = (ParCELNode)def.getParent(); + while (parent != null) { + logger.trace(" <-- " + OWLAPIRenderers.toManchesterOWLSyntax(parent.getDescription())); + //" [acc:" + df.format(parent.getAccuracy()) + + //", correctness:" + df.format(parent.getCorrectness()) + ", completeness:" + df.format(parent.getCompleteness()) + + //", score:" + df.format(this.heuristic.getScore(parent)) + "]"); + + //print out the children nodes + Collection children = parent.getChildren(); + for (OENode child : children) { + ParCELNode tmp = (ParCELNode)child; + logger.trace(" --> " + OWLAPIRenderers.toManchesterOWLSyntax(tmp.getDescription())); + //" [acc:" + df.format(tmp.getAccuracy()) + + //", correctness:" + df.format(tmp.getCorrectness()) + ", completeness:" + df.format(tmp.getCompleteness()) + + //", score:" + df.format(this.heuristic.getScore(tmp)) + "]"); + } + parent = (ParCELNode)parent.getParent(); + } + } //end of printing the learning tree + } + } + } + + + super.aggregateCounterPartialDefinitionInf(); + + } //start() + + + private void createNewTask(ParCELNode nodeToProcess) { + workerPool.execute(new ParCELWorkerExV2(this, this.refinementOperatorPool, + (ParCELPosNegLP)learningProblem, nodeToProcess, "ParCELEx2Task-" + (noOfTask++))); + } + + + + /**=========================================================================================================
+ * Callback method for worker when a partial definition found + * (callback for an evaluation request from reducer)
+ * If a definition (partial) found, do the following tasks:
+ * 1. Add the definition into the partial definition set
+ * 2. Update: uncovered positive examples, max accuracy, best description length + * 2. Check for the completeness of the learning. If yes, stop the learning
+ * + * @param definitions New partial definitions + */ + public void newPartialDefinitionsFound(Set definitions) { + + for (ParCELExtraNode def : definitions) { + + //NOTE: in the previous version, this node will be added back into the search tree + // it is not necessary since in DLLearn, a definition may be revised to get a better one but + // in this approach, we do not refine partial definition. + + //remove uncovered positive examples by the positive examples covered by the new partial definition + int uncoveredPositiveExamplesRemoved; + int uncoveredPositiveExamplesSize; //for avoiding synchronized uncoveredPositiveExamples later on + + synchronized (uncoveredPositiveExamples) { + uncoveredPositiveExamplesRemoved = this.uncoveredPositiveExamples.size(); + this.uncoveredPositiveExamples.removeAll(def.getCoveredPositiveExamples()); + uncoveredPositiveExamplesSize = this.uncoveredPositiveExamples.size(); + + + uncoveredPositiveExamplesRemoved -= uncoveredPositiveExamplesSize; + + if (uncoveredPositiveExamplesRemoved > 0) { + + //set the generation time for the new partial definition + //def.setGenerationTime(System.currentTimeMillis() - miliStarttime); + synchronized (partialDefinitions) { + partialDefinitions.add(def); + } + + //update the uncovered positive examples for the learning problem + ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); + + if (logger.isTraceEnabled()) { + logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + + ", des:" + def.getGenerationTime() + ); + } + else if (logger.isDebugEnabled()) + logger.debug("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + ); + else if (logger.isInfoEnabled()) { + logger.info("(+) PARTIAL definition found. Uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + } + + //update the max accuracy and max description length + if (def.getAccuracy() > this.maxAccuracy) { + this.maxAccuracy = def.getAccuracy(); + this.bestDescriptionLength = new OWLClassExpressionLengthCalculator().getLength(def.getDescription()); + } + + //check if the complete definition found + if (uncoveredPositiveExamplesSize <= uncoveredPositiveExampleAllowed) { + this.done = true; + //stop(); + } + } + } + + + } //for each partial definition + + } //definitionFound() + + + /**=========================================================================================================
+ * This function is used to process the counter partial definitions returned from the workers + */ + public void newCounterPartialDefinitionsFound(Set counterPartialDefinitions) { + + for (ParCELExtraNode def : counterPartialDefinitions) { + + //calculate the "actual" number of negative examples covered by the new definition + int numberOfNewCoveredNegativeExamples; + int numberOfCoveredNegativeExamples; ///for avoiding synchronized coveredNegativeExamples later on + + synchronized (this.coveredNegativeExamples) { + numberOfNewCoveredNegativeExamples = this.coveredNegativeExamples.size(); + this.coveredNegativeExamples.addAll(def.getCoveredNegativeExamples()); + numberOfNewCoveredNegativeExamples = this.coveredNegativeExamples.size() - numberOfNewCoveredNegativeExamples; + numberOfCoveredNegativeExamples = this.coveredNegativeExamples.size(); + + + //process the counter partial definition if it covers at least 1 new negative example + if (numberOfNewCoveredNegativeExamples > 0) { + + //add the new counter partial definition into the set of counter partial definitions + synchronized (this.counterPartialDefinitions) { + this.counterPartialDefinitions.add(def); + } + + //NOTE: when a partial definition found, we update the set of uncovered positive examples for the Learning Problem + // but there is no need to do it for the counter partial definition, i.e. no update for covered negative examples + if (logger.isTraceEnabled()) { + logger.trace("(-) COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + //TODO def.getDescription().getChild(0) + "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() + ); + } + else if (logger.isDebugEnabled()) + logger.debug("(-) COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + //TODO def.getDescription().getChild(0) + "\n\t - cn (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - total cn: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() + ); + else if (logger.isInfoEnabled()) { + logger.info("(-) COUNTER PARTIAL definition found. Total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size()); + } + + //complete counter definition found + if (this.coveredNegativeExamples.size() >= this.negativeExamples.size()) { + this.counterDone = true; + //this.stop(); + } + } + } + + } + + } + + /**=========================================================================================================
+ * Reset all necessary properties for a new learning + * 1. Create new search tree + * 2. Create an empty description set, which hold all generated description (to avoid redundancy) + * 3. Create an empty + */ + private void reset() { + searchTree = new ConcurrentSkipListSet<>(heuristic); + + //allDescriptions = new TreeSet(new ConceptComparator()); + this.allDescriptions = new ConcurrentSkipListSet<>(); + + partialDefinitions = new TreeSet<>(new ParCELCompletenessComparator()); + counterPartialDefinitions = new TreeSet<>(new ParCELCorrectnessComparator()); + + //clone the positive examples for this set + this.uncoveredPositiveExamples = new HashSet<>(); + this.uncoveredPositiveExamples.addAll(this.positiveExamples); //create a copy of positive examples used to check the completeness + + this.coveredNegativeExamples = new HashSet<>(); + + descriptionTested = 0; + maxAccuracy = 0; + + stop = false; + done = false; + timeout = false; + counterDone = false; + + this.noOfReducedPartialDefinition = -1; + } + + + /**=========================================================================================================
+ * Stop the learning algorithm: Stop the workers and set the "stop" flag to true + */ + @Override + public void stop() { + + if (!stop) { + stop = true; + + List waitingTasks = workerPool.shutdownNow(); + + + + try { + workerPool.awaitTermination(0, TimeUnit.SECONDS); + } + catch (InterruptedException ie) { + logger.error(ie); + } + + //put the unexecuted tasks back to the search tree + logger.debug("Put incompleted task back to the search tree: " + waitingTasks.size()); + for (Runnable node : waitingTasks) + searchTree.add(((ParCELWorkerExV2)node).getProcessingNode()); + + //don't stop immediately, wait until all workers finish their jobs + /* + while (workerPool.getQueue().size() > 0) { + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + */ + } + } + + + + + /**=========================================================================================================
+ * Get the overall completeness of all partial definition found + * + * @return Overall completeness so far + */ + public double getCurrentlyOveralMaxCompleteness() { + return 1 - (uncoveredPositiveExamples.size()/(double)positiveExamples.size()); + } + + + //methods related to the compactness: get compact definition, set compactor + public SortedSet getReducedPartialDefinition(ParCELReducer reducer) { + return reducer.reduce(partialDefinitions, positiveExamples, uncoveredPositiveExamples.size()); + } + + + public SortedSet getReducedPartialDefinition() { + return this.getReducedPartialDefinition(this.reducer); + } + + + public void setCompactor(ParCELReducer newReducer) { + this.reducer = newReducer; + } + + + + public int getNoOfReducedPartialDefinition() { + return this.noOfReducedPartialDefinition; + } + + public SortedSet getCurrentCounterPartialDefinitions() { + return this.counterPartialDefinitions; + } + +} diff --git a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java index cdbe4132fc..ed7d4607a8 100644 --- a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java +++ b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java @@ -18,6 +18,7 @@ */ package org.dllearner.core; +import com.sun.management.OperatingSystemMXBean; import org.dllearner.core.annotations.NoConfigOption; import org.dllearner.core.config.ConfigOption; import org.dllearner.core.owl.ClassHierarchy; @@ -46,9 +47,11 @@ import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl; import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; +import java.lang.management.ManagementFactory; import java.text.DecimalFormat; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * Abstract superclass of all class expression learning algorithm implementations. @@ -128,6 +131,10 @@ public abstract class AbstractCELA extends AbstractComponent implements ClassExp @ConfigOption(description="List of data properties to ignore") protected Set ignoredDataProperties = null; + private List bestConceptsTimes = new ArrayList<>(); + private List bestConceptsTrainingAccuracies = new ArrayList<>(); + private List bestConceptsTestAccuracies = new ArrayList<>(); + /** * Default Constructor */ @@ -356,7 +363,7 @@ protected String getSolutionString() { str += current + ": " + descriptionString + " (pred. acc.: " + dfPercent.format(reasoningUtil.getAccuracyOrTooWeak2(new AccMethodPredAcc(true), description, positiveExamples, negativeExamples, 1)) - + " / " + dfPercent.format(computeTestingAccuracy(description)) + + " / " + dfPercent.format(computeTestAccuracy(description)) + ", F-measure: "+ dfPercent.format(reasoningUtil.getAccuracyOrTooWeak2(new AccMethodFMeasure(true), description, positiveExamples, negativeExamples, 1)); AccMethodTwoValued accuracyMethod = ((PosNegLP)learningProblem).getAccuracyMethod(); @@ -374,7 +381,7 @@ protected String getSolutionString() { return str; } - protected double computeTestingAccuracy(OWLClassExpression description) { + protected double computeTestAccuracy(OWLClassExpression description) { if (learningProblem instanceof PosNegLP) { return ((PosNegLP) learningProblem).getTestAccuracyOrTooWeak(description, 1); } @@ -382,6 +389,23 @@ protected double computeTestingAccuracy(OWLClassExpression description) { return 0.0; } + protected void recordBestConceptTimeAndAccuracy(double seconds, double trainingAccuracy, double testAccuracy) { + bestConceptsTimes.add(seconds); + bestConceptsTrainingAccuracies.add(trainingAccuracy); + bestConceptsTestAccuracies.add(testAccuracy); + } + + protected void printBestConceptsTimesAndAccuracies() { + String times = bestConceptsTimes.stream().map(Object::toString).collect(Collectors.joining(", ")); + logger.info("Times: [" + times + "]"); + + String trainingAccuracies = bestConceptsTrainingAccuracies.stream().map(Object::toString).collect(Collectors.joining(", ")); + logger.info("Acc: [" + trainingAccuracies + "]"); + + String testAccuracies = bestConceptsTestAccuracies.stream().map(Object::toString).collect(Collectors.joining(", ")); + logger.info("Test Acc: [" + testAccuracies + "]"); + } + /** * Computes an internal class hierarchy that only contains classes * that are allowed. @@ -465,6 +489,12 @@ protected DatatypePropertyHierarchy initDataPropertyHierarchy() { // hierarchy.thinOutSubsumptionHierarchy(); return hierarchy; } + + // beware that this includes the setup time as well + protected long getCurrentCpuMillis() { + OperatingSystemMXBean bean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + return bean.getProcessCpuTime() / 1_000_000; + } protected boolean isTimeExpired() { return getCurrentRuntimeInMilliSeconds() >= TimeUnit.SECONDS.toMillis(maxExecutionTimeInSeconds); diff --git a/components-core/src/main/java/org/dllearner/core/owl/ObjectPropertyHierarchy.java b/components-core/src/main/java/org/dllearner/core/owl/ObjectPropertyHierarchy.java index 3d5f7918ca..8f69cccfbc 100644 --- a/components-core/src/main/java/org/dllearner/core/owl/ObjectPropertyHierarchy.java +++ b/components-core/src/main/java/org/dllearner/core/owl/ObjectPropertyHierarchy.java @@ -86,30 +86,6 @@ public OWLObjectProperty getBottomConcept() { return OWL_BOTTOM_OBJECT_PROPERTY; } - /* (non-Javadoc) - * @see org.dllearner.core.owl.AbstractHierarchy#toString(java.util.SortedMap, org.semanticweb.owlapi.model.OWLObject, int) - */ - @Override - protected String toString(SortedMap> hierarchy, - OWLObjectProperty prop, int depth) { - String str = ""; - for (int i = 0; i < depth; i++) - str += " "; - str += prop.toString() + "\n"; - Set tmp; - if(prop.isTopEntity()) { - tmp = getMostGeneralRoles(); - } else { - tmp = hierarchy.get(prop); - } - - if (tmp != null) { - for (OWLObjectProperty c : tmp) - str += toString(hierarchy, c, depth + 1); - } - return str; - } - @Override public ObjectPropertyHierarchy clone() { return new ObjectPropertyHierarchy(new TreeMap<>(getHierarchyUp()), new TreeMap<>(getHierarchyDown())); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 16aa5678c7..88b6974910 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -69,7 +69,7 @@ * */ @ComponentAnn(name = "rho refinement operator", shortName = "rho", version = 0.8) -public class RhoDRDown extends RefinementOperatorAdapter implements Component, CustomHierarchyRefinementOperator, CustomStartRefinementOperator, ReasoningBasedRefinementOperator { +public class RhoDRDown extends RefinementOperatorAdapter implements Component, CustomHierarchyRefinementOperator, CustomStartRefinementOperator, ReasoningBasedRefinementOperator, Cloneable { private static Logger logger = LoggerFactory.getLogger(RhoDRDown.class); private final static Marker sparql_debug = new BasicMarkerFactory().getMarker("SD"); @@ -200,6 +200,9 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C @ConfigOption(description="support of negation (owl:complementOf), e.g. \u00AC C ", defaultValue="true") private boolean useNegation = true; + @ConfigOption(description="support of disjunction (owl:unionOf), e.g. C\u2294 D ", defaultValue="true") + private boolean useDisjunction = true; + @ConfigOption(description="support of inverse object properties (owl:inverseOf), e.g. r\u207B.C ", defaultValue="false") private boolean useInverse = false; @@ -249,10 +252,11 @@ public RhoDRDown() {} */ public RhoDRDown(RhoDRDown op) { setApplyAllFilter(op.applyAllFilter); + setApplyExistsFilter(op.applyExistsFilter); setCardinalityLimit(op.cardinalityLimit); - setClassHierarchy(op.classHierarchy); - setObjectPropertyHierarchy(op.objectPropertyHierarchy); - setDataPropertyHierarchy(op.dataPropertyHierarchy); + setClassHierarchy(op.classHierarchy.clone()); + setObjectPropertyHierarchy(op.objectPropertyHierarchy.clone()); + setDataPropertyHierarchy(op.dataPropertyHierarchy.clone()); setDropDisjuncts(op.dropDisjuncts); setInstanceBasedDisjoints(op.instanceBasedDisjoints); setReasoner(op.reasoner); @@ -261,16 +265,24 @@ public RhoDRDown(RhoDRDown op) { setUseCardinalityRestrictions(op.useCardinalityRestrictions); setUseExistsConstructor(op.useExistsConstructor); setUseNegation(op.useNegation); + setUseDisjunction(op.useDisjunction); setUseHasValueConstructor(op.useHasValueConstructor); setUseObjectValueNegation(op.useObjectValueNegation); - setFrequencyThreshold(op.frequencyThreshold); setUseDataHasValueConstructor(op.useDataHasValueConstructor); setUseBooleanDatatypes(op.useBooleanDatatypes); setUseStringDatatypes(op.useStringDatatypes); setUseNumericDatatypes(op.useNumericDatatypes); setUseTimeDatatypes(op.useTimeDatatypes); setUseSomeOnly(op.useSomeOnly); + setUseHasSelf(op.useHasSelf); + setUseInverse(op.useInverse); + setFrequencyThreshold(op.frequencyThreshold); setAllowedRolesInCardinalityRestrictions(op.allowedRolesInCardinalityRestrictions); + setSplits(op.splits); + setMaxNrOfSplits(op.maxNrOfSplits); + setNumericValuesSplitter(op.numericValuesSplitter); + setDisjointChecks(op.disjointChecks); + setLengthMetric(op.lengthMetric); initialized = false; } @@ -342,18 +354,20 @@ public void init() throws ComponentInitException { // compute splits for numeric data properties if(useNumericDatatypes) { - if(reasoner instanceof SPARQLReasoner - && !((SPARQLReasoner)reasoner).isUseGenericSplitsCode()) { - // TODO SPARQL support for splits - logger.warn("Numeric Facet restrictions are not (yet) implemented for " + AnnComponentManager.getName(reasoner) + ", option ignored"); - } else { - // create default splitter if none was set - if(numericValuesSplitter == null) { - numericValuesSplitter = new DefaultNumericValuesSplitter(reasoner, df, maxNrOfSplits); - } - splits.putAll(numericValuesSplitter.computeSplits()); - if (logger.isDebugEnabled()) { - logger.debug( sparql_debug, "Numeric Splits: {}", splits); + if (splits == null) { + if (reasoner instanceof SPARQLReasoner + && !((SPARQLReasoner) reasoner).isUseGenericSplitsCode()) { + // TODO SPARQL support for splits + logger.warn("Numeric Facet restrictions are not (yet) implemented for " + AnnComponentManager.getName(reasoner) + ", option ignored"); + } else { + // create default splitter if none was set + if (numericValuesSplitter == null) { + numericValuesSplitter = new DefaultNumericValuesSplitter(reasoner, df, maxNrOfSplits); + } + splits.putAll(numericValuesSplitter.computeSplits()); + if (logger.isDebugEnabled()) { + logger.debug(sparql_debug, "Numeric Splits: {}", splits); + } } } } @@ -856,12 +870,18 @@ private Set refineUpwards( List knownRefinements, OWLClassExpression currDomain ) { OWLClassExpression negatedDescription = constructNegationInNNF(description); + + boolean useNegationBackup = useNegation; + useNegation = true; + // concept length can change because of the conversion process; as a heuristic // we increase maxLength by the length difference of negated and original concept int lengthDiff = Math.max(0, OWLClassExpressionUtils.getLength(negatedDescription, lengthMetric) - OWLClassExpressionUtils.getLength(description, lengthMetric)); Set refinements = refine(negatedDescription, maxLength+lengthDiff+1, knownRefinements, currDomain); TreeSet results = new TreeSet<>(); + useNegation = useNegationBackup; + description = description.getNNF(); for (OWLClassExpression d : refinements) { @@ -870,7 +890,10 @@ private Set refineUpwards( // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check - if(description.compareTo(dNeg) != 0 && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength) { + if(description.compareTo(dNeg) != 0 + && (useNegation || !containsNegation(dNeg)) + && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength + ) { results.add(dNeg); } } @@ -889,6 +912,13 @@ private OWLClassExpression constructNegationInNNF(OWLClassExpression description return negatedDescription; } + private boolean containsNegation(OWLClassExpression description) { + return description.getNestedClassExpressions() + .stream().anyMatch(e -> + e instanceof OWLObjectComplementOf || e instanceof OWLDataComplementOf + ); + } + private boolean checkRefinability(OWLNaryBooleanClassExpression description) { Set unrefinableOperands = new TreeSet<>(); @@ -1228,7 +1258,7 @@ private void computeTopRefinements(int maxLength, OWLClassExpression domain) { else topARefinements.get(domain).get(i).addAll(mA.get(domain).get(i)); // combinations has several numbers => generate disjunct - } else { + } else if (useDisjunction) { // check whether the combination makes sense, i.e. whether // all lengths mentioned in it have corresponding elements @@ -2053,6 +2083,14 @@ public void setUseNegation(boolean useNegation) { this.useNegation = useNegation; } + public void setUseDisjunction(boolean useDisjunction) { + this.useDisjunction = useDisjunction; + } + + public boolean isUseDisjunction() { + return useDisjunction; + } + public boolean isUseBooleanDatatypes() { return useBooleanDatatypes; } @@ -2187,6 +2225,10 @@ public void setMaxNrOfSplits(int maxNrOfSplits) { this.maxNrOfSplits = maxNrOfSplits; } + public void setSplits(Map> splits) { + this.splits = new TreeMap<>(splits); + } + public boolean isDisjointChecks() { return disjointChecks; } @@ -2233,6 +2275,15 @@ public Set getAllowedRolesInCardinalityRestrictions() { } public void setAllowedRolesInCardinalityRestrictions(Set allowedRolesInCardinalityRestrictions) { - this.allowedRolesInCardinalityRestrictions = allowedRolesInCardinalityRestrictions; + if (allowedRolesInCardinalityRestrictions != null) { + this.allowedRolesInCardinalityRestrictions = new TreeSet<>(allowedRolesInCardinalityRestrictions); + } else { + this.allowedRolesInCardinalityRestrictions = null; + } + } + + @Override + public RhoDRDown clone() { + return new RhoDRDown(this); } } diff --git a/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionUtils.java b/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionUtils.java index 167d11c0e3..30f4ff332a 100644 --- a/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionUtils.java +++ b/components-core/src/main/java/org/dllearner/utilities/owl/OWLClassExpressionUtils.java @@ -18,8 +18,7 @@ */ package org.dllearner.utilities.owl; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.util.MaximumModalDepthFinder; import org.semanticweb.owlapi.util.OWLObjectDuplicator; import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; @@ -101,4 +100,36 @@ public static boolean occursOnFirstLevel(OWLClassExpression description, OWLClas return description.containsConjunct(cls); } + /** + * Replace the filler of an object property restriction. + * + * @param restriction the object property restriction + * @param newFiller the filler to replace the old one + * @return the new object property restriction with a replaced filler + */ + public static OWLQuantifiedObjectRestriction replaceFiller(OWLQuantifiedObjectRestriction restriction, + OWLClassExpression newFiller) { + OWLQuantifiedObjectRestriction newRestriction = null; + OWLObjectPropertyExpression property = restriction.getProperty(); + if (restriction instanceof OWLObjectSomeValuesFrom) { + newRestriction = dataFactory.getOWLObjectSomeValuesFrom(property, newFiller); + } else if (restriction instanceof OWLObjectAllValuesFrom) { + newRestriction = dataFactory.getOWLObjectAllValuesFrom(property, newFiller); + } else if (restriction instanceof OWLObjectCardinalityRestriction) { + int cardinality = ((OWLObjectCardinalityRestriction) restriction).getCardinality(); + + if (restriction instanceof OWLObjectMinCardinality) { + newRestriction = dataFactory.getOWLObjectMinCardinality(cardinality, property, newFiller); + } else if (restriction instanceof OWLObjectMaxCardinality) { + newRestriction = dataFactory.getOWLObjectMaxCardinality(cardinality, property, newFiller); + } else if (restriction instanceof OWLObjectExactCardinality) { + newRestriction = dataFactory.getOWLObjectExactCardinality(cardinality, property, newFiller); + } + } else { + throw new IllegalArgumentException("unsupported restriction type for filler replacement: " + + restriction.getClassExpressionType().getName()); + } + return newRestriction; + } + } diff --git a/examples/forte/uncle_owl_large_parcelEx2_cross.conf b/examples/forte/uncle_owl_large_parcelEx2_cross.conf new file mode 100644 index 0000000000..3edc5cb14b --- /dev/null +++ b/examples/forte/uncle_owl_large_parcelEx2_cross.conf @@ -0,0 +1,127 @@ +/** +* See uncle.conf. This is the same learning problem, but loading background +* knowledge from an OWL file instead. +* +* Copyright (C) 2007, Jens Lehmann +* Modified by An C. Tran +*/ + + +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/** background knowledge **/ +prefixes = [ ("kb","http://localhost/foo#") ] + +// knowledge source definition +ks.type = "OWL File" +ks.fileName = "forte_family.owl" + +// reasoner +reasoner.type = "closed world reasoner" +reasoner.sources = { ks } + + +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV2" +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 20 + + +// learning problem +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "kb:art", + "kb:calvin", + "kb:carlos", + "kb:david", + "kb:eric", + "kb:fred", + "kb:frederick", + "kb:george", + "kb:harry", + "kb:jack", + "kb:james", + "kb:jonas", + "kb:karl", + "kb:leon", + "kb:mark", + "kb:melvin", + "kb:neil", + "kb:nero", + "kb:owen", + "kb:paul", + "kb:peter", + "kb:umo", + "kb:walt" +} +lp.negativeExamples = { + "kb:alfred", + "kb:alice", + "kb:angela", + "kb:ann", + "kb:beatrice", + "kb:bob", + "kb:callie", + "kb:carl", + "kb:christy", + "kb:cornelia", + "kb:deanna", + "kb:elisa", + "kb:f12", + "kb:f14", + "kb:f19", + "kb:f2", + "kb:f20", + "kb:f21", + "kb:f22", + "kb:f23", + "kb:f25", + "kb:f26", + "kb:f28", + "kb:f8", + "kb:fannie", + "kb:gail", + "kb:helen", + "kb:jane", + "kb:janet", + "kb:kari", + "kb:lorrie", + "kb:m1", + "kb:m10", + "kb:m11", + "kb:m13", + "kb:m15", + "kb:m16", + "kb:m17", + "kb:m18", + "kb:m24", + "kb:m27", + "kb:m29", + "kb:m3", + "kb:m4", + "kb:m5", + "kb:m6", + "kb:m7", + "kb:m9", + "kb:maria", + "kb:martha", + "kb:nancy", + "kb:nonnie", + "kb:oma", + "kb:paula", + "kb:prissie", + "kb:rachel", + "kb:ray", + "kb:regina", + "kb:steve", + "kb:susan", + "kb:terri", + "kb:terry", + "kb:wendy" +} + diff --git a/examples/forte/uncle_owl_large_parcelEx2_learn.conf b/examples/forte/uncle_owl_large_parcelEx2_learn.conf new file mode 100644 index 0000000000..b279ed45de --- /dev/null +++ b/examples/forte/uncle_owl_large_parcelEx2_learn.conf @@ -0,0 +1,127 @@ +/** +* See uncle.conf. This is the same learning problem, but loading background +* knowledge from an OWL file instead. +* +* Copyright (C) 2007, Jens Lehmann +* Modified by An C. Tran +*/ + + +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = false +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/** background knowledge **/ +prefixes = [ ("kb","http://localhost/foo#") ] + +// knowledge source definition +ks.type = "OWL File" +ks.fileName = "forte_family.owl" + +// reasoner +reasoner.type = "closed world reasoner" +reasoner.sources = { ks } + + +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV2" +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 120 + + +// learning problem +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "kb:art", + "kb:calvin", + "kb:carlos", + "kb:david", + "kb:eric", + "kb:fred", + "kb:frederick", + "kb:george", + "kb:harry", + "kb:jack", + "kb:james", + "kb:jonas", + "kb:karl", + "kb:leon", + "kb:mark", + "kb:melvin", + "kb:neil", + "kb:nero", + "kb:owen", + "kb:paul", + "kb:peter", + "kb:umo", + "kb:walt" +} +lp.negativeExamples = { + "kb:alfred", + "kb:alice", + "kb:angela", + "kb:ann", + "kb:beatrice", + "kb:bob", + "kb:callie", + "kb:carl", + "kb:christy", + "kb:cornelia", + "kb:deanna", + "kb:elisa", + "kb:f12", + "kb:f14", + "kb:f19", + "kb:f2", + "kb:f20", + "kb:f21", + "kb:f22", + "kb:f23", + "kb:f25", + "kb:f26", + "kb:f28", + "kb:f8", + "kb:fannie", + "kb:gail", + "kb:helen", + "kb:jane", + "kb:janet", + "kb:kari", + "kb:lorrie", + "kb:m1", + "kb:m10", + "kb:m11", + "kb:m13", + "kb:m15", + "kb:m16", + "kb:m17", + "kb:m18", + "kb:m24", + "kb:m27", + "kb:m29", + "kb:m3", + "kb:m4", + "kb:m5", + "kb:m6", + "kb:m7", + "kb:m9", + "kb:maria", + "kb:martha", + "kb:nancy", + "kb:nonnie", + "kb:oma", + "kb:paula", + "kb:prissie", + "kb:rachel", + "kb:ray", + "kb:regina", + "kb:steve", + "kb:susan", + "kb:terri", + "kb:terry", + "kb:wendy" +} + diff --git a/examples/forte/uncle_owl_large_parcel_learn.conf b/examples/forte/uncle_owl_large_parcel_learn.conf new file mode 100644 index 0000000000..f61827b288 --- /dev/null +++ b/examples/forte/uncle_owl_large_parcel_learn.conf @@ -0,0 +1,126 @@ +/** +* See uncle.conf. This is the same learning problem, but loading background +* knowledge from an OWL file instead. +* +* Copyright (C) 2007, Jens Lehmann +* Modified by An C. Tran +*/ + + +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = false +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/** background knowledge **/ +prefixes = [ ("kb","http://localhost/foo#") ] + +// knowledge source definition +ks.type = "OWL File" +ks.fileName = "forte_family.owl" + +// reasoner +reasoner.type = "closed world reasoner" +reasoner.sources = { ks } + + +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 60 + + +// learning problem +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "kb:art", + "kb:calvin", + "kb:carlos", + "kb:david", + "kb:eric", + "kb:fred", + "kb:frederick", + "kb:george", + "kb:harry", + "kb:jack", + "kb:james", + "kb:jonas", + "kb:karl", + "kb:leon", + "kb:mark", + "kb:melvin", + "kb:neil", + "kb:nero", + "kb:owen", + "kb:paul", + "kb:peter", + "kb:umo", + "kb:walt" +} +lp.negativeExamples = { + "kb:alfred", + "kb:alice", + "kb:angela", + "kb:ann", + "kb:beatrice", + "kb:bob", + "kb:callie", + "kb:carl", + "kb:christy", + "kb:cornelia", + "kb:deanna", + "kb:elisa", + "kb:f12", + "kb:f14", + "kb:f19", + "kb:f2", + "kb:f20", + "kb:f21", + "kb:f22", + "kb:f23", + "kb:f25", + "kb:f26", + "kb:f28", + "kb:f8", + "kb:fannie", + "kb:gail", + "kb:helen", + "kb:jane", + "kb:janet", + "kb:kari", + "kb:lorrie", + "kb:m1", + "kb:m10", + "kb:m11", + "kb:m13", + "kb:m15", + "kb:m16", + "kb:m17", + "kb:m18", + "kb:m24", + "kb:m27", + "kb:m29", + "kb:m3", + "kb:m4", + "kb:m5", + "kb:m6", + "kb:m7", + "kb:m9", + "kb:maria", + "kb:martha", + "kb:nancy", + "kb:nonnie", + "kb:oma", + "kb:paula", + "kb:prissie", + "kb:rachel", + "kb:ray", + "kb:regina", + "kb:steve", + "kb:susan", + "kb:terri", + "kb:terry", + "kb:wendy" +} diff --git a/examples/showering-duration/abd.muse.massey.ac.nz.owl b/examples/showering-duration/abd.muse.massey.ac.nz.owl new file mode 100644 index 0000000000..ce6384163f --- /dev/null +++ b/examples/showering-duration/abd.muse.massey.ac.nz.owl @@ -0,0 +1,809 @@ + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This property can be derived from day/month/year value. Howver, in this context, this property will be assigned to a timepoint. For example, Monday (t). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + + + + + + + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_180s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_180s.conf new file mode 100644 index 0000000000..37e9d72a81 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_180s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 180 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=12 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_300s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_300s.conf new file mode 100644 index 0000000000..bdae516ac2 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_300s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=12 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_600s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_600s.conf new file mode 100644 index 0000000000..bdae516ac2 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit12_600s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=12 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_180s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_180s.conf new file mode 100644 index 0000000000..d16a3c9e8b --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_180s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 180 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=38 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_300s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_300s.conf new file mode 100644 index 0000000000..bb76277007 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_300s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=38 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_600s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_600s.conf new file mode 100644 index 0000000000..bb76277007 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_600s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=38 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_60s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_60s.conf new file mode 100644 index 0000000000..93ce6abcc7 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_60s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 60 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=38 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_90s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_90s.conf new file mode 100644 index 0000000000..78049a5604 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit38_90s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 90 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=38 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_180s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_180s.conf new file mode 100644 index 0000000000..26b04c068f --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_180s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 180 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=6 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_300s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_300s.conf new file mode 100644 index 0000000000..e8f64d63fc --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_300s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=6 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_600s.conf b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_600s.conf new file mode 100644 index 0000000000..e8f64d63fc --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_celoe_cross_noSplit6_600s.conf @@ -0,0 +1,193 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +//alg.noisePercentage = 30 +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true +alg.maxNoOfSplits=6 + + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_180s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_180s.conf new file mode 100644 index 0000000000..7b960a82ed --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_180s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "12" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_300s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_300s.conf new file mode 100644 index 0000000000..b325030ec8 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_300s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "12" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 300 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_600s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_600s.conf new file mode 100644 index 0000000000..7e75540686 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter12_600s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "12" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 600 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_180s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_180s.conf new file mode 100644 index 0000000000..09e7d0c015 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_180s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "40" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_300s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_300s.conf new file mode 100644 index 0000000000..e8d1cbfb15 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_300s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "40" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 300 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_600s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_600s.conf new file mode 100644 index 0000000000..616508b4e2 --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter40_600s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "50" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 600 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_180s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_180s.conf new file mode 100644 index 0000000000..b3c929790c --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_180s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "6" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_300s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_300s.conf new file mode 100644 index 0000000000..a70b74361c --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_300s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "6" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 300 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_600s.conf b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_600s.conf new file mode 100644 index 0000000000..a70b74361c --- /dev/null +++ b/examples/showering-duration/segment/uca1_150_parcel_cross_noSplitter6_600s.conf @@ -0,0 +1,197 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +alg.maxNoOfSplits = "6" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 300 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +//alg.splitter = splitter + +/*--- configuration of the component 'splitter' ---*/ +//splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/uca1_150.owl b/examples/showering-duration/uca1_150.owl new file mode 100644 index 0000000000..35ac810b59 --- /dev/null +++ b/examples/showering-duration/uca1_150.owl @@ -0,0 +1,2153 @@ + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + 9 + + + + + 1 + + + + + 4 + + + + + 4 + + + + + 3 + + + + + 2 + + + + + 12 + + + + + 8 + + + + + 10 + + + + + 7 + + + + + 3 + + + + + 11 + + + + + 11 + + + + + 5 + + + + + 2 + + + + + 4 + + + + + 12 + + + + + 1 + + + + + 3 + + + + + 1 + + + + + 7 + + + + + 3 + + + + + 7 + + + + + 2 + + + + + 1 + + + + + 2 + + + + + 7 + + + + + 7 + + + + + 10 + + + + + 4 + + + + + 4 + + + + + 10 + + + + + 7 + + + + + 6 + + + + + 6 + + + + + 1 + + + + + 9 + + + + + 6 + + + + + 6 + + + + + 5 + + + + + 4 + + + + + 7 + + + + + 3 + + + + + 7 + + + + + 1 + + + + + 1 + + + + + 4 + + + + + 10 + + + + + 2 + + + + + 5 + + + + + 8 + + + + + 11 + + + + + 7 + + + + + 5 + + + + + 8 + + + + + 10 + + + + + 5 + + + + + 2 + + + + + 9 + + + + + 10 + + + + + 4 + + + + + 7 + + + + + 9 + + + + + 12 + + + + + 2 + + + + + 10 + + + + + 4 + + + + + 12 + + + + + 9 + + + + + 10 + + + + + 4 + + + + + 4 + + + + + 8 + + + + + 9 + + + + + 8 + + + + + 10 + + + + + 5 + + + + + 6 + + + + + 10 + + + + + 8 + + + + + 9 + + + + + 2 + + + + + 2 + + + + + 12 + + + + + 6 + + + + + 12 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 8 + + + + + 7 + + + + + 5 + + + + + 4 + + + + + 2 + + + + + 7 + + + + + 4 + + + + + 6 + + + + + 6 + + + + + 12 + + + + + 7 + + + + + 11 + + + + + 5 + + + + + 2 + + + + + 1 + + + + + 5 + + + + + 5 + + + + + 11 + + + + + 1 + + + + + 4 + + + + + 10 + + + + + 12 + + + + + 4 + + + + + 3 + + + + + 10 + + + + + 7 + + + + + 12 + + + + + 3 + + + + + 4 + + + + + 8 + + + + + 1 + + + + + 4 + + + + + 3 + + + + + 10 + + + + + 12 + + + + + 6 + + + + + 3 + + + + + 3 + + + + + 11 + + + + + 9 + + + + + 2 + + + + + 8 + + + + + 10 + + + + + 12 + + + + + 5 + + + + + 8 + + + + + 11 + + + + + 11 + + + + + 2 + + + + + 3 + + + + + 2 + + + + + 2 + + + + + 1 + + + + + 10 + + + + + 5 + + + + + 3 + + + + + 1 + + + + + 7 + + + + + 3 + + + + + 1 + + + + + + + + + 1 + + + + 3 + + + + 2 + + + + 19 + + + + 18 + + + + 19 + + + + 4 + + + + 16 + + + + 11 + + + + 29 + + + + 5 + + + + 18 + + + + 21 + + + + 27 + + + + 11 + + + + 13 + + + + 4 + + + + 15 + + + + 3 + + + + 27 + + + + 32 + + + + 2 + + + + 3 + + + + 19 + + + + 15 + + + + 1 + + + + 12 + + + + 4 + + + + 19 + + + + 5 + + + + 20 + + + + 28 + + + + 4 + + + + 10 + + + + 8 + + + + 6 + + + + 2 + + + + 4 + + + + 16 + + + + 13 + + + + 7 + + + + 12 + + + + 10 + + + + 18 + + + + 14 + + + + 35 + + + + 25 + + + + 18 + + + + 11 + + + + 17 + + + + 10 + + + + 3 + + + + 19 + + + + 38 + + + + 28 + + + + 17 + + + + 12 + + + + 33 + + + + 15 + + + + 14 + + + + 22 + + + + 29 + + + + 34 + + + + 15 + + + + 26 + + + + 30 + + + + 1 + + + + 19 + + + + 3 + + + + 9 + + + + 7 + + + + 28 + + + + 17 + + + + 14 + + + + 3 + + + + 29 + + + + 20 + + + + 30 + + + + 3 + + + + 7 + + + + 14 + + + + 8 + + + + 13 + + + + 1 + + + + 38 + + + + 32 + + + + 16 + + + + 14 + + + + 15 + + + + 19 + + + + 4 + + + + 29 + + + + 12 + + + + 12 + + + + 12 + + + + 18 + + + + 10 + + + + 32 + + + + 23 + + + + 22 + + + + 3 + + + + 1 + + + + 33 + + + + 1 + + + + 18 + + + + 19 + + + + 2 + + + + 1 + + + + 9 + + + + 16 + + + + 32 + + + + 12 + + + + 13 + + + + 29 + + + + 7 + + + + 7 + + + + 36 + + + + 31 + + + + 6 + + + + 19 + + + + 25 + + + + 17 + + + + 31 + + + + 18 + + + + 19 + + + + 18 + + + + 17 + + + + 29 + + + + 19 + + + + 4 + + + + 16 + + + + 2 + + + + 19 + + + + 21 + + + + 17 + + + + 16 + + + + 3 + + + + 1 + + + + 6 + + + + 8 + + + + 32 + + + + 13 + + + + 28 + + + + 14 + + + + 9 + + + + 17 + + + + 15 + + + + 24 + + + + 17 + + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/showering-duration/uca1_150_celoe_cross_300s.conf b/examples/showering-duration/uca1_150_celoe_cross_300s.conf new file mode 100644 index 0000000000..dc28cbcf16 --- /dev/null +++ b/examples/showering-duration/uca1_150_celoe_cross_300s.conf @@ -0,0 +1,190 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/uca1_150_celoe_cross_600s.conf b/examples/showering-duration/uca1_150_celoe_cross_600s.conf new file mode 100644 index 0000000000..6f2bf05b92 --- /dev/null +++ b/examples/showering-duration/uca1_150_celoe_cross_600s.conf @@ -0,0 +1,190 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +alg.maxExecutionTimeInSeconds = 600 +alg.stopOnFirstDefinition = true + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/uca1_150_celoe_fort_300s.conf b/examples/showering-duration/uca1_150_celoe_fort_300s.conf new file mode 100644 index 0000000000..23342aa625 --- /dev/null +++ b/examples/showering-duration/uca1_150_celoe_fort_300s.conf @@ -0,0 +1,190 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = true +cli.fairComparison = true + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +alg.maxExecutionTimeInSeconds = 300 +alg.stopOnFirstDefinition = true + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/uca1_150_celoe_learn_180s.conf b/examples/showering-duration/uca1_150_celoe_learn_180s.conf new file mode 100644 index 0000000000..3601c52c19 --- /dev/null +++ b/examples/showering-duration/uca1_150_celoe_learn_180s.conf @@ -0,0 +1,190 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 + + @author: An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = false +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.type = "org.dllearner.algorithms.celoe.CELOE" +alg.type = "celoe" +alg.maxExecutionTimeInSeconds = 180 +alg.stopOnFirstDefinition = true + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "posNegStandard" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/uca1_150_parcelEx12_cross.conf b/examples/showering-duration/uca1_150_parcelEx12_cross.conf new file mode 100644 index 0000000000..6347b69ccb --- /dev/null +++ b/examples/showering-duration/uca1_150_parcelEx12_cross.conf @@ -0,0 +1,192 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false +//cli.noOfRuns = 1 + +/*--- configuration of the component 'alg' ---*/ +//alg.maxNoOfSplits = "100" +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV12" +alg.splitter = splitter + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + + diff --git a/examples/showering-duration/uca1_150_parcelEx12_learn.conf b/examples/showering-duration/uca1_150_parcelEx12_learn.conf new file mode 100644 index 0000000000..7b8785ad4a --- /dev/null +++ b/examples/showering-duration/uca1_150_parcelEx12_learn.conf @@ -0,0 +1,191 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Positive examples: 73; Negative examples: 77 +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = false +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false +//cli.noOfRuns = 1 + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV12" +alg.splitter = splitter + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + + diff --git a/examples/showering-duration/uca1_150_parcelEx1_cross.conf b/examples/showering-duration/uca1_150_parcelEx1_cross.conf new file mode 100644 index 0000000000..7941f6526d --- /dev/null +++ b/examples/showering-duration/uca1_150_parcelEx1_cross.conf @@ -0,0 +1,195 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + +//cli.noOfRuns = 1 + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV1" +alg.splitter = splitter + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + + diff --git a/examples/showering-duration/uca1_150_parcelEx1_learn.conf b/examples/showering-duration/uca1_150_parcelEx1_learn.conf new file mode 100644 index 0000000000..c6324bde75 --- /dev/null +++ b/examples/showering-duration/uca1_150_parcelEx1_learn.conf @@ -0,0 +1,195 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = false +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + +//cli.noOfRuns = 1 + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV1" +alg.splitter = splitter + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + + diff --git a/examples/showering-duration/uca1_150_parcelEx2_cross.conf b/examples/showering-duration/uca1_150_parcelEx2_cross.conf new file mode 100644 index 0000000000..6e136779dd --- /dev/null +++ b/examples/showering-duration/uca1_150_parcelEx2_cross.conf @@ -0,0 +1,192 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "nz.ac.massey.seat.abd.learner.pdllearning.ParCELLearner" + - Positive examples: 73; Negative examples: 77 +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false +//cli.noOfRuns=1 + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV2" +alg.splitter = splitter + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + + diff --git a/examples/showering-duration/uca1_150_parcelEx2_fort.conf b/examples/showering-duration/uca1_150_parcelEx2_fort.conf new file mode 100644 index 0000000000..f4fc5dcbd6 --- /dev/null +++ b/examples/showering-duration/uca1_150_parcelEx2_fort.conf @@ -0,0 +1,192 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "nz.ac.massey.seat.abd.learner.pdllearning.ParCELLearner" + - Positive examples: 73; Negative examples: 77 +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = true +cli.fairComparison = true +//cli.noOfRuns=1 + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV2" +alg.splitter = splitter + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + + diff --git a/examples/showering-duration/uca1_150_parcelEx2_learn.conf b/examples/showering-duration/uca1_150_parcelEx2_learn.conf new file mode 100644 index 0000000000..d64ef69932 --- /dev/null +++ b/examples/showering-duration/uca1_150_parcelEx2_learn.conf @@ -0,0 +1,192 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "nz.ac.massey.seat.abd.learner.pdllearning.ParCELLearner" + - Positive examples: 73; Negative examples: 77 +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = false +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false +//cli.noOfRuns=1 + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcelex.ParCELearnerExV2" +alg.splitter = splitter + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'reasoner' ---*/ +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + + diff --git a/examples/showering-duration/uca1_150_parcel_cross.conf b/examples/showering-duration/uca1_150_parcel_cross.conf new file mode 100644 index 0000000000..0f420eb85e --- /dev/null +++ b/examples/showering-duration/uca1_150_parcel_cross.conf @@ -0,0 +1,199 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + + +/*--- configuration of the component 'alg' ---*/ +//alg.maxNoOfSplits = "100" +alg.numberOfWorkers = 4 +alg.maxExecutionTimeInSeconds = 60 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +alg.splitter = splitter +alg.noisePercentage = 10 +alg.startClass = "http://abd.muse.massey.ac.nz#Activity" + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/uca1_150_parcel_fort.conf b/examples/showering-duration/uca1_150_parcel_fort.conf new file mode 100644 index 0000000000..ed263d1538 --- /dev/null +++ b/examples/showering-duration/uca1_150_parcel_fort.conf @@ -0,0 +1,195 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = true +cli.nrOfFolds = 10 +cli.fortification = true +cli.fairComparison = true + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +alg.splitter = splitter + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/examples/showering-duration/uca1_150_parcel_learn.conf b/examples/showering-duration/uca1_150_parcel_learn.conf new file mode 100644 index 0000000000..33baec5513 --- /dev/null +++ b/examples/showering-duration/uca1_150_parcel_learn.conf @@ -0,0 +1,195 @@ +/* +Learning configuration + - Ontology: "uca1_150.owl" + - Algorithm: "org.dllearner.algorithms.parcel.ParCELReducer" + - Positive examples: 73; Negative examples: 77 + + @author An C. Tran +*/ + +/*--- cross validation configuration ---*/ +cli.type = "org.dllearner.cli.parcel.CLI" +cli.writeSpringConfiguration = false +cli.performCrossValidation = false +cli.nrOfFolds = 10 +cli.fortification = false +cli.fairComparison = false + +/*--- configuration of the component 'splitter' ---*/ +splitter.type = "org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterV1" + + +/*--- configuration of the component 'alg' ---*/ +alg.numberOfWorkers = 6 +alg.maxExecutionTimeInSeconds = 180 +alg.type = "org.dllearner.algorithms.parcel.ParCELearner" +alg.splitter = splitter + +/*--- configuration of the component 'reasoner' ---*/ +//reasoner.type = "org.dllearner.reasoning.PelletReasoner" +reasoner.type = "closed world reasoner" +reasoner.sources = {ks} + +/*--- configuration of the component 'ks' ---*/ +ks.fileName = "uca1_150.owl" +ks.type = "OWL file" + +/*--- configuration of the component 'lp' ---*/ +lp.type = "org.dllearner.algorithms.parcel.ParCELPosNegLP" +lp.positiveExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_004", + "http://uca1.abd.muse.massey.ac.nz#showering_005", + "http://uca1.abd.muse.massey.ac.nz#showering_006", + "http://uca1.abd.muse.massey.ac.nz#showering_009", + "http://uca1.abd.muse.massey.ac.nz#showering_011", + "http://uca1.abd.muse.massey.ac.nz#showering_012", + "http://uca1.abd.muse.massey.ac.nz#showering_015", + "http://uca1.abd.muse.massey.ac.nz#showering_016", + "http://uca1.abd.muse.massey.ac.nz#showering_018", + "http://uca1.abd.muse.massey.ac.nz#showering_024", + "http://uca1.abd.muse.massey.ac.nz#showering_025", + "http://uca1.abd.muse.massey.ac.nz#showering_027", + "http://uca1.abd.muse.massey.ac.nz#showering_029", + "http://uca1.abd.muse.massey.ac.nz#showering_030", + "http://uca1.abd.muse.massey.ac.nz#showering_034", + "http://uca1.abd.muse.massey.ac.nz#showering_035", + "http://uca1.abd.muse.massey.ac.nz#showering_036", + "http://uca1.abd.muse.massey.ac.nz#showering_040", + "http://uca1.abd.muse.massey.ac.nz#showering_041", + "http://uca1.abd.muse.massey.ac.nz#showering_042", + "http://uca1.abd.muse.massey.ac.nz#showering_043", + "http://uca1.abd.muse.massey.ac.nz#showering_045", + "http://uca1.abd.muse.massey.ac.nz#showering_048", + "http://uca1.abd.muse.massey.ac.nz#showering_049", + "http://uca1.abd.muse.massey.ac.nz#showering_050", + "http://uca1.abd.muse.massey.ac.nz#showering_051", + "http://uca1.abd.muse.massey.ac.nz#showering_056", + "http://uca1.abd.muse.massey.ac.nz#showering_057", + "http://uca1.abd.muse.massey.ac.nz#showering_059", + "http://uca1.abd.muse.massey.ac.nz#showering_060", + "http://uca1.abd.muse.massey.ac.nz#showering_064", + "http://uca1.abd.muse.massey.ac.nz#showering_068", + "http://uca1.abd.muse.massey.ac.nz#showering_070", + "http://uca1.abd.muse.massey.ac.nz#showering_071", + "http://uca1.abd.muse.massey.ac.nz#showering_074", + "http://uca1.abd.muse.massey.ac.nz#showering_080", + "http://uca1.abd.muse.massey.ac.nz#showering_081", + "http://uca1.abd.muse.massey.ac.nz#showering_082", + "http://uca1.abd.muse.massey.ac.nz#showering_083", + "http://uca1.abd.muse.massey.ac.nz#showering_087", + "http://uca1.abd.muse.massey.ac.nz#showering_088", + "http://uca1.abd.muse.massey.ac.nz#showering_089", + "http://uca1.abd.muse.massey.ac.nz#showering_090", + "http://uca1.abd.muse.massey.ac.nz#showering_093", + "http://uca1.abd.muse.massey.ac.nz#showering_094", + "http://uca1.abd.muse.massey.ac.nz#showering_095", + "http://uca1.abd.muse.massey.ac.nz#showering_097", + "http://uca1.abd.muse.massey.ac.nz#showering_105", + "http://uca1.abd.muse.massey.ac.nz#showering_106", + "http://uca1.abd.muse.massey.ac.nz#showering_109", + "http://uca1.abd.muse.massey.ac.nz#showering_110", + "http://uca1.abd.muse.massey.ac.nz#showering_112", + "http://uca1.abd.muse.massey.ac.nz#showering_113", + "http://uca1.abd.muse.massey.ac.nz#showering_115", + "http://uca1.abd.muse.massey.ac.nz#showering_116", + "http://uca1.abd.muse.massey.ac.nz#showering_119", + "http://uca1.abd.muse.massey.ac.nz#showering_122", + "http://uca1.abd.muse.massey.ac.nz#showering_124", + "http://uca1.abd.muse.massey.ac.nz#showering_125", + "http://uca1.abd.muse.massey.ac.nz#showering_127", + "http://uca1.abd.muse.massey.ac.nz#showering_129", + "http://uca1.abd.muse.massey.ac.nz#showering_131", + "http://uca1.abd.muse.massey.ac.nz#showering_133", + "http://uca1.abd.muse.massey.ac.nz#showering_135", + "http://uca1.abd.muse.massey.ac.nz#showering_139", + "http://uca1.abd.muse.massey.ac.nz#showering_140", + "http://uca1.abd.muse.massey.ac.nz#showering_142", + "http://uca1.abd.muse.massey.ac.nz#showering_144", + "http://uca1.abd.muse.massey.ac.nz#showering_145", + "http://uca1.abd.muse.massey.ac.nz#showering_146", + "http://uca1.abd.muse.massey.ac.nz#showering_147", + "http://uca1.abd.muse.massey.ac.nz#showering_149", + "http://uca1.abd.muse.massey.ac.nz#showering_150" +} + + +lp.negativeExamples = { + "http://uca1.abd.muse.massey.ac.nz#showering_001", + "http://uca1.abd.muse.massey.ac.nz#showering_002", + "http://uca1.abd.muse.massey.ac.nz#showering_003", + "http://uca1.abd.muse.massey.ac.nz#showering_007", + "http://uca1.abd.muse.massey.ac.nz#showering_008", + "http://uca1.abd.muse.massey.ac.nz#showering_010", + "http://uca1.abd.muse.massey.ac.nz#showering_013", + "http://uca1.abd.muse.massey.ac.nz#showering_014", + "http://uca1.abd.muse.massey.ac.nz#showering_017", + "http://uca1.abd.muse.massey.ac.nz#showering_019", + "http://uca1.abd.muse.massey.ac.nz#showering_020", + "http://uca1.abd.muse.massey.ac.nz#showering_021", + "http://uca1.abd.muse.massey.ac.nz#showering_022", + "http://uca1.abd.muse.massey.ac.nz#showering_023", + "http://uca1.abd.muse.massey.ac.nz#showering_026", + "http://uca1.abd.muse.massey.ac.nz#showering_028", + "http://uca1.abd.muse.massey.ac.nz#showering_031", + "http://uca1.abd.muse.massey.ac.nz#showering_032", + "http://uca1.abd.muse.massey.ac.nz#showering_033", + "http://uca1.abd.muse.massey.ac.nz#showering_037", + "http://uca1.abd.muse.massey.ac.nz#showering_038", + "http://uca1.abd.muse.massey.ac.nz#showering_039", + "http://uca1.abd.muse.massey.ac.nz#showering_044", + "http://uca1.abd.muse.massey.ac.nz#showering_046", + "http://uca1.abd.muse.massey.ac.nz#showering_047", + "http://uca1.abd.muse.massey.ac.nz#showering_052", + "http://uca1.abd.muse.massey.ac.nz#showering_053", + "http://uca1.abd.muse.massey.ac.nz#showering_054", + "http://uca1.abd.muse.massey.ac.nz#showering_055", + "http://uca1.abd.muse.massey.ac.nz#showering_058", + "http://uca1.abd.muse.massey.ac.nz#showering_061", + "http://uca1.abd.muse.massey.ac.nz#showering_062", + "http://uca1.abd.muse.massey.ac.nz#showering_063", + "http://uca1.abd.muse.massey.ac.nz#showering_065", + "http://uca1.abd.muse.massey.ac.nz#showering_066", + "http://uca1.abd.muse.massey.ac.nz#showering_067", + "http://uca1.abd.muse.massey.ac.nz#showering_069", + "http://uca1.abd.muse.massey.ac.nz#showering_072", + "http://uca1.abd.muse.massey.ac.nz#showering_073", + "http://uca1.abd.muse.massey.ac.nz#showering_075", + "http://uca1.abd.muse.massey.ac.nz#showering_076", + "http://uca1.abd.muse.massey.ac.nz#showering_077", + "http://uca1.abd.muse.massey.ac.nz#showering_078", + "http://uca1.abd.muse.massey.ac.nz#showering_079", + "http://uca1.abd.muse.massey.ac.nz#showering_084", + "http://uca1.abd.muse.massey.ac.nz#showering_085", + "http://uca1.abd.muse.massey.ac.nz#showering_086", + "http://uca1.abd.muse.massey.ac.nz#showering_091", + "http://uca1.abd.muse.massey.ac.nz#showering_092", + "http://uca1.abd.muse.massey.ac.nz#showering_096", + "http://uca1.abd.muse.massey.ac.nz#showering_098", + "http://uca1.abd.muse.massey.ac.nz#showering_099", + "http://uca1.abd.muse.massey.ac.nz#showering_100", + "http://uca1.abd.muse.massey.ac.nz#showering_101", + "http://uca1.abd.muse.massey.ac.nz#showering_102", + "http://uca1.abd.muse.massey.ac.nz#showering_103", + "http://uca1.abd.muse.massey.ac.nz#showering_104", + "http://uca1.abd.muse.massey.ac.nz#showering_107", + "http://uca1.abd.muse.massey.ac.nz#showering_108", + "http://uca1.abd.muse.massey.ac.nz#showering_111", + "http://uca1.abd.muse.massey.ac.nz#showering_114", + "http://uca1.abd.muse.massey.ac.nz#showering_117", + "http://uca1.abd.muse.massey.ac.nz#showering_118", + "http://uca1.abd.muse.massey.ac.nz#showering_120", + "http://uca1.abd.muse.massey.ac.nz#showering_121", + "http://uca1.abd.muse.massey.ac.nz#showering_123", + "http://uca1.abd.muse.massey.ac.nz#showering_126", + "http://uca1.abd.muse.massey.ac.nz#showering_128", + "http://uca1.abd.muse.massey.ac.nz#showering_130", + "http://uca1.abd.muse.massey.ac.nz#showering_132", + "http://uca1.abd.muse.massey.ac.nz#showering_134", + "http://uca1.abd.muse.massey.ac.nz#showering_136", + "http://uca1.abd.muse.massey.ac.nz#showering_137", + "http://uca1.abd.muse.massey.ac.nz#showering_138", + "http://uca1.abd.muse.massey.ac.nz#showering_141", + "http://uca1.abd.muse.massey.ac.nz#showering_143", + "http://uca1.abd.muse.massey.ac.nz#showering_148" +} + diff --git a/interfaces/src/main/java/org/dllearner/cli/CrossValidation.java b/interfaces/src/main/java/org/dllearner/cli/CrossValidation.java index 4b374703fe..a35d7c4034 100644 --- a/interfaces/src/main/java/org/dllearner/cli/CrossValidation.java +++ b/interfaces/src/main/java/org/dllearner/cli/CrossValidation.java @@ -63,6 +63,16 @@ public class CrossValidation { protected Stat fMeasure = new Stat(); protected Stat fMeasureTraining = new Stat(); + protected Stat trainingCompletenessStat; + protected Stat trainingCorrectnessStat; + + protected Stat testingCompletenessStat; + protected Stat testingCorrectnessStat; + + protected Stat totalNumberOfDescriptions; + protected Stat minimalDescriptionNeeded; + protected Stat learningTimeForBestDescription; + public static boolean writeToFile = false; public static File outputFile; public static boolean multiThreaded = false; diff --git a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java index fa85522f9e..573b244cae 100644 --- a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java +++ b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java @@ -1,16 +1,38 @@ package org.dllearner.cli; +import com.github.jsonldjava.shaded.com.google.common.collect.Sets; import org.apache.log4j.Level; +import org.dllearner.accuracymethods.AccMethodPredAcc; +import org.dllearner.algorithms.parcel.ParCELEvaluationResult; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.configuration.IConfiguration; +import org.dllearner.configuration.spring.ApplicationContextBuilder; +import org.dllearner.configuration.spring.DefaultApplicationContextBuilder; +import org.dllearner.confparser.ConfParserConfiguration; +import org.dllearner.confparser.ParseException; import org.dllearner.core.*; import org.dllearner.learningproblems.EvaluatedDescriptionPosNeg; +import org.dllearner.learningproblems.PosNegLP; import org.dllearner.utilities.OWLAPIUtils; +import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLIndividual; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * Evaluate a class expression on a PosNegLP @@ -56,18 +78,107 @@ public void run() { lp = context.getBean(AbstractClassExpressionLearningProblem.class); rs = lp.getReasoner(); - expression = OWLAPIUtils.classExpressionPropertyExpanderChecked(this.expression, rs, dataFactory, true, logger); - if (expression != null) { - EvaluatedHypothesis ev = lp.evaluate(expression); - if (ev instanceof EvaluatedDescriptionPosNeg) { - logger.info("#EVAL# tp: " + ((EvaluatedDescriptionPosNeg) ev).getCoveredPositives().size()); - logger.info("#EVAL# fp: " + ((EvaluatedDescriptionPosNeg) ev).getCoveredNegatives().size()); - logger.info("#EVAL# tn: " + ((EvaluatedDescriptionPosNeg) ev).getNotCoveredNegatives().size()); - logger.info("#EVAL# fn: " + ((EvaluatedDescriptionPosNeg) ev).getNotCoveredPositives().size()); +// expression = OWLAPIUtils.classExpressionPropertyExpanderChecked(this.expression, rs, dataFactory, true, logger); +// if (expression != null) { +// EvaluatedHypothesis ev = lp.evaluate(expression); +// if (ev instanceof EvaluatedDescriptionPosNeg) { +// logger.info("#EVAL# tp: " + ((EvaluatedDescriptionPosNeg) ev).getCoveredPositives().size()); +// logger.info("#EVAL# fp: " + ((EvaluatedDescriptionPosNeg) ev).getCoveredNegatives().size()); +// logger.info("#EVAL# tn: " + ((EvaluatedDescriptionPosNeg) ev).getNotCoveredNegatives().size()); +// logger.info("#EVAL# fn: " + ((EvaluatedDescriptionPosNeg) ev).getNotCoveredPositives().size()); +// } +// } else { +// logger.error("Expression is empty."); +// throw new RuntimeException("Expression is empty."); +// } + + expression = dataFactory.getOWLObjectSomeValuesFrom( + dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), + dataFactory.getOWLObjectIntersectionOf( + dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), + dataFactory.getOWLObjectMinCardinality( + 2, + dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), + dataFactory.getOWLThing() + ) + ) + ); + + logger.info("#EVAL# expression: " + expression); + + Set pos = ((ParCELPosNegLP) lp).getPositiveExamples(); + Set neg = ((ParCELPosNegLP) lp).getNegativeExamples(); + + int tp = rs.hasType(expression, pos).size(); + int fp = rs.hasType(expression, neg).size(); + int tn = neg.size() - fp; + int fn = pos.size() - tp; + double acc = (new AccMethodPredAcc(true)).getAccOrTooWeak2(tp, fn, fp, tn, 1); + + logger.info("#EVAL# tp: " + tp); + logger.info("#EVAL# fp: " + fp); + logger.info("#EVAL# tn: " + tn); + logger.info("#EVAL# fn: " + fn); + logger.info("#EVAL# acc: " + acc); + + ParCELEvaluationResult ev =((ParCELPosNegLP) lp).getAccuracyAndCorrectness4(expression, 1); + System.out.println(ev); + + Set coveredIndividuals = rs.getIndividuals(expression); + System.out.println(Sets.intersection(pos, coveredIndividuals).size()); + System.out.println(Sets.intersection(neg, coveredIndividuals).size()); + } + + public static void main(String[] args) throws ParseException, IOException, ReasoningMethodUnsupportedException { + System.out.println("DL-Learner expression validation"); + + // currently, CLI has exactly one parameter - the conf file + if(args.length == 0) { + System.out.println("You need to give a conf file as argument."); + System.exit(0); + } + + // read file and print and print a message if it does not exist + File file = new File(args[args.length - 1]); + if(!file.exists()) { + System.out.println("File \"" + file + "\" does not exist."); + System.exit(0); + } + + Resource confFile = new FileSystemResource(file); + + List springConfigResources = new ArrayList<>(); + + try { + //DL-Learner Configuration Object + IConfiguration configuration = new ConfParserConfiguration(confFile); + + ApplicationContextBuilder builder = new DefaultApplicationContextBuilder(); + ApplicationContext context = builder.buildApplicationContext(configuration,springConfigResources); + + ExpressionValidation validation = new ExpressionValidation(); + validation.setContext(context); + validation.setConfFile(file); + validation.run(); + validation.close(); + } catch (Exception e) { + String stacktraceFileName = "log/error.log"; + + //Find the primary cause of the exception. + Throwable primaryCause = findPrimaryCause(e); + + // Get the Root Error Message + logger.error("An Error Has Occurred During Processing."); + if (primaryCause != null) { + logger.error(primaryCause.getMessage()); } - } else { - logger.error("Expression is empty."); - throw new RuntimeException("Expression is empty."); + logger.debug("Stack Trace: ", e); + logger.error("Terminating DL-Learner...and writing stacktrace to: " + stacktraceFileName); + createIfNotExists(new File(stacktraceFileName)); + + FileOutputStream fos = new FileOutputStream(stacktraceFileName); + PrintStream ps = new PrintStream(fos); + e.printStackTrace(ps); } } } diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/CELOEFortifiedCrossValidation3PhasesFair.java b/interfaces/src/main/java/org/dllearner/cli/parcel/CELOEFortifiedCrossValidation3PhasesFair.java new file mode 100644 index 0000000000..3334abf41a --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/CELOEFortifiedCrossValidation3PhasesFair.java @@ -0,0 +1,2021 @@ +package org.dllearner.cli.parcel; + +import java.text.DecimalFormat; +import java.util.*; + +import com.google.common.collect.Sets; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.celoe.CELOEPartial; +import org.dllearner.cli.parcel.fortification.FortificationUtils; +import org.dllearner.cli.parcel.fortification.JaccardSimilarity; +import org.dllearner.algorithms.celoe.CELOE; +import org.dllearner.cli.CrossValidation; +import org.dllearner.core.ComponentInitException; +import org.dllearner.core.AbstractCELA; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.kb.OWLFile; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.dllearner.utilities.statistics.Stat; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyManager; + +import com.clarkparsia.pellet.owlapiv3.PelletReasoner; +import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory; + +/** + * Performs cross validation for the given problem. Supports k-fold cross-validation and + * + * @author An C. Tran + * + */ +public class CELOEFortifiedCrossValidation3PhasesFair extends CrossValidation { + + + protected Stat noOfCounterPartialDefinitionsStat; + protected Stat noOfLabelFortifyDefinitions; + protected Stat avgLabelCpdefLengthStat; + protected Stat avgLabelFortifyCpdefCoverage; + + //fortify variables + protected Stat lableFortifyDefinitionLengthStat; + protected Stat labelFortifyDefinitionLengthStat; + + //label fortification + protected Stat accuracyLabelFortifyStat; + protected Stat correctnessLabelFortifyStat; + protected Stat completenessLabelFortifyStat; + protected Stat fmeasureLabelFortifyStat; + + protected Stat avgFortifyCoverageTraingStat; + protected Stat avgFortifyCoverageTestStat; + + protected Stat fortifiedRuntime; + //protected int forstificationStopOnFirstDefinition = -1; + + //blind fortification + protected Stat accuracyBlindFortifyStat; + protected Stat correctnessBlindFortifyStat; + protected Stat completenessBlindFortifyStat; + protected Stat fmeasureBlindFortifyStat; + + protected Stat totalCPDefLengthStat; + protected Stat avgCPDefLengthStat; + + //hold the fortified accuracy, fmeasure,... of 5%, 10%, 20%, ..., 50% of cpdef used + protected Stat[][] accuracyPercentageFortifyStepStat; //hold the fortified accuracy at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] completenessPercentageFortifyStepStat; //hold the fortified completeness at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] correctnessPercentageFortifyStepStat; //hold the fortified correctness at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] fmeasurePercentageFortifyStepStat; //hold the fortified correctness at 5,10,20,30,40,50% (multi-strategies) + + protected Stat[] noOfCpdefUsedMultiStepFortStat; + + protected double[][] accuracyHalfFullStep; + protected double[][] fmeasureHalfFullStep; + + protected Stat[][] accuracyFullStepStat; + protected Stat[][] fmeasureFullStepStat; + protected Stat[][] correctnessFullStepStat; + protected Stat[][] completenessFullStepStat; + + + //---------------------------------- + //FAIR comparison + protected Stat fairLearningTimeStat; + protected Stat fairAccuracyStat; + protected Stat fairFmeasureStat; + protected Stat fairCorrectnessStat; + protected Stat fairCompletenessStat; + //---------------------------------- + + Logger logger = Logger.getLogger(this.getClass()); + + public CELOEFortifiedCrossValidation3PhasesFair() { + + } + + /* + public CELOEFortifiedCrossValidation3PhasesFair(AbstractCELA la, PosNegLP lp, AbstractReasonerComponent rs, int folds, + boolean leaveOneOut) { + + this(la, lp, rs, folds, leaveOneOut, 1, 0, 0, false); + + } + */ + + /* + public CELOEFortifiedCrossValidation3PhasesFair(AbstractCELA la, PosNegLP lp, AbstractReasonerComponent rs, int folds, + boolean leaveOneOut, int noOfRuns) { + + this(la, lp, rs, folds, leaveOneOut, noOfRuns, 0, 0, false); + } + */ + + /** + * Main method + * + * @param la + * @param lp + * @param rs + * @param folds + * @param leaveOneOut + * @param noOfRuns + * @param fortificationNoise + * @param fortificationTimeout + * @param fairComparison + */ + public CELOEFortifiedCrossValidation3PhasesFair(AbstractCELA la, PosNegLP lp, AbstractReasonerComponent rs, int folds, + boolean leaveOneOut, int noOfRuns, double fortificationNoise, int fortificationTimeout, boolean fairComparison, int fortificationStopOnFirstPosDefinition) { + + DecimalFormat df = new DecimalFormat(); + + String baseURI = rs.getBaseURI(); + Map prefixes = rs.getPrefixes(); + + // the training and test sets used later on + List> trainingSetsPos = new LinkedList<>(); + List> trainingSetsNeg = new LinkedList<>(); + List> testSetsPos = new LinkedList<>(); + List> testSetsNeg = new LinkedList<>(); + List> fortificationSetsPos = new LinkedList<>(); + List> fortificationSetsNeg = new LinkedList<>(); + + // get examples and shuffle them too + Set posExamples = ((PosNegLP) lp).getPositiveExamples(); + List posExamplesList = new LinkedList<>(posExamples); + //Collections.shuffle(posExamplesList, new Random(1)); + Set negExamples = ((PosNegLP) lp).getNegativeExamples(); + List negExamplesList = new LinkedList<>(negExamples); + //Collections.shuffle(negExamplesList, new Random(2)); + + // sanity check whether nr. of folds makes sense for this benchmark + if (!leaveOneOut && (posExamples.size() < folds && negExamples.size() < folds)) { + System.out.println("The number of folds is higher than the number of " + + "positive/negative examples. This can result in empty test sets. Exiting."); + System.exit(0); + } + + // calculating where to split the sets, ; note that we split + // positive and negative examples separately such that the + // distribution of positive and negative examples remains similar + // (note that there are better but more complex ways to implement this, + // which guarantee that the sum of the elements of a fold for pos + // and neg differs by at most 1 - it can differ by 2 in our implementation, + // e.g. with 3 folds, 4 pos. examples, 4 neg. examples) + int[] splitsPos = calculateSplits(posExamples.size(), folds); + int[] splitsNeg = calculateSplits(negExamples.size(), folds); + + /* + //for orthogonality check + long orthAllCheckCount[] = new long[5]; + orthAllCheckCount[0] = orthAllCheckCount[1] = orthAllCheckCount[2] = orthAllCheckCount[3] = orthAllCheckCount[4] = 0; + + long orthSelectedCheckCount[] = new long[5]; + orthSelectedCheckCount[0] = orthSelectedCheckCount[1] = orthSelectedCheckCount[2] = orthSelectedCheckCount[3] = orthSelectedCheckCount[4] = 0; + */ + + // calculating training and test sets + for (int i = 0; i < folds; i++) { + Set testPos = getTestingSet(posExamplesList, splitsPos, i); + Set testNeg = getTestingSet(negExamplesList, splitsNeg, i); + testSetsPos.add(i, testPos); + testSetsNeg.add(i, testNeg); + + //fortification training set + Set fortPos = getTestingSet(posExamplesList, splitsPos, (i+1) % folds); + Set fortNeg = getTestingSet(negExamplesList, splitsNeg, (i+1) % folds); + fortificationSetsPos.add(i, fortPos); + fortificationSetsNeg.add(i, fortNeg); + + Set trainingPos = getTrainingSet(posExamples, testPos); + Set trainingNeg = getTrainingSet(negExamples, testNeg); + + trainingPos.removeAll(fortPos); + trainingNeg.removeAll(fortNeg); + + trainingSetsPos.add(i, trainingPos); + trainingSetsNeg.add(i, trainingNeg); + } //end of calculating datasets (training, test, fortification) + + // --------------------------------- + // k-fold cross validation + // --------------------------------- + + Stat runtimeAvg = new Stat(); + Stat runtimeMax = new Stat(); + Stat runtimeMin = new Stat(); + Stat runtimeDev = new Stat(); + + Stat defLenAvg = new Stat(); + Stat defLenDev = new Stat(); + Stat defLenMax = new Stat(); + Stat defLenMin = new Stat(); + + Stat trainingAccAvg = new Stat(); + Stat trainingAccDev = new Stat(); + Stat trainingAccMax = new Stat(); + Stat trainingAccMin = new Stat(); + + Stat trainingCorAvg = new Stat(); + Stat trainingCorDev = new Stat(); + Stat trainingCorMax = new Stat(); + Stat trainingCorMin = new Stat(); + + Stat trainingComAvg = new Stat(); + Stat trainingComDev = new Stat(); + Stat trainingComMax = new Stat(); + Stat trainingComMin = new Stat(); + + Stat testingAccAvg = new Stat(); + Stat testingAccMax = new Stat(); + Stat testingAccMin = new Stat(); + Stat testingAccDev = new Stat(); + + Stat testingCorAvg = new Stat(); + Stat testingCorDev = new Stat(); + Stat testingCorMax = new Stat(); + Stat testingCorMin = new Stat(); + + Stat testingComAvg = new Stat(); + Stat testingComDev = new Stat(); + Stat testingComMax = new Stat(); + Stat testingComMin = new Stat(); + + Stat testingFMesureAvg = new Stat(); + Stat testingFMesureDev = new Stat(); + Stat testingFMesureMax = new Stat(); + Stat testingFMesureMin = new Stat(); + + Stat trainingFMesureAvg = new Stat(); + Stat trainingFMesureDev = new Stat(); + Stat trainingFMesureMax = new Stat(); + Stat trainingFMesureMin = new Stat(); + + Stat noOfDescriptionsAgv = new Stat(); + Stat noOfDescriptionsMax = new Stat(); + Stat noOfDescriptionsMin = new Stat(); + Stat noOfDescriptionsDev = new Stat(); + + //fortify stat. variables + Stat noOfCounterPartialDefinitionsAvg = new Stat(); + Stat noOfCounterPartialDefinitionsDev = new Stat(); + Stat noOfCounterPartialDefinitionsMax = new Stat(); + Stat noOfCounterPartialDefinitionsMin = new Stat(); + + //this is for ParCELEx only + Stat noOfCounterPartialDefinitionsUsedAvg = new Stat(); + Stat noOfCounterPartialDefinitionsUsedDev = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMax = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMin = new Stat(); + + Stat avgCounterPartialDefinitionLengthAvg = new Stat(); + Stat avgCounterPartialDefinitionLengthDev = new Stat(); + Stat avgCounterPartialDefinitionLengthMax = new Stat(); + Stat avgCounterPartialDefinitionLengthMin = new Stat(); + + + Stat avgFirtifiedDefinitionLengthAvg = new Stat(); + Stat avgFirtifiedDefinitionLengthDev = new Stat(); + Stat avgFirtifiedDefinitionLengthMax = new Stat(); + Stat avgFirtifiedDefinitionLengthMin = new Stat(); + + Stat accuracyFortifyAvg = new Stat(); + Stat accuracyFortifyDev = new Stat(); + Stat accuracyFortifyMax = new Stat(); + Stat accuracyFortifyMin = new Stat(); + + Stat correctnessFortifyAvg = new Stat(); + Stat correctnessFortifyDev = new Stat(); + Stat correctnessFortifyMax = new Stat(); + Stat correctnessFortifyMin = new Stat(); + + Stat completenessFortifyAvg = new Stat(); + Stat completenessFortifyDev = new Stat(); + Stat completenessFortifyMax = new Stat(); + Stat completenessFortifyMin = new Stat(); + + Stat fmeasureFortifyAvg = new Stat(); + Stat fmeasureFortifyDev = new Stat(); + Stat fmeasureFortifyMax = new Stat(); + Stat fmeasureFortifyMin = new Stat(); + + Stat avgFortifyCoverageTraingAvg = new Stat(); + Stat avgFortifyCoverageTraingDev = new Stat(); + Stat avgFortifyCoverageTraingMax = new Stat(); + Stat avgFortifyCoverageTraingMin = new Stat(); + + Stat avgFortifyCoverageTestAvg = new Stat(); + Stat avgFortifyCoverageTestDev = new Stat(); + Stat avgFortifyCoverageTestMax = new Stat(); + Stat avgFortifyCoverageTestMin = new Stat(); + + + //---------------------------------------------------------------------- + //loading ontology into Pellet reasoner for checking + //the orthogonality and satisfiability (fortification training strategy) + //---------------------------------------------------------------------- + long ontologyLoadStarttime = System.nanoTime(); + OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); + OWLOntology ontology = ((OWLFile)la.getReasoner().getSources().iterator().next()).createOWLOntology(manager); + outputWriter("Ontology created, axiom count: " + ontology.getAxiomCount()); + PelletReasoner pelletReasoner = PelletReasonerFactory.getInstance().createReasoner(ontology); + outputWriter("Pellet creared and binded with the ontology: " + pelletReasoner.getReasonerName()); + long ontologyLoadDuration = System.nanoTime() - ontologyLoadStarttime; + outputWriter("Total time for creating and binding ontology: " + ontologyLoadDuration/1000000000d + "ms"); + //---------------------------------------------------------------------- + + + boolean celoeFirstOnFirstDefinition = ((CELOEPartial)la).isStopOnFirstDefinition(); + + for (int kk = 0; kk < noOfRuns; kk++) { + + //stat. variables for each fold ==> need to be re-created after each fold + runtime = new Stat(); + length = new Stat(); + accuracyTraining = new Stat(); + trainingCorrectnessStat = new Stat(); + trainingCompletenessStat = new Stat(); + accuracy = new Stat(); + testingCorrectnessStat = new Stat(); + testingCompletenessStat = new Stat(); + fMeasure = new Stat(); + fMeasureTraining = new Stat(); + + noOfCounterPartialDefinitionsStat = new Stat(); + noOfLabelFortifyDefinitions = new Stat(); + avgLabelCpdefLengthStat = new Stat(); + avgLabelFortifyCpdefCoverage = new Stat(); + + totalNumberOfDescriptions = new Stat(); + + //fortify variables + lableFortifyDefinitionLengthStat = new Stat(); + labelFortifyDefinitionLengthStat = new Stat(); + + accuracyLabelFortifyStat = new Stat(); + correctnessLabelFortifyStat = new Stat(); + completenessLabelFortifyStat = new Stat(); + fmeasureLabelFortifyStat = new Stat(); + + avgFortifyCoverageTraingStat = new Stat(); + avgFortifyCoverageTestStat = new Stat(); + + fortifiedRuntime = new Stat(); + + //blind fortification + accuracyBlindFortifyStat = new Stat(); + correctnessBlindFortifyStat = new Stat(); + completenessBlindFortifyStat = new Stat(); + fmeasureBlindFortifyStat = new Stat(); + + totalCPDefLengthStat = new Stat(); + avgCPDefLengthStat = new Stat(); + + + //fair evaluation variables initialization + fairAccuracyStat = new Stat(); + fairFmeasureStat = new Stat(); + fairCorrectnessStat = new Stat(); + fairCompletenessStat = new Stat(); + fairLearningTimeStat = new Stat(); + + + int noOfStrategies = FortificationUtils.strategyNames.length; + + + //fortification accuracy + accuracyPercentageFortifyStepStat = new Stat[noOfStrategies][6]; //6 elements for six values of 5%, 10%, ..., 50% + completenessPercentageFortifyStepStat = new Stat[noOfStrategies][6]; + correctnessPercentageFortifyStepStat = new Stat[noOfStrategies][6]; + fmeasurePercentageFortifyStepStat = new Stat[noOfStrategies][6]; + + //initial fortification accuracy by PERCENTAGE + for (int i=0; i 0) + ((CELOEPartial)la).setMaxExecutionTimeInSeconds(fortificationTimeout); + + + //start the learner + long algorithmStartTimeCpdef = System.nanoTime(); + la.start(); + long algorithmDurationCpdef = System.nanoTime() - algorithmStartTimeCpdef; + + + //get and store the counter partial definitions + + /** + * all counter partial definition sorted by the training neg. coverage (coverage of training neg. example) + */ + TreeSet counterPartialDefinitions = new TreeSet(new FortificationUtils.CoverageComparator()); + + counterPartialDefinitions.addAll(((CELOEPartial)la).getPartialDefinitions()); + + outputWriter("Finish learning, number of counter partial definitions: " + counterPartialDefinitions.size()); + + noOfCounterPartialDefinitionsStat.addNumber(counterPartialDefinitions.size()); + + + //----------------------------------------------------- + // 2. Do the NORMAL learn: learn definition for pos + // Re-assign the pos/neg and restart the learner + //----------------------------------------------------- + + //set the pos/neg examples + lp.setPositiveExamples(trainingSetsPos.get(currFold)); + lp.setNegativeExamples(trainingSetsNeg.get(currFold)); + + + //init the learner + try { + lp.init(); + la.init(); + ((CELOEPartial)la).setStopOnFirstDefinition(true); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + + //set the noise + timeout + stopOnFirstDefinition to the original values + ((CELOEPartial)la).setNoisePercentage(orgNoise); + ((CELOEPartial)la).setMaxExecutionTimeInSeconds(orgTimeout); + ((CELOEPartial)la).setStopOnFirstDefinition(celoeFirstOnFirstDefinition); + + + outputWriter("\n** Phase 2 - Learning the main concept"); + outputWriter("Noise: " + orgNoise + "%, timeout=" + orgTimeout); + + + //----------------------------- + //start learning the 2nd phase + //----------------------------- + long algorithmStartTimePdef = System.nanoTime(); + la.start(); + long algorithmDurationPdef = System.nanoTime() - algorithmStartTimePdef; + runtime.addNumber(algorithmDurationPdef / (double) 1000000000); + + fortifiedRuntime.addNumber((algorithmDurationCpdef + algorithmDurationPdef)/1000000000d); + + //---------------------------- + //FINISHED learning + //---------------------------- + + //get the learned concept + OWLClassExpression concept = la.getCurrentlyBestDescription(); + +// long noOfDescriptionGeneratedPdef = la.getTotalNumberOfDescriptionsGenerated(); // TODO not available yet +// totalNumberOfDescriptions.addNumber(noOfDescriptionGeneratedPdef); + + //---------------------------------------------- + //check if another "FAIR" evaluation is needed + //---------------------------------------------- + boolean fairEvaluationNeeded = false; + OWLClassExpression conceptFair = null; + + if (fairComparison && algorithmDurationPdef/(double) 1000000000 >= ((CELOEPartial)la).getMaxExecutionTimeInSeconds()) { + fairEvaluationNeeded = true; + + + long fairLearningTimeout = orgTimeout; + if (fortificationTimeout == 0) + fairLearningTimeout *= 2; + else + fairLearningTimeout += fortificationTimeout; + + + outputWriter("\n** Phase 3 - Learning the main concept again with double timeout value (for fair comparison): " + + fairLearningTimeout + "s"); + + //init the learner + //set the pos/neg examples + lp.setPositiveExamples(trainingSetsPos.get(currFold)); + lp.setNegativeExamples(trainingSetsNeg.get(currFold)); + try { + lp.init(); + la.init(); + ((CELOEPartial)la).setStopOnFirstDefinition(true); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + + //set the fair learning timeout + ((CELOEPartial)la).setMaxExecutionTimeInSeconds(fairLearningTimeout); + + + //----------------------------- + //start learning the 3rd phase + //----------------------------- + long algorithmStartTimeFair = System.nanoTime(); + la.start(); + long algorithmDurationFair = System.nanoTime() - algorithmStartTimeFair; + fairLearningTimeStat.addNumber(algorithmDurationFair / (double) 1000000000); + + //reset the timeout value + ((CELOEPartial)la).setMaxExecutionTimeInSeconds(orgTimeout); + + conceptFair = ((CELOEPartial)la).getCurrentlyBestDescription(); + } + else { + fairLearningTimeStat.addNumber(algorithmDurationPdef); + } + + + //---------------------------- + //TRAINING accuracy + //---------------------------- + Set curFoldPosTrainingSet = trainingSetsPos.get(currFold); + Set curFoldNegTrainingSet = trainingSetsNeg.get(currFold); + + int correctTrainingPosClassified = getCorrectPosClassified(rs, concept, curFoldPosTrainingSet); + int correctTrainingNegClassified = getCorrectNegClassified(rs, concept, curFoldNegTrainingSet); + int correctTrainingExamples = correctTrainingPosClassified + correctTrainingNegClassified; + + double trainingAccuracy = 100 * ((double) correctTrainingExamples / + (curFoldPosTrainingSet.size() + curFoldNegTrainingSet.size())); + double trainingCompleteness = 100*(double)correctTrainingPosClassified/curFoldPosTrainingSet.size(); + double trainingCorrectness = 100*(double)correctTrainingNegClassified/curFoldNegTrainingSet.size(); + + accuracyTraining.addNumber(trainingAccuracy); + trainingCompletenessStat.addNumber(trainingCompleteness); + trainingCorrectnessStat.addNumber(trainingCorrectness); + + // calculate training F-Score + int negAsPosTraining = curFoldNegTrainingSet.size() - correctTrainingNegClassified; //neg - un = cn + double precisionTraining = (correctTrainingPosClassified + negAsPosTraining) == 0 ? 0 + : correctTrainingPosClassified / (double) (correctTrainingPosClassified + negAsPosTraining); + double recallTraining = correctTrainingPosClassified / (double) curFoldPosTrainingSet.size(); + double fMeasureTrainingFold = 100 * Heuristics.getFScore(recallTraining, precisionTraining); + + fMeasureTraining.addNumber(fMeasureTrainingFold); + + + //--------------------- + //TEST accuracy + //--------------------- + Set curFoldPosTestSet = testSetsPos.get(currFold); + Set curFoldNegTestSet = testSetsNeg.get(currFold); + + + //calculate testing coverage + Set cpTest = rs.hasType(concept, curFoldPosTestSet); //cp + Set upTest = Sets.difference(curFoldPosTestSet, cpTest); //up + Set cnTest = rs.hasType(concept, curFoldNegTestSet); //cn + + // calculate test accuracies + int correctTestPosClassified = cpTest.size(); //covered positive examples //curFoldPosTestSet.size() - upTest.size(); //getCorrectPosClassified(rs, concept, curFoldPosTestSet); + int correctTestNegClassified = curFoldNegTestSet.size() - cnTest.size(); //getCorrectNegClassified(rs, concept, curFoldNegTestSet); + int correctTestExamples = correctTestPosClassified + correctTestNegClassified; + + double testingAccuracyCurrFold = 100 * ((double) correctTestExamples / + (curFoldPosTestSet.size() + curFoldNegTestSet.size())); + double testingCompleteness = 100*(double)correctTestPosClassified/curFoldPosTestSet.size(); + double testingCorrectness = 100*(double)correctTestNegClassified/curFoldNegTestSet.size(); + + accuracy.addNumber(testingAccuracyCurrFold); + testingCompletenessStat.addNumber(testingCompleteness); + testingCorrectnessStat.addNumber(testingCorrectness); + + + // calculate test F-Score + int negAsPos = cnTest.size(); + double testPrecision = correctTestPosClassified + negAsPos == 0 ? 0 : correctTestPosClassified + / (double) (correctTestPosClassified + negAsPos); + double testRecall = correctTestPosClassified / (double) curFoldPosTestSet.size(); + + double fMeasureTestingFold = 100 * Heuristics.getFScore(testRecall, testPrecision); + fMeasure.addNumber(fMeasureTestingFold); + + length.addNumber(OWLClassExpressionUtils.getLength(concept)); + + //-------------------- + // FAIR accuracy + //-------------------- + double fairAccuracyCurrFold = testingAccuracyCurrFold; + double fairCompleteness = testingCompleteness; + double fairCorrectness = testingCorrectness; + double fairFMeasureCurrFold = fMeasureTestingFold; + + if (fairEvaluationNeeded) { + //calculate FAIR coverage + Set cpFair = rs.hasType(conceptFair, curFoldPosTestSet); //cp + //Set upFair = Helper.difference(curFoldPosTestSet, cpTest); //up + Set cnFair = rs.hasType(conceptFair, curFoldNegTestSet); //cn + + // calculate FAIR accuracy + int correctFairPosClassified = cpFair.size(); //covered positive examples //curFoldPosTestSet.size() - upTest.size(); //getCorrectPosClassified(rs, concept, curFoldPosTestSet); + int correctFairNegClassified = curFoldNegTestSet.size() - cnFair.size(); //getCorrectNegClassified(rs, concept, curFoldNegTestSet); + int correctFairExamples = correctFairPosClassified + correctFairNegClassified; + + fairAccuracyCurrFold = 100 * ((double) correctFairExamples / + (curFoldPosTestSet.size() + curFoldNegTestSet.size())); + fairCompleteness = 100*(double)correctFairPosClassified/curFoldPosTestSet.size(); + fairCorrectness = 100*(double)correctFairNegClassified/curFoldNegTestSet.size(); + + // calculate FAIR F-measure + int fairNegAsPos = cnTest.size(); + double fairPrecision = correctFairPosClassified + fairNegAsPos == 0 ? 0 : correctFairPosClassified + / (double) (correctFairPosClassified + fairNegAsPos); + double fairRecall = correctFairPosClassified / (double) curFoldPosTestSet.size(); + + fairFMeasureCurrFold = 100 * Heuristics.getFScore(fairRecall, fairPrecision); + } //fair evaluation + + fairAccuracyStat.addNumber(fairAccuracyCurrFold); + fairCorrectnessStat.addNumber(fairCorrectness); + fairCompletenessStat.addNumber(fairCompleteness); + fairFmeasureStat.addNumber(fairFMeasureCurrFold); + + + //================================================== + //FORTIFICATION + //================================================== + FortificationUtils.FortificationResult[] multiStepFortificationResult = new FortificationUtils.FortificationResult[noOfStrategies]; + + + //--------------------------------- + // Fortification - ALL CPDEF + // (BLIND Fortification) + //--------------------------------- + //NOTE: + //Since this will iterate all cpdef, we will calculate score for all other fortification strategies + // training coverage (done), jaccard, fortification training, + + outputWriter("---------------------------------------------------------------"); + outputWriter("BLIND fortification - All counter partial defintions are used"); + outputWriter("---------------------------------------------------------------"); + //outputWriter("List of counter partial defintions i"); + + //get the set of pos and neg (in the test set) covered by counter partial definition + Set cpdefPositiveCovered = new HashSet<>(); + Set cpdefNegativeCovered = new HashSet<>(); + + long totalCPDefLength = 0; + + //--------------------------------------------------- + //variables for fortification training + //--------------------------------------------------- + + //fortification validation (FV) dataset + Set fortificationTrainingPos = fortificationSetsPos.get(currFold); + Set fortificationTrainingNeg= fortificationSetsNeg.get(currFold); + + //both positive and negative FV + Set allFortificationExamples = new HashSet<>(); + + allFortificationExamples.addAll(fortificationTrainingPos); + allFortificationExamples.addAll(fortificationTrainingNeg); //duplicate will be remove automatically + + + //New Jaccard Similarity + JaccardSimilarity newJaccardSimilarity = new JaccardSimilarity(pelletReasoner); + + //------------------------------------------------------------ + //start the BLIND fortification and + // calculate the scores for other methods (use a common loop) + //------------------------------------------------------------ + int tmp_id = 1; //assign id for each cpdef + int count = 1; //used to count the number of cpdef + for (CELOEPartial.PartialDefinition cpdef : counterPartialDefinitions) { + + //assign id for cpdef for debugging purpose + cpdef.setId("#" + tmp_id++); + + + + //-------------------- + //BLIND Fortification + //-------------------- + //get set of covered pos. and neg. examples in test set + Set cpdefCp = rs.hasType(cpdef.getDescription(), curFoldPosTestSet); + Set cpdefCn = rs.hasType(cpdef.getDescription(), curFoldNegTestSet); + + + //-------------------------------- + //Fortification Validation (FV) + //-------------------------------- + Set fortCp = rs.hasType(cpdef.getDescription(), fortificationTrainingPos); + Set fortCn = rs.hasType(cpdef.getDescription(), fortificationTrainingNeg); + + + Set conceptCp = rs.hasType(concept, fortificationTrainingPos); + Set conceptCn = rs.hasType(concept, fortificationTrainingNeg); + + int cp = fortCp.size(); + int cn = fortCn.size(); + + //these are used to compute common instances between cpdef and learnt concept + fortCp.removeAll(conceptCp); + fortCn.removeAll(conceptCn); + + double fortificationValidationScore = FortificationUtils.fortificationScore(pelletReasoner, cpdef.getDescription(), concept, + cp, cn, fortificationTrainingPos.size(), fortificationTrainingNeg.size(), + cp-fortCp.size(), cn-fortCn.size(), ((CELOEPartial)la).getMaximumHorizontalExpansion()); + + + //---------------------------- + //Overlap + Similarity Score + //---------------------------- + double overlapNeg = FortificationUtils.getConceptOverlapSimple(fortCn, conceptCn); + double overlapPos = FortificationUtils.getConceptOverlapSimple(fortCp, conceptCp); + + //--------------- + //NEW- JACCARD + //--------------- + double newJaccardSimilarityScore = 0; + try { + newJaccardSimilarityScore = newJaccardSimilarity.getJaccardSimilarityComplex(concept, cpdef.getDescription()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + double conceptOverlapSimilairtyScore = overlapNeg + newJaccardSimilarityScore; + + double similarityPosNegScore = overlapNeg - 0.5 * overlapPos; + + + //--------------------------- + //TRAINING COVERAGE Score + //--------------------------- + double trainingCoverageScore = cpdefCn.size()/(double)curFoldNegTrainingSet.size(); + + + //---------------------------------- + //Assign all scores to the CPDEF + //new scoring: 21/4/2013 + //---------------------------------- + double allScores = conceptOverlapSimilairtyScore + fortificationValidationScore + + trainingCoverageScore*0.5; + + double randomScore = new Random().nextDouble(); + + cpdef.setAdditionValue(0, trainingCoverageScore); //no of neg. examples in training set covered by the cpdef + cpdef.setAdditionValue(1, conceptOverlapSimilairtyScore); //can be used to infer jaccard overlap score + cpdef.setAdditionValue(2, fortificationValidationScore); //fortification validation strategy + cpdef.setAdditionValue(3, similarityPosNegScore); + cpdef.setAdditionValue(4, newJaccardSimilarityScore); + cpdef.setAdditionValue(5, allScores); + cpdef.setAdditionValue(6, randomScore); + + + //-------------------------------- + //BLIND fortification process + //-------------------------------- + boolean cpChanged = cpdefPositiveCovered.addAll(cpdefCp); + boolean cnChanged = cpdefNegativeCovered.addAll(cpdefCn); + + + totalCPDefLength += OWLClassExpressionUtils.getLength(cpdef.getDescription()); + + //print the cpdef which covers some pos. examples + //if (cpdefCp.size() > 0) + String changed = ""; + if (cpChanged || cnChanged) { + changed = "(" + (cpChanged?"-":"") + (cnChanged?"+":"") + ")"; + + outputWriter(count++ + changed + ". " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + } + else if (logger.isDebugEnabled()) { + logger.debug(count++ + changed + ". " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + } + + avgCPDefLengthStat.addNumber(OWLClassExpressionUtils.getLength(cpdef.getDescription())); + + } //end of BLIND fortification (loop through all cpdef) + + + outputWriter( " * Blind fortifcation summary: cp=" + cpdefPositiveCovered + " --- cn=" + cpdefNegativeCovered); + + outputWriter("test set errors pos (" + upTest.size() + "): " + upTest); + outputWriter("test set errors neg (" + cnTest.size() + "): " + cnTest); + + //----------------------------------------- + //calculate BLIND fortification accuracy + //----------------------------------------- + + //fortify definition length: total length of all cpdef + totalCPDefLengthStat.addNumber(totalCPDefLength); + double avgCPDefLength = totalCPDefLength/(double)counterPartialDefinitions.size(); + + + //accuracy, completeness, correctness + int oldSizePosFort = cpdefPositiveCovered.size(); + int oldSizeNegFort = cpdefNegativeCovered.size(); + + cpdefPositiveCovered.removeAll(cpTest); + cpdefNegativeCovered.removeAll(cnTest); + + int commonPos = oldSizePosFort - cpdefPositiveCovered.size(); + int commonNeg = oldSizeNegFort - cpdefNegativeCovered.size(); + + + int cpFort = cpTest.size() - commonPos; //positive examples covered by fortified definition + int cnFort = cnTest.size() - commonNeg; //negative examples covered by fortified definition + + //correctness = un/negSize + double blindFortificationCorrectness = 100 * (curFoldNegTestSet.size() - cnFort)/(double)(curFoldNegTestSet.size()); + + //completeness = cp/posSize + double blindFortificationCompleteness = 100 * (cpFort)/(double)curFoldPosTestSet.size(); + + //accuracy = (cp + un)/(pos + neg) + double blindFortificationAccuracy = 100 * (cpFort + (curFoldNegTestSet.size() - cnFort))/ + (double)(curFoldPosTestSet.size() + curFoldNegTestSet.size()); + + //precision = right positive classified / total positive classified + // = cp / (cp + negAsPos) + double blindPrecission = (cpFort + cnFort) == 0 ? 0 : cpFort / (double)(cpFort + cnFort); + + //recall = right positive classified / total positive + double blindRecall = cpFort / (double)curFoldPosTestSet.size(); + + double blindFmeasure = 100 * Heuristics.getFScore(blindRecall, blindPrecission); + + //STAT values for Blind fortification + correctnessBlindFortifyStat.addNumber(blindFortificationCorrectness); + completenessBlindFortifyStat.addNumber(blindFortificationCompleteness); + accuracyBlindFortifyStat.addNumber(blindFortificationAccuracy); + fmeasureBlindFortifyStat.addNumber(blindFmeasure); + + //------------------------------- + //end of BLIND fortification + //------------------------------- + + + //======================================================== + // process other fortification strategies (except BLIND) + //======================================================== + + int INDEX; + + //--------------------------------------- + /// 1. Fortification - TRAINGING COVERAGE + //--------------------------------------- + outputWriter("---------------------------------------------"); + outputWriter("Fortification - TRAINGING COVERAGE"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.TRAINING_COVERAGE_INDEX; + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, counterPartialDefinitions, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 2. Fortification - CONCEPT SIMILARITY & OVERLAP + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - CONCEPT SIMILARITY & OVERLAP"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.CONCEPT_OVERL_SIM_INDEX; + + SortedSet similarityAndOverlapCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(1)); + similarityAndOverlapCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, similarityAndOverlapCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 3. Fortification - FORTIFICATION VALIDATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - FORTIFICATION VALIDATION"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.FORTIFICATION_VALIDATION_INDEX; + + SortedSet fortificationValidationCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(2)); + fortificationValidationCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, fortificationValidationCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 4. Fortification - SIMILARITY NEG-POS + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - SIMILARITY NEG-POS"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.SIMILARITY_POS_NEG_INDEX; + + SortedSet similarityNegPosCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(3)); + similarityNegPosCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, similarityNegPosCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 5. Fortification - JACCARD OVERLAP + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - JACCARD OVERLAP"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.NEW_JACCARD_OVERLAP_INDEX; + + SortedSet jaccardOverlapCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(4)); + jaccardOverlapCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, jaccardOverlapCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 6. Fortification - JACCARD DISTANCE + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - JACCARD DISTANCE"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.NEW_JACCARD_DISTANCE_INDEX; + + SortedSet jaccardDistanceCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(4, false)); + jaccardDistanceCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, jaccardDistanceCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + + //------------------------------------------------ + /// 7. Fortification - COMBINATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - COMBINATION SCORES"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.CONBINATION_INDEX; + + SortedSet combinationScoreCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(5)); + combinationScoreCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, combinationScoreCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + + //------------------------------------------------ + /// 7. Fortification - COMBINATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - RANDOM"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.RANDOM_INDEX; + + SortedSet randomCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(6)); + randomCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, randomCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------ + // Fortification with + // LABLED TEST DATA + //------------------------------ + //if there exists covered negative examples ==> check if there are any counter partial definitions + //can be used to remove covered negative examples + + int fixedNeg = 0; + int fixedPos = 0; + int selectedCpdef = 0; + int totalSelectedCpdefLength = 0; + double avgTrainingCoverage = 0; + + /** + * selected cpdef which are selected based on the test labled data + * given a set of wrong classified neg., select a set of cpdef to remove the wrong classified neg examples + * the cpdef are sorted based on the training neg. example coverage + */ + TreeSet selectedCounterPartialDefinitions = new TreeSet(new FortificationUtils.CoverageComparator()); + + if (cnTest.size() > 0) { + + TreeSet tempCoveredNeg = new TreeSet<>(); + tempCoveredNeg.addAll(cnTest); + + TreeSet tempUncoveredPos = new TreeSet<>(); + tempUncoveredPos.addAll(upTest); + + //check each counter partial definitions + for (CELOEPartial.PartialDefinition cpdef : counterPartialDefinitions) { + + //set of neg examples covered by the counter partial definition + Set desCoveredNeg = new HashSet<>(rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + + //if the current counter partial definition can help to remove some neg examples + //int oldNoOfCoveredNeg=tempCoveredNeg.size(); + if (tempCoveredNeg.removeAll(desCoveredNeg)) { + + //assign cn on test set to additionalValue + selectedCounterPartialDefinitions.add(cpdef); + + //check if it may remove some positive examples or not + Set desCoveredPos = new HashSet<>(rs.hasType(cpdef.getDescription(), curFoldPosTestSet)); + tempUncoveredPos.addAll(desCoveredPos); + + //count the total number of counter partial definition selected and their total length + selectedCpdef++; + totalSelectedCpdefLength += OWLClassExpressionUtils.getLength(cpdef.getDescription()); + avgTrainingCoverage += cpdef.getCoverage(); + } + + if (tempCoveredNeg.size() == 0) + break; + } + + fixedNeg = cnTest.size() - tempCoveredNeg.size(); + fixedPos = tempUncoveredPos.size() - upTest.size(); + avgTrainingCoverage /= selectedCpdef; + } //labelled fortification + + + noOfLabelFortifyDefinitions.addNumber(selectedCpdef); + avgLabelFortifyCpdefCoverage.addNumber(avgTrainingCoverage); + + + //----------------------------- + // Labeled fortification + // stat calculation + //----------------------------- + //def length + double labelFortifiedDefinitionLength = OWLClassExpressionUtils.getLength(concept) + totalSelectedCpdefLength + selectedCpdef; //-1 from the selected cpdef and +1 for NOT + lableFortifyDefinitionLengthStat.addNumber(labelFortifiedDefinitionLength); + + double avgLabelFortifyDefinitionLength = 0; + + if (selectedCpdef > 0) { + avgLabelFortifyDefinitionLength = (double)totalSelectedCpdefLength/selectedCpdef; + avgLabelCpdefLengthStat.addNumber(totalSelectedCpdefLength/(double)selectedCpdef); + } + + //accuracy + double fortifiedAccuracy = 100 * ((double)(correctTestExamples + fixedNeg - fixedPos)/ + (curFoldPosTestSet.size() + curFoldNegTestSet.size())); + accuracyLabelFortifyStat.addNumber(fortifiedAccuracy); + + //completeness + double fortifiedCompleteness = 100 * ((double)(correctTestPosClassified - fixedPos)/curFoldPosTestSet.size()); + completenessLabelFortifyStat.addNumber(fortifiedCompleteness); + + //correctness + double fortifiedCorrectness = 100 * ((double)(correctTestNegClassified + fixedNeg)/curFoldNegTestSet.size()); + correctnessLabelFortifyStat.addNumber(fortifiedCorrectness); + + //precision, recall, f-measure + double labelFortifiedPrecision = 0.0; //percent of correct pos examples in total pos examples classified (= correct pos classified + neg as pos) + if (((correctTestPosClassified - fixedPos) + (cnTest.size() - fixedNeg)) > 0) + labelFortifiedPrecision = (double)(correctTestPosClassified - fixedPos)/ + (correctTestPosClassified - fixedPos + cnTest.size() - fixedNeg); //tmp3: neg as pos <=> false pos + + double labelFortifiedRecall = (double)(correctTestPosClassified - fixedPos) / curFoldPosTestSet.size(); + + double labelFortifiedFmeasure = 100 * Heuristics.getFScore(labelFortifiedRecall, labelFortifiedPrecision); + fmeasureLabelFortifyStat.addNumber(labelFortifiedFmeasure); + + + + outputWriter("---------------------------------------------"); + outputWriter("LABEL fortify counter partial definitions: "); + outputWriter("---------------------------------------------"); + count = 1; + //output the selected counter partial definition information + if (selectedCpdef > 0) { + for (CELOEPartial.PartialDefinition cpdef : selectedCounterPartialDefinitions) { + + outputWriter(count++ + cpdef.getId() + ". " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + + } + } //end of labelled fortification STAT + + + outputWriter("----------------------"); + + + int[] noOfCpdefMultiStep = FortificationUtils.getMultiStepFortificationStep(counterPartialDefinitions.size()); + + for (int i=0; i<6; i++) { + noOfCpdefUsedMultiStepFortStat[i].addNumber(noOfCpdefMultiStep[i]); + + //minimal value of 50% of the cpdef used in the fortification + //NOTE: no of cpdef descreases after added into other sets for fortification + // Cause has not been investigated + minOfHalfCpdef = (minOfHalfCpdef > noOfCpdefMultiStep[i])? noOfCpdefMultiStep[i] : minOfHalfCpdef; + + //minimal number of counter partial definitions till the current run + //the above problem happens for this case as well + minCpdef = (minCpdef > multiStepFortificationResult[i].fortificationAccuracyStepByStep.length)? + multiStepFortificationResult[i].fortificationAccuracyStepByStep.length : minCpdef; + } + + + + + //create data structure to hold the fortification result + if (currFold == 0) { //have not initiallised + accuracyHalfFullStep = new double[noOfStrategies][minOfHalfCpdef]; //4 strategies + fmeasureHalfFullStep = new double[noOfStrategies][minOfHalfCpdef]; + + accuracyFullStepStat = new Stat[noOfStrategies][minCpdef]; + fmeasureFullStepStat = new Stat[noOfStrategies][minCpdef]; + correctnessFullStepStat = new Stat[noOfStrategies][minCpdef]; + completenessFullStepStat = new Stat[noOfStrategies][minCpdef]; + + //run a loop to create a set of Stat objects + for (int i=0; i < noOfStrategies; i++) { + for (int j = 0; j < minCpdef; j++) { + accuracyFullStepStat[i][j] = new Stat(); + fmeasureFullStepStat[i][j] = new Stat(); + correctnessFullStepStat[i][j] = new Stat(); + completenessFullStepStat[i][j] = new Stat(); + } + } + } + + + //sum up the accuracy and fmeasure directly, do not use Stat for simplicity + outputWriter("*** Calculate full step accuracy: minCpdef = " + minCpdef); + + outputWriter("\tcounter partial deifnition size=" + + counterPartialDefinitions.size()); + + //calculate accuracy, fmeasure by HALF FULL of the cpdef + for (int i=0; i 0) //this is for a weird side-affect of the floating point such that the getMax return a very small number >0 even if the acutuall value is zero + cutOffPoint = (int)Math.round(Math.ceil(noOfLabelFortifyDefinitions.getMax())); + + outputWriter("\n CUT-OFF point computation: " + cutOffPoint); + + if (cutOffPoint == 0) { + outputWriter("\tNo fortifying definition is used, the accuracy is unchanged"); + outputWriter("\t\taccuracy: " + df.format(accuracy.getMean()) + ", " + df.format(accuracy.getStandardDeviation()) + + "; correctness: " + df.format(testingCorrectnessStat.getMean()) + ", " + df.format(testingCorrectnessStat.getStandardDeviation()) + + "; completeness: " + df.format(testingCompletenessStat.getMean()) + ", " + df.format(testingCompletenessStat.getStandardDeviation())); + + } + else { + cutOffPoint--; + for (int i=0; i < noOfStrategies; i++) { + outputWriter("\t" + FortificationUtils.strategyNames[i] + ":"); + outputWriter("\t accuracy: " + df.format(accuracyFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(accuracyFullStepStat[i][cutOffPoint].getStandardDeviation()) + + "; correctness: " + df.format(correctnessFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(correctnessFullStepStat[i][cutOffPoint].getStandardDeviation()) + + "; completeness: " + df.format(completenessFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(completenessFullStepStat[i][cutOffPoint].getStandardDeviation()) + ); + /* + cutOffAvg[0][i] = accuracyFullStepStat[i][cutOffPoint].getMean(); + cutOffAvg[1][i] = correctnessFullStepStat[i][cutOffPoint].getMean(); + cutOffAvg[2][i] = completenessFullStepStat[i][cutOffPoint].getMean(); + + cutOffDev[0][i] = accuracyFullStepStat[i][cutOffPoint].getStandardDeviation(); + cutOffDev[1][i] = correctnessFullStepStat[i][cutOffPoint].getStandardDeviation(); + cutOffDev[2][i] = completenessFullStepStat[i][cutOffPoint].getStandardDeviation(); + */ + } + } + + outputWriter(""); + + //fortification by PERCENTAGE + for (int i=0; i< noOfStrategies; i++) { + + outputWriter(" multi-step fortified accuracy by " + FortificationUtils.strategyNames[i] + "(cpdef:" + noOfCpdefUsedMultiStepFortStat[i] + "):"); + + outputWriter("\t 5%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][0], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][0], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][0], "%") + ); + outputWriter("\t 10%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][1], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][1], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][1], "%") + ); + outputWriter("\t 20%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][2], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][2], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][2], "%") + ); + outputWriter("\t 30%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][3], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][3], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][3], "%") + ); + outputWriter("\t 40%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][4], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][4], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][4], "%") + ); + outputWriter("\t 50%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][5], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][5], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][5], "%") + ); + + } + + + outputWriter(" no of cpdef used in multi-step fortification:"); + outputWriter("\t5%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[0], "")); + outputWriter("\t10%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[1], "")); + outputWriter("\t20%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[2], "")); + outputWriter("\t30%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[3], "")); + outputWriter("\t40%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[4], "")); + outputWriter("\t50%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[5], "")); + /* + outputWriter("======= Fmeasure full steps (of 50%) ======="); + for (int i=0; i 1) { + // runtime + runtimeAvg.addNumber(runtime.getMean()); + runtimeMax.addNumber(runtime.getMax()); + runtimeMin.addNumber(runtime.getMin()); + runtimeDev.addNumber(runtime.getStandardDeviation()); + + defLenAvg.addNumber(length.getMean()); + defLenMax.addNumber(length.getMax()); + defLenMin.addNumber(length.getMin()); + defLenDev.addNumber(length.getStandardDeviation()); + + trainingAccAvg.addNumber(accuracyTraining.getMean()); + trainingAccDev.addNumber(accuracyTraining.getStandardDeviation()); + trainingAccMax.addNumber(accuracyTraining.getMax()); + trainingAccMin.addNumber(accuracyTraining.getMin()); + + trainingCorAvg.addNumber(trainingCorrectnessStat.getMean()); + trainingCorDev.addNumber(trainingCorrectnessStat.getStandardDeviation()); + trainingCorMax.addNumber(trainingCorrectnessStat.getMax()); + trainingCorMin.addNumber(trainingCorrectnessStat.getMin()); + + trainingComAvg.addNumber(trainingCompletenessStat.getMean()); + trainingComDev.addNumber(trainingCompletenessStat.getStandardDeviation()); + trainingComMax.addNumber(trainingCompletenessStat.getMax()); + trainingComMin.addNumber(trainingCompletenessStat.getMin()); + + testingAccAvg.addNumber(accuracy.getMean()); + testingAccMax.addNumber(accuracy.getMax()); + testingAccMin.addNumber(accuracy.getMin()); + testingAccDev.addNumber(accuracy.getStandardDeviation()); + + testingCorAvg.addNumber(testingCorrectnessStat.getMean()); + testingCorDev.addNumber(testingCorrectnessStat.getStandardDeviation()); + testingCorMax.addNumber(testingCorrectnessStat.getMax()); + testingCorMin.addNumber(testingCorrectnessStat.getMin()); + + testingComAvg.addNumber(testingCompletenessStat.getMean()); + testingComDev.addNumber(testingCompletenessStat.getStandardDeviation()); + testingComMax.addNumber(testingCompletenessStat.getMax()); + testingComMin.addNumber(testingCompletenessStat.getMin()); + + testingFMesureAvg.addNumber(fMeasure.getMean()); + testingFMesureDev.addNumber(fMeasure.getStandardDeviation()); + testingFMesureMax.addNumber(fMeasure.getMax()); + testingFMesureMin.addNumber(fMeasure.getMin()); + + trainingFMesureAvg.addNumber(fMeasureTraining.getMean()); + trainingFMesureDev.addNumber(fMeasureTraining.getStandardDeviation()); + trainingFMesureMax.addNumber(fMeasureTraining.getMax()); + trainingFMesureMin.addNumber(fMeasureTraining.getMin()); + + noOfDescriptionsAgv.addNumber(totalNumberOfDescriptions.getMean()); + noOfDescriptionsMax.addNumber(totalNumberOfDescriptions.getMax()); + noOfDescriptionsMin.addNumber(totalNumberOfDescriptions.getMin()); + noOfDescriptionsDev.addNumber(totalNumberOfDescriptions.getStandardDeviation()); + } + } // for kk folds + + + if (noOfRuns > 1) { + outputWriter(""); + outputWriter("Finished " + noOfRuns + " time(s) of the " + folds + "-folds cross-validations"); + + outputWriter("runtime: " + + "\n\t avg.: " + statOutput(df, runtimeAvg, "s") + + "\n\t dev.: " + statOutput(df, runtimeDev, "s") + + "\n\t max.: " + statOutput(df, runtimeMax, "s") + + "\n\t min.: " + statOutput(df, runtimeMin, "s")); + + + outputWriter("no of descriptions: " + + "\n\t avg.: " + statOutput(df, noOfDescriptionsAgv, "") + + "\n\t dev.: " + statOutput(df, noOfDescriptionsDev, "") + + "\n\t max.: " + statOutput(df, noOfDescriptionsMax, "") + + "\n\t min.: " + statOutput(df, noOfDescriptionsMin, "")); + + outputWriter("definition length: " + + "\n\t avg.: " + statOutput(df, defLenAvg, "") + + "\n\t dev.: " + statOutput(df, defLenDev, "") + + "\n\t max.: " + statOutput(df, defLenMax, "") + + "\n\t min.: " + statOutput(df, defLenMin, "")); + + outputWriter("accuracy on training set:" + + "\n\t avg.: " + statOutput(df, trainingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingAccDev, "%") + + "\n\t max.: " + statOutput(df, trainingAccMax, "%") + + "\n\t min.: " + statOutput(df, trainingAccMin, "%")); + + outputWriter("correctness on training set: " + + "\n\t avg.: " + statOutput(df, trainingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingCorDev, "%") + + "\n\t max.: " + statOutput(df, trainingCorMax, "%") + + "\n\t min.: " + statOutput(df, trainingCorMin, "%")); + + outputWriter("completeness on training set: " + + "\n\t avg.: " + statOutput(df, trainingComAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingComDev, "%") + + "\n\t max.: " + statOutput(df, trainingComMax, "%") + + "\n\t min.: " + statOutput(df, trainingComMin, "%")); + + outputWriter("FMesure on training set: " + + "\n\t avg.: " + statOutput(df, trainingFMesureAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingFMesureDev, "%") + + "\n\t max.: " + statOutput(df, trainingFMesureMax, "%") + + "\n\t min.: " + statOutput(df, trainingFMesureMin, "%")); + + outputWriter("accuracy on testing set: " + + "\n\t avg.: " + statOutput(df, testingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, testingAccDev, "%") + + "\n\t max.: " + statOutput(df, testingAccMax, "%") + + "\n\t min.: " + statOutput(df, testingAccMin, "%")); + + outputWriter("correctness on testing set: " + + "\n\t avg.: " + statOutput(df, testingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, testingCorDev, "%") + + "\n\t max.: " + statOutput(df, testingCorMax, "%") + + "\n\t min.: " + statOutput(df, testingCorMin, "%")); + + outputWriter("completeness on testing set: " + + "\n\t avg.: " + statOutput(df, testingComAvg, "%") + + "\n\t dev.: " + statOutput(df, testingComDev, "%") + + "\n\t max.: " + statOutput(df, testingComMax, "%") + + "\n\t min.: " + statOutput(df, testingComMin, "%")); + + outputWriter("FMesure on testing set: " + + "\n\t avg.: " + statOutput(df, testingFMesureAvg, "%") + + "\n\t dev.: " + statOutput(df, testingFMesureDev, "%") + + "\n\t max.: " + statOutput(df, testingFMesureMax, "%") + + "\n\t min.: " + statOutput(df, testingFMesureMin, "%")); + } + + } //no of runs + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/CLI.java b/interfaces/src/main/java/org/dllearner/cli/parcel/CLI.java new file mode 100644 index 0000000000..507205ef9d --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/CLI.java @@ -0,0 +1,400 @@ +package org.dllearner.cli.parcel; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; + +import org.dllearner.algorithms.celoe.OEHeuristicRuntime; +import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELDefaultHeuristic; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.dllearner.algorithms.parcelex.ParCELExAbstract; +import org.dllearner.cli.CrossValidation; +import org.dllearner.configuration.IConfiguration; +import org.dllearner.configuration.spring.ApplicationContextBuilder; +import org.dllearner.configuration.spring.DefaultApplicationContextBuilder; +import org.dllearner.confparser.ConfParserConfiguration; +import org.dllearner.confparser.ParseException; +import org.dllearner.core.*; +import org.dllearner.core.config.ConfigOption; +import org.dllearner.learningproblems.PosNegLP; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; + + +/** + * + * Command line interface for learning algorithms. + * Adopted from DLLearner CLI with extensions for supporting more learning options + fortification + * + * @author An C. Tran + * + */ +public class CLI { + + private static Logger logger = LoggerFactory.getLogger(CLI.class); + + private ApplicationContext context; + private IConfiguration configuration; + private File confFile; + + private LearningAlgorithm algorithm; + private KnowledgeSource knowledgeSource; + + // some CLI options + private boolean writeSpringConfiguration = false; + private boolean performCrossValidation = false; + + + @ConfigOption(defaultValue="10", description="Number of validation folds") + private int nrOfFolds = 10; //default 10 folds (for cross validation), it can be changed using configuration option + + @ConfigOption(defaultValue="1", description="Number of runs for k-fold cross validation") + private int noOfRuns = 1; //how many "runs" of k-fold cross validation + + + @ConfigOption(defaultValue="false", description="Use this to evaluate the fortification") + private boolean fortification = false; + + @ConfigOption(defaultValue="0", description="Use this to indicate timeout of learning fortification definition. Default is no timeout") + private int fortificationTimeout = 0; + + @ConfigOption(defaultValue="false", description="Use this learning double timeout for non-fortification strategy.") + private boolean fairComparison = false; + + @ConfigOption(defaultValue="98%", description="Indicate minimal coverage for fortification definitions") + private double fortificationNoise = 98; + + @ConfigOption(defaultValue="-1", description="Stop when the ist definition found. This is mainly for fortification, otherwise, set it in CELOE component (-1: unset, 1: yes, 0: no)") + private int stopOnFirstDefinition = -1; + + + @ConfigOption(defaultValue="null", description="Use this indicate the reducer (used for ParCEL and ParCELEx only)") + private Set reducers = null; + + + public CLI() { + + } + + public CLI(File confFile) { + this(); + this.confFile = confFile; + } + + // separate init methods, because some scripts may want to just get the application + // context from a conf file without actually running it + public void init() throws IOException { + + if(context == null) { + Resource confFileR = new FileSystemResource(confFile); + List springConfigResources = new ArrayList(); + configuration = new ConfParserConfiguration(confFileR); + + ApplicationContextBuilder builder = new DefaultApplicationContextBuilder(); + context = builder.buildApplicationContext(configuration, springConfigResources); + } + } + + + public void run() throws IOException { + //cross validation + if (performCrossValidation) { + AbstractReasonerComponent rs = context.getBean(AbstractReasonerComponent.class); + AbstractCELA la = context.getBean(AbstractCELA.class); + + //--------------------------- + //ParCEL, ParCELEx + //--------------------------- + //this test is added for ParCEL/Ex algorithm since it does not use the PosNegLP + //use "check and fail" strategy (better strategies? ==> use instance check) + try { + ParCELPosNegLP lp = context.getBean(ParCELPosNegLP.class); + + ParCELDefaultHeuristic h = new ParCELDefaultHeuristic(); + + logger.info("\\\\-----------------------------------\n\\\\" + nrOfFolds + " folds " + + "\n\\\\ timeout: " + ((ParCELAbstract)la).getMaxExecutionTimeInSeconds() + + "\n\\\\ heuristic: length penalty=" + h.getExpansionPenaltyFactor() + + ", accGainBonus=" + h.getGainBonusFactor() + + ", accAward=" + h.getAccuracyAwardFactor() + + "\n\\\\-----------------------------------"); + + + //------------------------------------------------------ + //with FORTIFICATION + // no multiple reducers supported with FORTIFICATION + //------------------------------------------------------ + if (this.fortification) { + logger.info("Cross validation with FORTIFICATION"); + + if (la instanceof ParCELExAbstract) + new ParCELExFortifiedCrossValidation3Phases(la, lp, rs, nrOfFolds, false, noOfRuns); + else + new ParCELFortifiedCrossValidation3PhasesFair(la, lp, rs, nrOfFolds, + false, noOfRuns, fortificationTimeout, fairComparison); + } + + //--------------------------- + //no FORTIFICATION + //--------------------------- + else { //without fortification, the cross-validation is similar between ParCEL and ParCEL-Ex + + logger.info("Cross validation WITHOUT FORTIFICATION"); + + //check multiple reducers options + if (this.reducers == null) + new ParCELCrossValidation(la, lp, rs, nrOfFolds, false, noOfRuns); + else { + String reducersStr = ""; + for (ParCELReducer r : reducers) + reducersStr += r.getClass().getSimpleName() + "; "; + logger.info("* Multiple reducers: " + reducersStr); + new ParCELValidationMultiReducers(la, lp, rs, nrOfFolds, false, noOfRuns, reducers); + } + } + //int noOfFolds[] = {10}; //{4, 5, 8, 10}; + //for (int f=0; f < noOfFolds.length; f++) { + //new ParCELFortifiedCrossValidationOrtho2Blind(la, lp, rs, noOfFolds[f], false, noOfRuns); + //new ParCELFortifiedCrossValidation2Phases(la, lp, rs, noOfFolds[f], false, noOfRuns); + //new ParCELExFortifiedCrossValidation3Phases(la, lp, rs, nrOfFolds, false, noOfRuns); + //new ParCELCrossValidation(la, lp, rs, nrOfFolds, false, noOfRuns); + //} + //else + //new ParCELCrossValidation(la, lp, rs, nrOfFolds, false, noOfRuns); + //new ParCELValidationModelAnalysis(la, lp, rs, nrOfFolds, false, noOfRuns); + //new ParCELFortifiedCrossValidation(la, lp, rs, nrOfFolds, false, noOfRuns); + //new ParCELValidationMultiReducers(la, lp, rs, nrOfFolds, false, noOfRuns, reducers); + } + catch (BeansException be) { + PosNegLP lp = context.getBean(PosNegLP.class); + + //int noOfFolds[] = {4, 5, 8, 10}; + //int noOfFolds[] = {10}; + //for (int f=0; f < noOfFolds.length; f++) { + OEHeuristicRuntime h = new OEHeuristicRuntime(); + + logger.info("\\\\-----------------------------------\n\\\\" + nrOfFolds + " folds " + + "\n\\\\ timeout: " + ((org.dllearner.algorithms.celoe.CELOE)la).getMaxExecutionTimeInSeconds() + + "\n\\\\ heuristic: expansionPenalty=" + h.getExpansionPenaltyFactor() + + ", accGainBonus=" + h.getGainBonusFactor() + + ", refinementPenalty=" + h.getNodeRefinementPenalty() + + "\n\\\\-----------------------------------"); + //new CELOEFortifiedCrossValidationBlind(la, lp, rs, noOfFolds[f], false, noOfRuns); + + + + if (this.fortification) { + logger.info("Cross validation with FORTIFICATION"); + new CELOEFortifiedCrossValidation3PhasesFair(la, lp, rs, nrOfFolds, false, noOfRuns, + fortificationNoise, fortificationTimeout, fairComparison, stopOnFirstDefinition); + } + else { + logger.info("Cross validation with NO FORTIFICATION"); + new CrossValidation(la, lp, rs, nrOfFolds, false); // TODO nrOfRuns not available in CV + } + } + + + + //no cross validation + } else { + + for(Entry entry : context.getBeansOfType(LearningAlgorithm.class).entrySet()){ + algorithm = entry.getValue(); + logger.info("Running algorithm instance \"" + entry.getKey() + "\" (" + algorithm.getClass().getSimpleName() + ")"); + algorithm.start(); + } + + } + + } + + public boolean isWriteSpringConfiguration() { + return writeSpringConfiguration; + } + + public void setWriteSpringConfiguration(boolean writeSpringConfiguration) { + this.writeSpringConfiguration = writeSpringConfiguration; + } + + /** + * @param args + * @throws ParseException + * @throws IOException + * @throws ReasoningMethodUnsupportedException + */ + public static void main(String[] args) throws ParseException, IOException, ReasoningMethodUnsupportedException { + + System.out.println("DL-Learner (ParCEL) command line interface"); + + // currently, CLI has exactly one parameter - the conf file + if(args.length == 0) { + System.out.println("You need to give a conf file as argument."); + System.exit(0); + } + + // read file and print and print a message if it does not exist + File file = new File(args[args.length - 1]); + if(!file.exists()) { + System.out.println("File \"" + file + "\" does not exist."); + System.exit(0); + } + + logger.info("Learning config file: " + file.getName()); + + Resource confFile = new FileSystemResource(file); + + List springConfigResources = new ArrayList(); + + try { + //DL-Learner Configuration Object + IConfiguration configuration = new ConfParserConfiguration(confFile); + + + //parsing learning configuration (application context) + ApplicationContextBuilder builder = new DefaultApplicationContextBuilder(); + ApplicationContext context = builder.buildApplicationContext(configuration,springConfigResources); + + //get CLI from the configuration + CLI cli; + if(context.containsBean("cli")) { + cli = (CLI) context.getBean("cli"); + } else { + cli = new CLI(); + } + + cli.setContext(context); + cli.setConfFile(file); + cli.run(); + + } catch (Exception e) { + String stacktraceFileName = "log/error.log"; + + // Get the Root Error Message + logger.error("An Error Has Occurred During Processing."); + logger.error(e.getMessage()); + logger.debug("Stack Trace: ", e); + logger.error("Terminating DL-Learner...and writing stacktrace to: " + stacktraceFileName); + FileOutputStream fos = new FileOutputStream(stacktraceFileName); + PrintStream ps = new PrintStream(fos); + e.printStackTrace(ps); + + } + + } + + + + public void setContext(ApplicationContext context) { + this.context = context; + } + + public ApplicationContext getContext() { + return context; + } + + public File getConfFile() { + return confFile; + } + + public void setConfFile(File confFile) { + this.confFile = confFile; + } + + public boolean isPerformCrossValidation() { + return performCrossValidation; + } + + public void setPerformCrossValidation(boolean performCrossValiation) { + this.performCrossValidation = performCrossValiation; + } + + public int getNrOfFolds() { + return nrOfFolds; + } + + public void setNrOfFolds(int nrOfFolds) { + this.nrOfFolds = nrOfFolds; + } + + public LearningAlgorithm getLearningAlgorithm() { + return algorithm; + } + + public KnowledgeSource getKnowledgeSource() { + return knowledgeSource; + } + + + public int getNoOfRuns() { + return noOfRuns; + } + + public void setNoOfRuns(int noOfRuns) { + this.noOfRuns = noOfRuns; + } + + + public boolean getFortification() { + return this.fortification; + } + + public void setFortification(boolean fort) { + this.fortification = fort; + } + + + public Set getReducers() { + return reducers; + } + + public void setReducers(Set reducers) { + this.reducers = reducers; + } + + public void setFortificationTimeout(int time) { + this.fortificationTimeout = time; + } + + public int getFortificationTimeout() { + return this.fortificationTimeout; + } + + public boolean getFairComparison() { + return this.fairComparison; + } + + public void setFairComparison(boolean fair) { + this.fairComparison = fair; + } + + public double getFortificationNoise() { + return fortificationNoise; + } + + public void setFortificationNoise(double fortificationNoise) { + this.fortificationNoise = fortificationNoise; + } + + public int getStopOnFirstDefinition() { + return stopOnFirstDefinition; + } + + public void setStopOnFirstDefinition(int stopOnFirstDefinition) { + this.stopOnFirstDefinition = stopOnFirstDefinition; + } + + + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELCrossValidation.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELCrossValidation.java new file mode 100644 index 0000000000..93e006cac3 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELCrossValidation.java @@ -0,0 +1,652 @@ +package org.dllearner.cli.parcel; + +import java.text.DecimalFormat; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import com.google.common.collect.Sets; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.algorithms.parcelex.ParCELExAbstract; +import org.dllearner.cli.CrossValidation; +import org.dllearner.core.AbstractCELA; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentInitException; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.utilities.Files; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.dllearner.utilities.statistics.Stat; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Add ParCEL cross validation support to Jens Lehmann work ( + * {@link CrossValidation}). In this cross validation, + * some more addition dimensions will be investigated such as: + * number partial definitions, partial definition length, etc. + * + * + * @author An C. Tran + * + */ + +public class ParCELCrossValidation extends CrossValidation { + + protected Stat learningTime; + protected Stat noOfPartialDef; + protected Stat partialDefinitionLength; + + //protected Stat minimalDescriptionNeeded; + //protected Stat learningtimeForBestDescription; + + Logger logger = Logger.getLogger(this.getClass()); + + protected boolean interupted = false; + + /** + * This is for ParCEL cross validation + * + * @param la + * @param lp + * @param rs + * @param folds + * @param leaveOneOut + * @param noOfRuns Number of k-fold runs, i.e. the validation will run kk times of k-fold validations + */ + public ParCELCrossValidation(AbstractCELA la, ParCELPosNegLP lp, AbstractReasonerComponent rs, + int folds, boolean leaveOneOut, int noOfRuns) { + + super(); // do nothing + + //-------------------------- + //setting up + //-------------------------- + DecimalFormat df = new DecimalFormat(); + + // the training and test sets used later on + List> trainingSetsPos = new LinkedList<>(); + List> trainingSetsNeg = new LinkedList<>(); + List> testSetsPos = new LinkedList<>(); + List> testSetsNeg = new LinkedList<>(); + + // get examples and shuffle them too + Set posExamples = lp.getPositiveExamples(); + List posExamplesList = new LinkedList<>(posExamples); + //Collections.shuffle(posExamplesList, new Random(1)); + Set negExamples = lp.getNegativeExamples(); + List negExamplesList = new LinkedList<>(negExamples); + //Collections.shuffle(negExamplesList, new Random(2)); + + //---------------------- + //end of setting up + //---------------------- + + // sanity check whether nr. of folds makes sense for this benchmark + if(!leaveOneOut && (posExamples.size() testPos = getTestingSet(posExamplesList, splitsPos, i); + Set testNeg = getTestingSet(negExamplesList, splitsNeg, i); + testSetsPos.add(i, testPos); + testSetsNeg.add(i, testNeg); + trainingSetsPos.add(i, getTrainingSet(posExamples, testPos)); + trainingSetsNeg.add(i, getTrainingSet(negExamples, testNeg)); + } + + } + + // run the algorithm + int terminatedBypartialDefinition=0, terminatedByCounterPartialDefinitions=0; + + //--------------------------------- + //k-fold cross validation + //--------------------------------- + Stat learningTimeAvg = new Stat(); + Stat learningTimeMax = new Stat(); + Stat learningTimeMin = new Stat(); + Stat learningTimeDev = new Stat(); + + Stat runtimeAvg = new Stat(); + Stat runtimeMax = new Stat(); + Stat runtimeMin = new Stat(); + Stat runtimeDev = new Stat(); + + Stat noOfPartialDefAvg = new Stat(); + Stat noOfPartialDefDev = new Stat(); + Stat noOfPartialDefMax = new Stat(); + Stat noOfPartialDefMin = new Stat(); + + Stat avgPartialDefLenAvg = new Stat(); + Stat avgPartialDefLenDev = new Stat(); + Stat avgPartialDefLenMax = new Stat(); + Stat avgPartialDefLenMin = new Stat(); + + Stat defLenAvg = new Stat(); + Stat defLenDev = new Stat(); + Stat defLenMax = new Stat(); + Stat defLenMin = new Stat(); + + Stat trainingAccAvg = new Stat(); + Stat trainingAccDev = new Stat(); + Stat trainingAccMax = new Stat(); + Stat trainingAccMin = new Stat(); + + Stat trainingCorAvg = new Stat(); + Stat trainingCorDev = new Stat(); + Stat trainingCorMax = new Stat(); + Stat trainingCorMin = new Stat(); + + Stat trainingComAvg = new Stat(); + Stat trainingComDev = new Stat(); + Stat trainingComMax = new Stat(); + Stat trainingComMin = new Stat(); + + Stat testingAccAvg = new Stat(); + Stat testingAccMax = new Stat(); + Stat testingAccMin = new Stat(); + Stat testingAccDev = new Stat(); + + Stat testingCorAvg = new Stat(); + Stat testingCorMax = new Stat(); + Stat testingCorMin = new Stat(); + Stat testingCorDev = new Stat(); + + Stat testingComAvg = new Stat(); + Stat testingComMax = new Stat(); + Stat testingComMin = new Stat(); + Stat testingComDev = new Stat(); + + Stat testingFMeasureAvg = new Stat(); + Stat testingFMeasureMax = new Stat(); + Stat testingFMeasureMin = new Stat(); + Stat testingFMeasureDev = new Stat(); + + Stat trainingFMeasureAvg = new Stat(); + Stat trainingFMeasureMax = new Stat(); + Stat trainingFMeasureMin = new Stat(); + Stat trainingFMeasureDev = new Stat(); + + Stat noOfDescriptionsAgv = new Stat(); + Stat noOfDescriptionsMax = new Stat(); + Stat noOfDescriptionsMin = new Stat(); + Stat noOfDescriptionsDev = new Stat(); + + for (int kk=0; kk < noOfRuns; kk++) { + + learningTime = new Stat(); + + + //runtime + runtime = new Stat(); + noOfPartialDef = new Stat(); + partialDefinitionLength = new Stat(); + length = new Stat(); + accuracyTraining = new Stat(); + trainingCorrectnessStat= new Stat(); + trainingCompletenessStat = new Stat(); + accuracy = new Stat(); + testingCorrectnessStat = new Stat(); + testingCompletenessStat = new Stat(); + + // statistical values + + fMeasure = new Stat(); + fMeasureTraining = new Stat(); + totalNumberOfDescriptions= new Stat(); + + minimalDescriptionNeeded = new Stat(); + learningTimeForBestDescription = new Stat(); + + for(int currFold=0; (currFold pos = Datastructures.individualSetToStringSet(trainingSetsPos.get(currFold)); + //Set neg = Datastructures.individualSetToStringSet(trainingSetsNeg.get(currFold)); + lp.setPositiveExamples(trainingSetsPos.get(currFold)); + lp.setNegativeExamples(trainingSetsNeg.get(currFold)); + + try { + lp.init(); + la.init(); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + + long algorithmStartTime = System.nanoTime(); + try { + la.start(); + } + catch (OutOfMemoryError e) { + System.out.println("out of memory at " + (System.currentTimeMillis() - algorithmStartTime)/1000 + "s"); + } + + long algorithmDuration = System.nanoTime() - algorithmStartTime; + runtime.addNumber(algorithmDuration/(double)1000000000); + + //learning time, does not include the reduction time + long learningMili = ((ParCELAbstract)la).getLearningTime(); + learningTime.addNumber(learningMili); + + OWLClassExpression concept = ((ParCELAbstract) la).getUnionCurrentlyBestDescription(); + + Set tmp = rs.hasType(concept, trainingSetsPos.get(currFold)); + Set tmp2 = Sets.difference(trainingSetsPos.get(currFold), tmp); + Set tmp3 = rs.hasType(concept, trainingSetsNeg.get(currFold)); + + outputWriter("training set errors pos (" + tmp2.size() + "): " + tmp2); + outputWriter("training set errors neg (" + tmp3.size() + "): " + tmp3); + + + tmp = rs.hasType(concept, testSetsPos.get(currFold)); + tmp2 = Sets.difference(testSetsPos.get(currFold), tmp); + tmp3 = rs.hasType(concept, testSetsNeg.get(currFold)); + + outputWriter("test set errors pos: " + tmp2); + outputWriter("test set errors neg: " + tmp3); + + // calculate training accuracies + int trainingCorrectPosClassified = getCorrectPosClassified(rs, concept, trainingSetsPos.get(currFold)); + int trainingCorrectNegClassified = getCorrectNegClassified(rs, concept, trainingSetsNeg.get(currFold)); + int trainingCorrectExamples = trainingCorrectPosClassified + trainingCorrectNegClassified; + double trainingAccuracy = 100*((double)trainingCorrectExamples/(trainingSetsPos.get(currFold).size()+ + trainingSetsNeg.get(currFold).size())); + + double trainingCompleteness = 100*(double)trainingCorrectPosClassified/trainingSetsPos.get(currFold).size(); + double trainingCorrectness = 100*(double)trainingCorrectNegClassified/trainingSetsNeg.get(currFold).size(); + + accuracyTraining.addNumber(trainingAccuracy); + trainingCompletenessStat.addNumber(trainingCompleteness); + trainingCorrectnessStat.addNumber(trainingCorrectness); + + // calculate test accuracies + int correctPosClassified = getCorrectPosClassified(rs, concept, testSetsPos.get(currFold)); + int correctNegClassified = getCorrectNegClassified(rs, concept, testSetsNeg.get(currFold)); + int correctExamples = correctPosClassified + correctNegClassified; + double currAccuracy = 100*((double)correctExamples/(testSetsPos.get(currFold).size()+ + testSetsNeg.get(currFold).size())); + + double testingCompleteness = 100*(double)correctPosClassified/testSetsPos.get(currFold).size(); + double testingCorrectness = 100*(double)correctNegClassified/testSetsNeg.get(currFold).size(); + + accuracy.addNumber(currAccuracy); + testingCompletenessStat.addNumber(testingCompleteness); + testingCorrectnessStat.addNumber(testingCorrectness); + + + // calculate training F-Score + int negAsPosTraining = rs.hasType(concept, trainingSetsNeg.get(currFold)).size(); + double precisionTraining = trainingCorrectPosClassified + negAsPosTraining == 0 ? 0 : trainingCorrectPosClassified / (double) (trainingCorrectPosClassified + negAsPosTraining); + double recallTraining = trainingCorrectPosClassified / (double) trainingSetsPos.get(currFold).size(); + fMeasureTraining.addNumber(100*Heuristics.getFScore(recallTraining, precisionTraining)); + // calculate test F-Score + int negAsPos = rs.hasType(concept, testSetsNeg.get(currFold)).size(); + double precision = correctPosClassified + negAsPos == 0 ? 0 : correctPosClassified / (double) (correctPosClassified + negAsPos); + double recall = correctPosClassified / (double) testSetsPos.get(currFold).size(); + // System.out.println(precision);System.out.println(recall); + fMeasure.addNumber(100*Heuristics.getFScore(recall, precision)); + + length.addNumber(OWLClassExpressionUtils.getLength(concept)); +// totalNumberOfDescriptions.addNumber(la.getTotalNumberOfDescriptionsGenerated()); // TODO not available yet + + outputWriter("Fold " + currFold + ":"); + outputWriter(" training: " + trainingCorrectPosClassified + "/" + trainingSetsPos.get(currFold).size() + + " positive and " + trainingCorrectNegClassified + "/" + trainingSetsNeg.get(currFold).size() + " negative examples"); + outputWriter(" testing: " + correctPosClassified + "/" + testSetsPos.get(currFold).size() + " correct positives, " + + correctNegClassified + "/" + testSetsNeg.get(currFold).size() + " correct negatives"); + //outputWriter(" concept: " + concept); + outputWriter(" accuracy: " + df.format(currAccuracy) + + "% (corr:"+ df.format(testingCorrectness) + + "%, comp:" + testingCompleteness + "%) --- " + + df.format(trainingAccuracy) + "% (corr:"+ trainingCorrectness + + ", comp:" + trainingCompleteness + "%) on training set)"); + outputWriter(" definition length: " + OWLClassExpressionUtils.getLength(concept)); + outputWriter(" runtime: " + df.format(algorithmDuration/(double)1000000000) + "s"); + outputWriter(" learning time: " + df.format(learningMili/(double)1000) + "s"); +// outputWriter(" total number of descriptions: " + la.getTotalNumberOfDescriptionsGenerated()); // TODO not available yet + + + double minDescriptions = 0; + double minLearningTime = 0; + for (ParCELExtraNode pdef : ((ParCELAbstract)la).getReducedPartialDefinition()) { + if (pdef.getExtraInfo() > minDescriptions) { + minDescriptions = pdef.getExtraInfo(); + minLearningTime = pdef.getGenerationTime(); + } + + } + + //outputWriter(" minimal number of descriptions needed: " + minDescriptions); + minimalDescriptionNeeded.addNumber(minDescriptions); + learningTimeForBestDescription.addNumber(minLearningTime); + + + if (la instanceof ParCELAbstract) { + int pn = ((ParCELAbstract)la).getNoOfReducedPartialDefinition(); + this.noOfPartialDef.addNumber(pn); + outputWriter(" number of partial definitions: " + pn + "/" + ((ParCELAbstract)la).getNumberOfPartialDefinitions()); + + double pl = OWLClassExpressionUtils.getLength(concept)/(double)pn; + this.partialDefinitionLength.addNumber(pl); + outputWriter(" avarage partial definition length: " + pl); + + //show more information on counter partial definitions + + if (la instanceof ParCELExAbstract) { + ParCELExAbstract pdllexla = (ParCELExAbstract)la; + /* + outputWriter(" number of partial definitions for each type: 1:" + pdllexla.getNumberOfPartialDefinitions(1) + + "; 2:" + pdllexla.getNumberOfPartialDefinitions(2) + + "; 3:" + pdllexla.getNumberOfPartialDefinitions(3) + + "; 4:" + pdllexla.getNumberOfPartialDefinitions(4)); + */ + outputWriter(" number of counter partial definition used: " + pdllexla.getNumberOfCounterPartialDefinitionUsed() + "/" + pdllexla.getNumberOfCounterPartialDefinitions()); + + //check how did the learner terminate: by partial definition or counter partial definition + if (pdllexla.terminatedByCounterDefinitions()) { + outputWriter(" terminated by counter partial definitions"); + terminatedByCounterPartialDefinitions++; + } + else if (pdllexla.terminatedByPartialDefinitions()) { + outputWriter(" terminated by partial definitions"); + terminatedBypartialDefinition++; + } + else + outputWriter(" neither terminated by partial definition nor counter partial definition"); + } + } + + outputWriter("----------"); + outputWriter("Aggregate data from fold 0 to fold " + currFold); + outputWriter(" runtime: " + statOutput(df, runtime, "s")); + outputWriter(" no of descriptions: " + statOutput(df, totalNumberOfDescriptions, "")); + outputWriter(" length: " + statOutput(df, length, "")); + outputWriter(" F-Measure on training set: " + statOutput(df, fMeasureTraining, "%")); + outputWriter(" F-Measure: " + statOutput(df, fMeasure, "%")); + outputWriter(" accuracy on training set: " + statOutput(df, accuracyTraining, "%")); + outputWriter(" correctness: " + statOutput(df, trainingCorrectnessStat, "%")); + outputWriter(" completeness: " + statOutput(df, trainingCompletenessStat, "%")); + outputWriter(" predictive accuracy on testing set: " + statOutput(df, accuracy, "%")); + outputWriter(" correctness: " + statOutput(df, testingCorrectnessStat, "%")); + outputWriter(" completeness: " + statOutput(df, testingCompletenessStat, "%")); + //outputWriter(" minimal descriptions needed: " + statOutput(df, minimalDescriptionNeeded, "")); + //outputWriter(" minimal learning time: " + statOutput(df, learningTimeForBestDescription, "")); + outputWriter("----------"); + + + //sleep after each run (fer MBean collecting information purpose) + try { + Thread.sleep(5000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + + } //for k folds + + + //--------------------------------- + //end of k-fold cross validation + //output result of the k-fold + //--------------------------------- + + outputWriter(""); + outputWriter("Finished the " + (kk+1) + "/" + noOfRuns + " of " + folds + "-folds cross-validation."); + outputWriter(" runtime: " + statOutput(df, runtime, "s")); + outputWriter(" learning time: " + statOutput(df, learningTime, "s")); + outputWriter(" no of descriptions: " + statOutput(df, totalNumberOfDescriptions, "")); + outputWriter(" no of partial definitions: " + statOutput(df, noOfPartialDef, "")); + outputWriter(" avg. partial definition length: " + statOutput(df, partialDefinitionLength, "")); + outputWriter(" definition length: " + statOutput(df, length, "")); + outputWriter(" F-Measure on training set: " + statOutput(df, fMeasureTraining, "%")); + outputWriter(" F-Measure: " + statOutput(df, fMeasure, "%")); + outputWriter(" predictive accuracy on training set: " + statOutput(df, accuracyTraining, "%") + + " - corr: " + statOutput(df, trainingCorrectnessStat, "%") + + ", comp: " + statOutput(df, trainingCompletenessStat, "%")); + outputWriter(" predictive accuracy: " + statOutput(df, accuracy, "%") + + " - corr: " + statOutput(df, testingCorrectnessStat, "%") + + ", comp: " + statOutput(df, testingCompletenessStat, "%")); + + //if (la instanceof ParCELExAbstract) + // outputWriter(" terminated by: partial def.: " + terminatedBypartialDefinition + "; counter partial def.: " + terminatedByCounterPartialDefinitions); + + + //output for copying to excel/ + + //runtime + runtimeAvg.addNumber(runtime.getMean()); + runtimeMax.addNumber(runtime.getMax()); + runtimeMin.addNumber(runtime.getMin()); + runtimeDev.addNumber(runtime.getStandardDeviation()); + + //learning time + learningTimeAvg.addNumber(learningTime.getMean()); + learningTimeDev.addNumber(learningTime.getStandardDeviation()); + learningTimeMax.addNumber(learningTime.getMax()); + learningTimeMin.addNumber(learningTime.getMin()); + + //number of partial definitions + noOfPartialDefAvg.addNumber(noOfPartialDef.getMean()); + noOfPartialDefMax.addNumber(noOfPartialDef.getMax()); + noOfPartialDefMin.addNumber(noOfPartialDef.getMin()); + noOfPartialDefDev.addNumber(noOfPartialDef.getStandardDeviation()); + + avgPartialDefLenAvg.addNumber(partialDefinitionLength.getMean()); + avgPartialDefLenMax.addNumber(partialDefinitionLength.getMax()); + avgPartialDefLenMin.addNumber(partialDefinitionLength.getMin()); + avgPartialDefLenDev.addNumber(partialDefinitionLength.getStandardDeviation()); + + defLenAvg.addNumber(length.getMean()); + defLenMax.addNumber(length.getMax()); + defLenMin.addNumber(length.getMin()); + defLenDev.addNumber(length.getStandardDeviation()); + + trainingAccAvg.addNumber(accuracyTraining.getMean()); + trainingAccDev.addNumber(accuracyTraining.getStandardDeviation()); + trainingAccMax.addNumber(accuracyTraining.getMax()); + trainingAccMin.addNumber(accuracyTraining.getMin()); + + trainingCorAvg.addNumber(trainingCorrectnessStat.getMean()); + trainingCorDev.addNumber(trainingCorrectnessStat.getStandardDeviation()); + trainingCorMax.addNumber(trainingCorrectnessStat.getMax()); + trainingCorMin.addNumber(trainingCorrectnessStat.getMin()); + + trainingComAvg.addNumber(trainingCompletenessStat.getMean()); + trainingComDev.addNumber(trainingCompletenessStat.getStandardDeviation()); + trainingComMax.addNumber(trainingCompletenessStat.getMax()); + trainingComMin.addNumber(trainingCompletenessStat.getMin()); + + testingAccAvg.addNumber(accuracy.getMean()); + testingAccMax.addNumber(accuracy.getMax()); + testingAccMin.addNumber(accuracy.getMin()); + testingAccDev.addNumber(accuracy.getStandardDeviation()); + + + testingCorAvg.addNumber(testingCorrectnessStat.getMean()); + testingCorDev.addNumber(testingCorrectnessStat.getStandardDeviation()); + testingCorMax.addNumber(testingCorrectnessStat.getMax()); + testingCorMin.addNumber(testingCorrectnessStat.getMin()); + + testingComAvg.addNumber(testingCompletenessStat.getMean()); + testingComDev.addNumber(testingCompletenessStat.getStandardDeviation()); + testingComMax.addNumber(testingCompletenessStat.getMax()); + testingComMin.addNumber(testingCompletenessStat.getMin()); + + testingFMeasureAvg.addNumber(fMeasure.getMean()); + testingFMeasureDev.addNumber(fMeasure.getStandardDeviation()); + testingFMeasureMax.addNumber(fMeasure.getMax()); + testingFMeasureMin.addNumber(fMeasure.getMin()); + + trainingFMeasureAvg.addNumber(fMeasureTraining.getMean()); + trainingFMeasureDev.addNumber(fMeasureTraining.getStandardDeviation()); + trainingFMeasureMax.addNumber(fMeasureTraining.getMax()); + trainingFMeasureMin.addNumber(fMeasureTraining.getMin()); + + noOfDescriptionsAgv.addNumber(totalNumberOfDescriptions.getMean()); + noOfDescriptionsMax.addNumber(totalNumberOfDescriptions.getMax()); + noOfDescriptionsMin.addNumber(totalNumberOfDescriptions.getMin()); + noOfDescriptionsDev.addNumber(totalNumberOfDescriptions.getStandardDeviation()); + + } //for kk folds + + if (noOfRuns > 1) { + + outputWriter(""); + outputWriter("Finished " + noOfRuns + " time(s) of the " + folds + "-folds cross-validations"); + + outputWriter("runtime: " + + "\n\t avg.: " + statOutput(df, runtimeAvg, "s") + + "\n\t dev.: " + statOutput(df, runtimeDev, "s") + + "\n\t max.: " + statOutput(df, runtimeMax, "s") + + "\n\t min.: " + statOutput(df, runtimeMin, "s")); + + outputWriter("learning time: " + + "\n\t avg.: " + statOutput(df, learningTimeAvg, "s") + + "\n\t dev.: " + statOutput(df, learningTimeDev, "s") + + "\n\t max.: " + statOutput(df, learningTimeMax, "s") + + "\n\t min.: " + statOutput(df, learningTimeMin, "s")); + + outputWriter("no of descriptions: " + + "\n\t avg.: " + statOutput(df, noOfDescriptionsAgv, "") + + "\n\t dev.: " + statOutput(df, noOfDescriptionsDev, "") + + "\n\t max.: " + statOutput(df, noOfDescriptionsMax, "") + + "\n\t min.: " + statOutput(df, noOfDescriptionsMin, "")); + + outputWriter("number of partial definitions: " + + "\n\t avg.: " + statOutput(df, noOfPartialDefAvg, "") + + "\n\t dev.: " + statOutput(df, noOfPartialDefDev, "") + + "\n\t max.: " + statOutput(df, noOfPartialDefMax, "") + + "\n\t min.: " + statOutput(df, noOfPartialDefMin, "")); + + outputWriter("avg. partial definition length: " + + "\n\t avg.: " + statOutput(df, avgPartialDefLenAvg, "") + + "\n\t dev.: " + statOutput(df, avgPartialDefLenDev, "") + + "\n\t max.: " + statOutput(df, avgPartialDefLenMax, "") + + "\n\t min.: " + statOutput(df, avgPartialDefLenMin, "")); + + outputWriter("definition length: " + + "\n\t avg.: " + statOutput(df, defLenAvg, "") + + "\n\t dev.: " + statOutput(df, defLenDev, "") + + "\n\t max.: " + statOutput(df, defLenMax, "") + + "\n\t min.: " + statOutput(df, defLenMin, "")); + + outputWriter("accuracy on training set:" + + "\n\t avg.: " + statOutput(df, trainingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingAccDev, "%") + + "\n\t max.: " + statOutput(df, trainingAccMax, "%") + + "\n\t min.: " + statOutput(df, trainingAccMin, "%")); + + outputWriter("correctness on training set: " + + "\n\t avg.: " + statOutput(df, trainingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingCorDev, "%") + + "\n\t max.: " + statOutput(df, trainingCorMax, "%") + + "\n\t min.: " + statOutput(df, trainingCorMin, "%")); + + outputWriter("completeness on training set: " + + "\n\t avg.: " + statOutput(df, trainingComAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingComDev, "%") + + "\n\t max.: " + statOutput(df, trainingComMax, "%") + + "\n\t min.: " + statOutput(df, trainingComMin, "%")); + + outputWriter("FMeasure on training set: " + + "\n\t avg.: " + statOutput(df, trainingFMeasureAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingFMeasureDev, "%") + + "\n\t max.: " + statOutput(df, trainingFMeasureMax, "%") + + "\n\t min.: " + statOutput(df, trainingFMeasureMin, "%")); + + outputWriter("accuracy on testing set: " + + "\n\t avg.: " + statOutput(df, testingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, testingAccDev, "%") + + "\n\t max.: " + statOutput(df, testingAccMax, "%") + + "\n\t min.: " + statOutput(df, testingAccMin, "%")); + + outputWriter("correctness on testing set: " + + "\n\t avg.: " + statOutput(df, testingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, testingCorDev, "%") + + "\n\t max.: " + statOutput(df, testingCorMax, "%") + + "\n\t min.: " + statOutput(df, testingCorMin, "%")); + + outputWriter("completeness on testing set: " + + "\n\t avg.: " + statOutput(df, testingComAvg, "%") + + "\n\t dev.: " + statOutput(df, testingComDev, "%") + + "\n\t max.: " + statOutput(df, testingComMax, "%") + + "\n\t min.: " + statOutput(df, testingComMin, "%")); + + outputWriter("FMeasure on testing set: " + + "\n\t avg.: " + statOutput(df, testingFMeasureAvg, "%") + + "\n\t dev.: " + statOutput(df, testingFMeasureDev, "%") + + "\n\t max.: " + statOutput(df, testingFMeasureMax, "%") + + "\n\t min.: " + statOutput(df, testingFMeasureMin, "%")); + } + + //if (la instanceof ParCELExAbstract) + // outputWriter("terminated by: partial def.: " + terminatedBypartialDefinition + "; counter partial def.: " + terminatedByCounterPartialDefinitions); + + } + + + /* + private String getOrderUnit(int order) { + switch (order) { + case 1: return "st"; + case 2: return "nd"; + case 3: return "rd"; + default: return "th"; + } + } + */ + + @Override + protected void outputWriter(String output) { + logger.info(output); + + if (writeToFile) + Files.appendToFile(outputFile, output + "\n"); + } + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation.java new file mode 100644 index 0000000000..ff72ccaa33 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation.java @@ -0,0 +1,1184 @@ +package org.dllearner.cli.parcel; + +import java.text.DecimalFormat; +import java.util.*; + +import com.google.common.collect.Sets; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.algorithms.parcelex.ParCELExAbstract; +import org.dllearner.cli.CrossValidation; +import org.dllearner.core.AbstractCELA; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentInitException; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.utilities.Files; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.dllearner.utilities.statistics.Stat; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Add PDLL cross validation support to Jens Lehmann work ( + * {@link CrossValidation}). In this cross validation, + * some more addition dimensions will be investigated such as: + * number partial definitions, partial definition length, etc. + * + * + * @author actran + * + */ + +public class ParCELExFortifiedCrossValidation extends CrossValidation { + + protected Stat noOfPartialDef; + protected Stat avgPartialDefinitionLength; + protected Stat noOfCounterPartialDefinitions; + protected Stat noOfCounterPartialDefinitionsUsed; + protected Stat learningTime; + + //fortify strategy statistical variables + protected Stat accuracyFortify1Stat; + protected Stat accuracyFortify2Stat; + protected Stat correctnessFortify1Stat; + protected Stat correctnessFortify2Stat; + protected Stat completenessFortify2Stat; + protected Stat fmeasureFortify1Stat; + protected Stat fmeasureFortify2Stat; + protected Stat avgFortifiedPartialDefinitionLengthStat; + protected Stat avgFortifyDefinitionsLengthStat; + protected Stat avgFortifyCoverageTrainingStatLevel1; + protected Stat avgFortifyCoverageTestStatLevel1; + protected Stat avgFortifyCoverageTrainingStatLevel2; + protected Stat avgFortifyCoverageTestStatLevel2; + + protected Stat avgNoOfFortifiedDefinitions; + protected Stat avgNoOfFortifiedDefinitionsL1; + protected Stat avgNoOfFortifiedDefinitionsL2; + + Logger logger = Logger.getLogger(this.getClass()); + + protected boolean interupted = false; + + /** + * Default constructor + */ + + public ParCELExFortifiedCrossValidation(AbstractCELA la, PosNegLP lp, AbstractReasonerComponent rs, + int folds, boolean leaveOneOut, int noOfRuns) { + super(la, lp, rs, folds, leaveOneOut); // TODO nrOfRuns not available in CV class + } + + /** + * This is for PDLL cross validation + * + * @param la + * @param lp + * @param rs + * @param folds + * @param leaveOneOut + * @param noOfRuns Number of k-fold runs, i.e. the validation will run kk times of k-fold validations + */ + public ParCELExFortifiedCrossValidation(AbstractCELA la, ParCELPosNegLP lp, AbstractReasonerComponent rs, + int folds, boolean leaveOneOut, int noOfRuns) { + + super(); // do nothing + + //-------------------------- + //setting up + //-------------------------- + DecimalFormat df = new DecimalFormat(); + + // the training and test sets used later on + List> trainingSetsPos = new LinkedList<>(); + List> trainingSetsNeg = new LinkedList<>(); + List> testSetsPos = new LinkedList<>(); + List> testSetsNeg = new LinkedList<>(); + + // get examples and shuffle them too + Set posExamples = lp.getPositiveExamples(); + List posExamplesList = new LinkedList<>(posExamples); + Collections.shuffle(posExamplesList, new Random(1)); + Set negExamples = lp.getNegativeExamples(); + List negExamplesList = new LinkedList<>(negExamples); + Collections.shuffle(negExamplesList, new Random(2)); + + String baseURI = rs.getBaseURI(); + Map prefixes = rs.getPrefixes(); + + //---------------------- + //end of setting up + //---------------------- + + // sanity check whether nr. of folds makes sense for this benchmark + if(!leaveOneOut && (posExamples.size() testPos = getTestingSet(posExamplesList, splitsPos, i); + Set testNeg = getTestingSet(negExamplesList, splitsNeg, i); + testSetsPos.add(i, testPos); + testSetsNeg.add(i, testNeg); + trainingSetsPos.add(i, getTrainingSet(posExamples, testPos)); + trainingSetsNeg.add(i, getTrainingSet(negExamples, testNeg)); + } + + + + // run the algorithm + int terminatedBypartialDefinition=0, terminatedByCounterPartialDefinitions=0; + + //--------------------------------- + //k-fold cross validation + //--------------------------------- + + Stat runtimeAvg = new Stat(); + Stat runtimeMax = new Stat(); + Stat runtimeMin = new Stat(); + Stat runtimeDev = new Stat(); + + Stat learningTimeAvg = new Stat(); + Stat learningTimeMax = new Stat(); + Stat learningTimeMin = new Stat(); + Stat learningTimeDev = new Stat(); + + Stat noOfPartialDefAvg = new Stat(); + Stat noOfPartialDefDev = new Stat(); + Stat noOfPartialDefMax = new Stat(); + Stat noOfPartialDefMin = new Stat(); + + Stat avgPartialDefLenAvg = new Stat(); + Stat avgPartialDefLenDev = new Stat(); + Stat avgPartialDefLenMax = new Stat(); + Stat avgPartialDefLenMin = new Stat(); + + Stat avgFortifiedPartialDefLenAvg = new Stat(); + Stat avgFortifiedPartialDefLenDev = new Stat(); + Stat avgFortifiedPartialDefLenMax = new Stat(); + Stat avgFortifiedPartialDefLenMin = new Stat(); + + Stat defLenAvg = new Stat(); + Stat defLenDev = new Stat(); + Stat defLenMax = new Stat(); + Stat defLenMin = new Stat(); + + Stat trainingAccAvg = new Stat(); + Stat trainingAccDev= new Stat(); + Stat trainingAccMax = new Stat(); + Stat trainingAccMin = new Stat(); + + Stat trainingCorAvg = new Stat(); + Stat trainingCorDev = new Stat(); + Stat trainingCorMax = new Stat(); + Stat trainingCorMin = new Stat(); + + Stat trainingComAvg = new Stat(); + Stat trainingComDev = new Stat(); + Stat trainingComMax = new Stat(); + Stat trainingComMin = new Stat(); + + Stat testingAccAvg = new Stat(); + Stat testingAccMax = new Stat(); + Stat testingAccMin = new Stat(); + Stat testingAccDev = new Stat(); + + Stat fortify1AccAvg = new Stat(); + Stat fortify1AccMax = new Stat(); + Stat fortify1AccMin = new Stat(); + Stat fortify1AccDev = new Stat(); + + Stat fortify2AccAvg = new Stat(); + Stat fortify2AccMax = new Stat(); + Stat fortify2AccMin = new Stat(); + Stat fortify2AccDev = new Stat(); + + + Stat testingCorAvg = new Stat(); + Stat testingCorMax = new Stat(); + Stat testingCorMin = new Stat(); + Stat testingCorDev = new Stat(); + + Stat fortify1CorAvg = new Stat(); + Stat fortify1CorMax = new Stat(); + Stat fortify1CorMin = new Stat(); + Stat fortify1CorDev = new Stat(); + + Stat fortify2CorAvg = new Stat(); + Stat fortify2CorMax = new Stat(); + Stat fortify2CorMin = new Stat(); + Stat fortify2CorDev = new Stat(); + + + Stat testingComAvg = new Stat(); + Stat testingComMax = new Stat(); + Stat testingComMin = new Stat(); + Stat testingComDev = new Stat(); + + + Stat fortify2ComAvg = new Stat(); + Stat fortify2ComMax = new Stat(); + Stat fortify2ComMin = new Stat(); + Stat fortify2ComDev = new Stat(); + + + Stat testingFMeasureAvg = new Stat(); + Stat testingFMeasureMax = new Stat(); + Stat testingFMeasureMin = new Stat(); + Stat testingFMeasureDev = new Stat(); + + Stat trainingFMeasureAvg = new Stat(); + Stat trainingFMeasureMax = new Stat(); + Stat trainingFMeasureMin = new Stat(); + Stat trainingFMeasureDev = new Stat(); + + Stat fortify1FmeasureAvg = new Stat(); + Stat fortify1FmeasureMax = new Stat(); + Stat fortify1FmeasureMin = new Stat(); + Stat fortify1FmeasureDev = new Stat(); + + + Stat fortify2FmeasureAvg = new Stat(); + Stat fortify2FmeasureMax = new Stat(); + Stat fortify2FmeasureMin = new Stat(); + Stat fortify2FmeasureDev = new Stat(); + + Stat noOfDescriptionsAgv = new Stat(); + Stat noOfDescriptionsMax = new Stat(); + Stat noOfDescriptionsMin = new Stat(); + Stat noOfDescriptionsDev = new Stat(); + + Stat noOfCounterPartialDefinitionsAvg = new Stat(); + Stat noOfCounterPartialDefinitionsDev = new Stat(); + Stat noOfCounterPartialDefinitionsMax = new Stat(); + Stat noOfCounterPartialDefinitionsMin = new Stat(); + + Stat noOfCounterPartialDefinitionsUsedAvg = new Stat(); + Stat noOfCounterPartialDefinitionsUsedDev = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMax = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMin = new Stat(); + + + for (int kk=0; kk < noOfRuns; kk++) { + + //runtime + runtime = new Stat(); + fMeasure = new Stat(); + fMeasureTraining = new Stat(); + + noOfPartialDef = new Stat(); + avgPartialDefinitionLength = new Stat(); + length = new Stat(); + accuracyTraining = new Stat(); + trainingCorrectnessStat= new Stat(); + trainingCompletenessStat = new Stat(); + accuracy = new Stat(); + testingCorrectnessStat = new Stat(); + testingCompletenessStat = new Stat(); + + noOfCounterPartialDefinitions = new Stat(); + noOfCounterPartialDefinitionsUsed = new Stat(); + learningTime = new Stat(); + + //fortify strategy statistical variables + accuracyFortify1Stat = new Stat(); + accuracyFortify2Stat = new Stat(); + correctnessFortify1Stat = new Stat(); + correctnessFortify2Stat = new Stat(); + completenessFortify2Stat = new Stat(); + fmeasureFortify1Stat = new Stat(); + fmeasureFortify2Stat = new Stat(); + avgFortifiedPartialDefinitionLengthStat = new Stat(); + avgFortifyCoverageTrainingStatLevel1 = new Stat(); + avgFortifyCoverageTestStatLevel1 = new Stat(); + avgFortifyCoverageTrainingStatLevel2 = new Stat(); + avgFortifyCoverageTestStatLevel2 = new Stat(); + avgFortifyDefinitionsLengthStat = new Stat(); + + avgNoOfFortifiedDefinitions = new Stat(); + avgNoOfFortifiedDefinitionsL1 = new Stat(); + avgNoOfFortifiedDefinitionsL2 = new Stat(); + + totalNumberOfDescriptions = new Stat(); + + for(int currFold=0; (currFold pos = Datastructures.individualSetToStringSet(trainingSetsPos.get(currFold)); + //Set neg = Datastructures.individualSetToStringSet(trainingSetsNeg.get(currFold)); + lp.setPositiveExamples(trainingSetsPos.get(currFold)); + lp.setNegativeExamples(trainingSetsNeg.get(currFold)); + + try { + lp.init(); + la.init(); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + + long algorithmStartTime = System.nanoTime(); + try { + la.start(); + } + catch (OutOfMemoryError e) { + System.out.println("out of memory at " + (System.currentTimeMillis() - algorithmStartTime)/1000 + "s"); + } + + long algorithmDuration = System.nanoTime() - algorithmStartTime; + runtime.addNumber(algorithmDuration/(double)1000000000); + + //learning time, does not include the reduction time + long learningMili = ((ParCELAbstract)la).getLearningTime(); + learningTime.addNumber(learningMili/(double)1000); + + //no of counter partial definition + this.noOfCounterPartialDefinitions.addNumber(((ParCELExAbstract)la).getNumberOfCounterPartialDefinitions()); + this.noOfCounterPartialDefinitionsUsed.addNumber(((ParCELExAbstract)la).getNumberOfCounterPartialDefinitionUsed()); + + + //cast the la into ParCELExAbstract for easy accessing + ParCELExAbstract parcelEx = (ParCELExAbstract)la; + + //get the target (learned) definition + OWLClassExpression concept = parcelEx.getUnionCurrentlyBestDescription(); + + //for the training accuracy, we do not need to refine because the reducer warranty the best accuracy returned + Set tmp = rs.hasType(concept, trainingSetsPos.get(currFold)); + Set tmp2 = Sets.difference(trainingSetsPos.get(currFold), tmp); + Set tmp3 = rs.hasType(concept, trainingSetsNeg.get(currFold)); + + outputWriter("training set errors pos (" + tmp2.size() + "): " + tmp2); + outputWriter("training set errors neg (" + tmp3.size() + "): " + tmp3); + + + //calculate the accuracy on the test set + tmp = rs.hasType(concept, testSetsPos.get(currFold)); //examples covered by the definition + tmp2 = Sets.difference(testSetsPos.get(currFold), tmp); //false negative + tmp3 = rs.hasType(concept, testSetsNeg.get(currFold)); //false positive + + outputWriter("test set errors pos (" + tmp2.size() + "): " + tmp2); + outputWriter("test set errors neg (" + tmp3.size() + "): " + tmp3); + + //if the correctness is not 100%, check if we can improve it using the counter partial definition + int fixedNegLevel1 = 0; + int fixedNegLevel2 = 0; + int errorFixedPosLevel2 = 0; + int addedLength = 0; //total length of fortify counter partial definitions + + int fortifyLevel1Count = 0; + int fortifyLevel2Count = 0; + int totalFortifyTrainingCoverageLevel1 = 0; + int totalFortifyTestCoverageLevel1 = 0; + int totalFortifyTrainingCoverageLevel2 = 0; + int totalFortifyTestCoverageLevel2 = 0; + + double avgFortifyTrainingCoverageLevel1 = 0; + double avgFortifyTestCoverageLevel1 = 0; + double avgFortifyTrainingCoverageLevel2 = 0; + double avgFortifyTestCoverageLevel2 = 0; + + + //if there is a false positive (neg. as pos.), identify the error partial definition and + //use the counter partial definitions to fix it + if (tmp3.size() > 0) { + SortedSet counterPartialDefinitions = parcelEx.getCounterPartialDefinitions(); + SortedSet reducedPartialDefinitions = parcelEx.getReducedPartialDefinition(); + + //identify the partial definition cause the false positive + Set negTestSet = testSetsNeg.get(currFold); + Set fortifiedCounterDefinitions = new TreeSet(new ParCELTestingCorrectnessComparator()); + + for (ParCELExtraNode pdef : reducedPartialDefinitions) { + + //check if the partial definition covers some of the negative examples + Set coveredNeg = rs.hasType(pdef.getDescription(), negTestSet); + + if (coveredNeg.size() > 0) { + + //create a temporary set to test for the intersection (this may not a good solution but for testing only) + TreeSet tempCoveredNeg = new TreeSet<>(); + tempCoveredNeg.addAll(coveredNeg); + + //if yes, find the counter partial definitions that can help to fix this + logger.info(" ==> incorect partial definition: " + pdef + + "\n\tcovered negative examples (" + coveredNeg.size() + "): " + + coveredNeg); + + for (ParCELExtraNode cpdef : counterPartialDefinitions) { + OWLClassExpression child = OWLClassExpressionUtils.getChildren(cpdef.getDescription()).iterator().next(); + Set cpdefNegCovered = new HashSet<>(rs.hasType(child, negTestSet)); + logger.info(" - cpdef: " + child.toString() + + ", covered neg.: " + cpdefNegCovered); + + //if (tempCoveredNeg.removeAll(cpdef.getCoveredNegativeExamples())) { + if (tempCoveredNeg.removeAll(cpdefNegCovered)) { + //get the covered positive examples on test set + Set cpdefPosCovered = new HashSet<>(rs.hasType(child, testSetsPos.get(currFold))); + + //add the fortify counter partial definition into the potential fortify counter definition set + fortifiedCounterDefinitions.add(new ParCELExtraTestingNode(cpdef, cpdefPosCovered, cpdefNegCovered)); + + //logger.info(" --> fixed by: " + cpdef + "\n\tcovered negative examples: " + cpdefNegCovered + + // "\n\tcovered positive examples: " + cpdefPosCovered); + + //pdef.setDescription(new Intersection(pdef.getDescription(), cpdef.getDescription())); + //NOTE: do not need to adjust the covered positive examples and covered negative examples. why? + //calculate the adjusted accuracy (and correctness and completeness) + + } + + //if (tempCoveredNeg.size() == 0) + // break; + } //find the fortified counter partial definitions (for each counter partial definition) + + } //if (cn(pd) > 0): the current partial definition covers some negative examples ==> potential fortify definition + + } //for each reduced partial definition + + //process the potential fortify counter partial definitions + //the fortify definitions are divided into 2 levels: level 1 covers neg. only, level 2 covers both pos. and neg. + + Set fortifiedLevel1 = new TreeSet(new ParCELTestingCorrectnessComparator()); + Set fortifiedLevel2 = new TreeSet(new ParCELTestingCorrectnessComparator()); + for (ParCELExtraTestingNode n : fortifiedCounterDefinitions) { + if (n.getCoveredPositiveExamplesTestSet().size() == 0) + fortifiedLevel1.add(n); + else + fortifiedLevel2.add(n); + } + + //level 1: + fixedNegLevel1 = tmp3.size(); + + logger.info(" **fixing using fortifying counter partial definitions - level 1:"); + for (ParCELExtraTestingNode n : fortifiedLevel1) { + if (tmp3.removeAll(n.getCoveredNegativeExamplestestSet())) { + logger.info(" --> fixed by: " + n.getExtraNode() + + "\n\tcovered negative examples (" + n.getCoveredNegativeExamplestestSet().size() + "): " + + n.getCoveredNegativeExamplestestSet()); + + addedLength += OWLClassExpressionUtils.getLength(n.getExtraNode().getDescription()); + + fortifyLevel1Count++; + totalFortifyTestCoverageLevel1 += n.getExtraNode().getCoveredNegativeExamples().size(); + totalFortifyTrainingCoverageLevel1+= n.getCoveredNegativeExamplestestSet().size(); + + if (tmp3.size() <= 0) + break; + } + } + + fixedNegLevel1 -= tmp3.size(); //number of negative examples removed by level 1 + + //level 2: + fixedNegLevel2 = tmp3.size(); + errorFixedPosLevel2 = tmp2.size(); + if (tmp3.size() > 0) { + logger.info(" **fixing using fortifying counter partial definitions - level 2:"); + for (ParCELExtraTestingNode n : fortifiedLevel2) { + if (tmp3.removeAll(n.getCoveredNegativeExamplestestSet())) { + logger.info(" --> fixed by: " + n.getExtraNode() + + "\n\tcovered negative examples (" + n.getCoveredNegativeExamplestestSet().size() + "): " + + n.getCoveredNegativeExamplestestSet() + + "\n\tcovered positive examples: " + n.getCoveredPositiveExamplesTestSet().size() + "): " + + n.getCoveredPositiveExamplesTestSet()); + tmp2.addAll(n.getCoveredPositiveExamplesTestSet()); + + addedLength += OWLClassExpressionUtils.getLength(n.getExtraNode().getDescription()); + + fortifyLevel2Count++; + totalFortifyTrainingCoverageLevel2 += n.getExtraNode().getCoveredNegativeExamples().size(); + totalFortifyTestCoverageLevel2 += n.getCoveredNegativeExamplestestSet().size(); + + + if (tmp3.size() <= 0) + break; + } + } + } + + fixedNegLevel2 -= tmp3.size(); //number of negative examples removed by level 2 + errorFixedPosLevel2 = tmp2.size() - errorFixedPosLevel2; //number of positive examples that is wrong classified by level 2 of fixing + + if (fortifyLevel1Count > 0) { + avgFortifyTrainingCoverageLevel1 = 100*totalFortifyTrainingCoverageLevel1/(double)fortifyLevel1Count; + avgFortifyTrainingCoverageLevel1 /= trainingSetsNeg.get(currFold).size(); + + avgFortifyTestCoverageLevel1 = 100*totalFortifyTestCoverageLevel1/(double)fortifyLevel1Count; + avgFortifyTestCoverageLevel1 /= testSetsNeg.get(currFold).size(); + + avgFortifyCoverageTrainingStatLevel1.addNumber(avgFortifyTrainingCoverageLevel1); + avgFortifyCoverageTestStatLevel1.addNumber(avgFortifyTestCoverageLevel1); + } + + if (fortifyLevel2Count > 0) { + avgFortifyTrainingCoverageLevel2 = 100*totalFortifyTrainingCoverageLevel2/(double)fortifyLevel2Count; + avgFortifyTrainingCoverageLevel2 /= trainingSetsNeg.get(currFold).size(); + + avgFortifyTestCoverageLevel2 = 100*totalFortifyTestCoverageLevel2/(double)fortifyLevel2Count; + avgFortifyTestCoverageLevel2 /= testSetsNeg.get(currFold).size(); + + + avgFortifyCoverageTrainingStatLevel2.addNumber(avgFortifyTrainingCoverageLevel2); + avgFortifyCoverageTestStatLevel2.addNumber(avgFortifyTestCoverageLevel2); + + } + + outputWriter("test set errors pos after fixing: (" + tmp2.size() + "): " + tmp2); + outputWriter("test set errors neg after fixing: (" + tmp3.size() + "): " + tmp3); + + /* + //combine + LinkedList tmpPartialDefinition = new LinkedList(); + for (ParCELExtraNode rpd : reducedPartialDefinitions) + tmpPartialDefinition.add(rpd.getDescription()); + + concept = new Union(tmpPartialDefinition); + */ + + } //of false positive + + avgNoOfFortifiedDefinitionsL1.addNumber(fortifyLevel1Count); + avgNoOfFortifiedDefinitionsL2.addNumber(fortifyLevel2Count); + avgNoOfFortifiedDefinitions.addNumber(fortifyLevel1Count+fortifyLevel2Count); + + double avgFortifyDefinitionsLength = (addedLength==0? 0 : (double)addedLength/(fortifyLevel1Count+fortifyLevel2Count)); + avgFortifyDefinitionsLengthStat.addNumber(avgFortifyDefinitionsLength); + + // calculate training accuracies + int trainingPosSize = trainingSetsPos.get(currFold).size() ; + int trainingNegSize = trainingSetsNeg.get(currFold).size(); + int testingPosSize = testSetsPos.get(currFold).size(); + int testingNegSize = testSetsNeg.get(currFold).size(); + + //TODO: this should be refined so that we can use the above result to avoid re-calculation + int trainingCorrectPosClassified = getCorrectPosClassified(rs, concept, trainingSetsPos.get(currFold)); + int trainingCorrectNegClassified = getCorrectNegClassified(rs, concept, trainingSetsNeg.get(currFold)); + int trainingCorrectExamples = trainingCorrectPosClassified + trainingCorrectNegClassified; + double trainingAccuracy = 100*((double)trainingCorrectExamples/(trainingPosSize + + trainingNegSize)); + + double trainingCompleteness = 100*(double)trainingCorrectPosClassified/trainingPosSize; + double trainingCorrectness = 100*(double)trainingCorrectNegClassified/trainingNegSize; + + accuracyTraining.addNumber(trainingAccuracy); + trainingCompletenessStat.addNumber(trainingCompleteness); + trainingCorrectnessStat.addNumber(trainingCorrectness); + + // calculate test accuracies + //int correctPosClassified = getCorrectPosClassified(rs, concept, testSetsPos.get(currFold)); + //int correctNegClassified = getCorrectNegClassified(rs, concept, testSetsNeg.get(currFold)); + //int correctExamples = correctPosClassified + correctNegClassified; + int correctPosClassified = testingPosSize - tmp2.size(); //tmp2: wrong classification of pos. examples + int correctNegClassified = testingNegSize - tmp3.size(); //tmp3: wrong classification of neg. examples + int correctExamples = correctPosClassified + correctNegClassified; + + double testingCompleteness = 100*(double)correctPosClassified/testingPosSize; + double testingCorrectness = 100*(double)correctNegClassified/testingNegSize; + + double currAccuracy = 100*((double)correctExamples/(testingPosSize + testingNegSize)); + + accuracy.addNumber(currAccuracy); + testingCompletenessStat.addNumber(testingCompleteness); + testingCorrectnessStat.addNumber(testingCorrectness); + + + //fortify + double testingCompletenessFortify2 = 100*(double)(correctPosClassified - errorFixedPosLevel2)/testingPosSize; + double testingCorrectnessFortify1 = 100*(double)(correctNegClassified + fixedNegLevel1)/testingNegSize; + double testingCorrectnessFortify2 = 100*(double)(correctNegClassified + fixedNegLevel1 + fixedNegLevel2)/testingNegSize; + double testingAccuracyFortify1 = 100*((double)(correctExamples + fixedNegLevel1)/(testingPosSize + testingNegSize)); + double testingAccuracyFortify2 = 100*((double)(correctExamples + fixedNegLevel1 + fixedNegLevel2 - errorFixedPosLevel2)/(testingPosSize + testingNegSize));; + + //fortify + accuracyFortify1Stat.addNumber(testingAccuracyFortify1); + accuracyFortify2Stat.addNumber(testingAccuracyFortify2); + + correctnessFortify1Stat.addNumber(testingCorrectnessFortify1); + correctnessFortify2Stat.addNumber(testingCorrectnessFortify2); + + completenessFortify2Stat.addNumber(testingCompletenessFortify2); + + + // calculate training F-Score + int negAsPosTraining = rs.hasType(concept, trainingSetsNeg.get(currFold)).size(); + double precisionTraining = trainingCorrectPosClassified + negAsPosTraining == 0 ? 0 : trainingCorrectPosClassified / (double) (trainingCorrectPosClassified + negAsPosTraining); + double recallTraining = trainingCorrectPosClassified / (double) trainingSetsPos.get(currFold).size(); + double currFmeasureTraining = 100*Heuristics.getFScore(recallTraining, precisionTraining); + fMeasureTraining.addNumber(currFmeasureTraining); + + + // calculate test F-Score + int negAsPos = rs.hasType(concept, testSetsNeg.get(currFold)).size(); + double precision = correctPosClassified + negAsPos == 0 ? 0 : correctPosClassified / (double) (correctPosClassified + negAsPos); + double recall = correctPosClassified / (double) testingPosSize; + //System.out.println(precision);System.out.println(recall); + double currFmeasureTest = 100*Heuristics.getFScore(recall, precision); + fMeasure.addNumber(currFmeasureTest); + + //fortify + double precision1 = (correctPosClassified + (negAsPos - fixedNegLevel1)) == 0 ? + 0 : correctPosClassified / (double) (correctPosClassified + negAsPos - fixedNegLevel1);; + double precision2 = ((correctPosClassified - errorFixedPosLevel2) + (negAsPos - fixedNegLevel1 - fixedNegLevel2)) == 0 ? + 0 : correctPosClassified / (double) ((correctPosClassified - errorFixedPosLevel2) + (negAsPos - fixedNegLevel1 - fixedNegLevel2));; + double recall2 = (correctPosClassified - errorFixedPosLevel2) / (double) testingPosSize; + + double testingFmeasureFortiafy1 = 100*Heuristics.getFScore(recall, precision1); + double testingFmeasureFortiafy2 = 100*Heuristics.getFScore(recall2, precision2); + + fmeasureFortify1Stat.addNumber(testingFmeasureFortiafy1); + fmeasureFortify2Stat.addNumber(testingFmeasureFortiafy2); + + length.addNumber(OWLClassExpressionUtils.getLength(concept)); + totalNumberOfDescriptions.addNumber(parcelEx.getTotalNumberOfDescriptionsGenerated()); + + outputWriter("Fold " + currFold + "/" + folds + ":"); + outputWriter(" training: " + trainingCorrectPosClassified + "/" + trainingSetsPos.get(currFold).size() + + " positive and " + trainingCorrectNegClassified + "/" + trainingSetsNeg.get(currFold).size() + " negative examples"); + outputWriter(" testing: " + correctPosClassified + "/" + testSetsPos.get(currFold).size() + " correct positives, " + + correctNegClassified + "/" + testSetsNeg.get(currFold).size() + " correct negatives"); + + outputWriter(" runtime: " + df.format(algorithmDuration/(double)1000000000) + "s"); + outputWriter(" learning time: " + df.format(learningMili/(double)1000) + "s"); + outputWriter(" definition length: " + df.format(OWLClassExpressionUtils.getLength(concept))); + + outputWriter(" concept: " + concept); + + outputWriter(" f-measure test: " + df.format(currFmeasureTest) + + "% (" + df.format(currFmeasureTraining) + "% on training set)"); + + outputWriter(" f-measure fortify 1: " + df.format(testingFmeasureFortiafy1) + + "%, fortify 2:" + df.format(testingFmeasureFortiafy2) + "%"); + + + outputWriter(" accuracy test: " + df.format(currAccuracy) + + "% (corr:"+ df.format(testingCorrectness) + + "%, comp:" + df.format(testingCompleteness) + "%) --- " + + df.format(trainingAccuracy) + "% (corr:"+ trainingCorrectness + + "%, comp:" + df.format(trainingCompleteness) + "%) on training set"); + + outputWriter(" fortified accuracy 1: " + df.format(testingAccuracyFortify1) + + "%, correctness: " + df.format(testingCorrectnessFortify1) + + "%, completeness: " + df.format(testingCompleteness) + "%"); //after applying the level 1 fixing, completeness does not change + + outputWriter(" fortified accuracy 2: " + df.format(testingAccuracyFortify2) + + "%, correctness: " + df.format(testingCorrectnessFortify2) + + "%, completeness: " + df.format(testingCompletenessFortify2) + "%"); + + outputWriter(" avg. fortified training coverage: +level 1: " + df.format(avgFortifyTrainingCoverageLevel1) + + "%, +level 2: " + df.format(avgFortifyTrainingCoverageLevel2) + "%"); + + outputWriter(" avg. fortified test coverage: +level 1: " + df.format(avgFortifyTestCoverageLevel1) + + "%, +level 2: " + df.format(avgFortifyTestCoverageLevel2) + "%"); + + +// outputWriter(" total number of descriptions: " + la.getTotalNumberOfDescriptionsGenerated()); // TODO method not available yet + + if (la instanceof ParCELAbstract) { + int pn = ((ParCELAbstract)la).getNoOfReducedPartialDefinition(); + this.noOfPartialDef.addNumber(pn); + outputWriter(" number of partial definitions: " + pn + "/" + ((ParCELAbstract)la).getNumberOfPartialDefinitions()); + + double pl = OWLClassExpressionUtils.getLength(concept)/(double)pn; + this.avgPartialDefinitionLength.addNumber(pl); + outputWriter(" average partial definition length: " + df.format(pl)); + + double avgFortifiedPartialDefinitionLength = pl + (addedLength==0 ? 0: (double)addedLength/pn); + avgFortifiedPartialDefinitionLengthStat.addNumber(avgFortifiedPartialDefinitionLength); + + outputWriter(" average fortified partial definition length: " + df.format(avgFortifiedPartialDefinitionLength)); + outputWriter(" average fortify partial definition length: " + df.format(avgFortifiedPartialDefinitionLength)); + + //show more information on counter partial definitions + if (la instanceof ParCELExAbstract) { + ParCELExAbstract pdllexla = (ParCELExAbstract)la; + outputWriter(" number of partial definitions for each type: 1:" + pdllexla.getNumberOfPartialDefinitions(1) + + "; 2:" + pdllexla.getNumberOfPartialDefinitions(2) + + "; 3:" + pdllexla.getNumberOfPartialDefinitions(3) + + "; 4:" + pdllexla.getNumberOfPartialDefinitions(4)); + outputWriter(" number of counter partial definition used: " + pdllexla.getNumberOfCounterPartialDefinitionUsed() + "/" + pdllexla.getNumberOfCounterPartialDefinitions()); + + outputWriter(" number of fortify definition: " + (fortifyLevel1Count+fortifyLevel2Count) + + "(level 1: " + fortifyLevel1Count + ", level 2: " + fortifyLevel2Count + ")"); + + //check how did the learner terminate: by partial definition or counter partial definition + if (pdllexla.terminatedByCounterDefinitions()) { + outputWriter(" terminated by counter partial definitions"); + terminatedByCounterPartialDefinitions++; + } + else if (pdllexla.terminatedByPartialDefinitions()) { + outputWriter(" terminated by partial definitions"); + terminatedBypartialDefinition++; + } + else + outputWriter(" neither terminated by partial definition nor counter partial definition"); + } + } + + //cumulative statistical data + outputWriter("----------"); + outputWriter("Aggregate data from fold 0 to fold " + currFold + "/" + folds); + outputWriter(" runtime: " + statOutput(df, runtime, "s")); + outputWriter(" no of descriptions: " + statOutput(df, totalNumberOfDescriptions, "")); + outputWriter(" length: " + statOutput(df, length, "")); + outputWriter(" avg. no of partial definitions: " + statOutput(df, noOfPartialDef, "")); + outputWriter(" avg. partial definition length: " + statOutput(df, avgPartialDefinitionLength, "")); + outputWriter(" avg. no of fortify definitions: " + statOutput(df, avgNoOfFortifiedDefinitions, "")); + outputWriter(" level 1: " + statOutput(df, avgNoOfFortifiedDefinitionsL1, "")); + outputWriter(" level 2: " + statOutput(df, avgNoOfFortifiedDefinitionsL2, "")); + outputWriter(" avg. fortified partial definition length: " + statOutput(df, avgFortifiedPartialDefinitionLengthStat, "")); + outputWriter(" avg. fortify definition length: " + statOutput(df, avgFortifyDefinitionsLengthStat, "")); + outputWriter(" F-Measure on training set: " + statOutput(df, fMeasureTraining, "%")); + outputWriter(" F-Measure on test set: " + statOutput(df, fMeasure, "%")); + outputWriter(" F-Measure fortify 1: " + statOutput(df, fmeasureFortify1Stat, "%")); + outputWriter(" F-Measure fortify 2: " + statOutput(df, fmeasureFortify2Stat, "%")); + outputWriter(" predictive accuracy on training set: " + statOutput(df, accuracyTraining, "%") + + " -- correctness: " + statOutput(df, trainingCorrectnessStat, "%") + + "-- completeness: " + statOutput(df, trainingCompletenessStat, "%")); + outputWriter(" predictive accuracy on test set: " + statOutput(df, accuracy, "%") + + " -- correctness: " + statOutput(df, testingCorrectnessStat, "%") + + "-- completeness: " + statOutput(df, testingCompletenessStat, "%")); + + outputWriter(" accuracy fortify 1: " + statOutput(df, accuracyFortify1Stat, "%") + + " -- correctness: " + statOutput(df, correctnessFortify1Stat, "%") + + "-- completeness: " + statOutput(df, testingCompletenessStat, "%")); + + outputWriter(" accuracy fortify 2: " + statOutput(df, accuracyFortify2Stat, "%") + + " -- correctness: " + statOutput(df, correctnessFortify2Stat, "%") + + "-- completeness: " + statOutput(df, completenessFortify2Stat, "%")); + + outputWriter(" coverage fortify 1: + training:" + + statOutput(df, avgFortifyCoverageTrainingStatLevel1, "%") + + ", +test: " + statOutput(df, avgFortifyCoverageTestStatLevel1, "%") + ); + + outputWriter(" coverage fortify 2: +training:" + + statOutput(df, avgFortifyCoverageTrainingStatLevel2, "%") + + ", +test: " + statOutput(df, avgFortifyCoverageTestStatLevel2, "%") + ); + + + outputWriter("----------------------"); + + //sleep after each run (fer MBean collecting information purpose) + try { + Thread.sleep(5000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + + } //for k folds + + + //--------------------------------- + //end of k-fold cross validation + //output result of the k-fold + //--------------------------------- + + //final cumulative statistical data of a run + outputWriter(""); + outputWriter("Finished the " + (kk+1) + "/" + noOfRuns + " of " + folds + "-folds cross-validation."); + outputWriter(" runtime: " + statOutput(df, runtime, "s")); + outputWriter(" learning time: " + statOutput(df, learningTime, "s")); + outputWriter(" no of descriptions: " + statOutput(df, totalNumberOfDescriptions, "")); + outputWriter(" no of partial definitions: " + statOutput(df, noOfPartialDef, "")); + outputWriter(" avg. partial definition length: " + statOutput(df, avgPartialDefinitionLength, "")); + outputWriter(" avg. no of fortify definitions: " + statOutput(df, avgNoOfFortifiedDefinitions, "")); + outputWriter(" level 1: " + statOutput(df, avgNoOfFortifiedDefinitionsL1, "")); + outputWriter(" level 2: " + statOutput(df, avgNoOfFortifiedDefinitionsL2, "")); + outputWriter(" definition length: " + statOutput(df, length, "")); + outputWriter(" avg. fortified partial definition length: " + statOutput(df, avgFortifiedPartialDefinitionLengthStat, "")); + outputWriter(" avg. fortify partial definition length: " + statOutput(df, avgFortifyDefinitionsLengthStat, "")); + outputWriter(" no of counter partial definition: " + statOutput(df, noOfCounterPartialDefinitions, "")); + outputWriter(" no of counter partial definition used: " + statOutput(df, noOfCounterPartialDefinitionsUsed, "")); + outputWriter(" F-Measure on training set: " + statOutput(df, fMeasureTraining, "%")); + outputWriter(" F-Measure on test set: " + statOutput(df, fMeasure, "%")); + outputWriter(" F-Measure fortify 1: " + statOutput(df, fmeasureFortify1Stat, "%")); + outputWriter(" F-Measure fortify 2: " + statOutput(df, fmeasureFortify2Stat, "%")); + outputWriter(" predictive accuracy on training set: " + statOutput(df, accuracyTraining, "%") + + " - corr: " + statOutput(df, trainingCorrectnessStat, "%") + + ", comp: " + statOutput(df, trainingCompletenessStat, "%")); + outputWriter(" predictive accuracy on test set: " + statOutput(df, accuracy, "%") + + " - corr: " + statOutput(df, testingCorrectnessStat, "%") + + ", comp: " + statOutput(df, testingCompletenessStat, "%")); + + outputWriter(" accuracy fortify 1: " + statOutput(df, accuracyFortify1Stat, "%") + + " -- correctness: " + statOutput(df, correctnessFortify1Stat, "%") + + "-- completeness: " + statOutput(df, testingCompletenessStat, "%")); + + outputWriter(" accuracy fortify 2: " + statOutput(df, accuracyFortify2Stat, "%") + + " -- correctness: " + statOutput(df, correctnessFortify2Stat, "%") + + "-- completeness: " + statOutput(df, completenessFortify2Stat, "%")); + + + if (la instanceof ParCELExAbstract) + outputWriter(" terminated by: partial def.: " + terminatedBypartialDefinition + "; counter partial def.: " + terminatedByCounterPartialDefinitions); + + + //this is for copying to word document + //f-measure, accuracy, correctness, completeness, avg pdef length, no of pdef, time, no of des, no of cpdef + outputWriter("***without fortify (f-measure, accuracy, correctness, completeness, avg. pdef length)***\n" + + df.format(fMeasure.getMean()) + "\n" + df.format(fMeasure.getStandardDeviation()) + "\n" + + df.format(accuracy.getMean()) + "\n" + df.format(accuracy.getStandardDeviation()) + "\n" + + df.format(testingCorrectnessStat.getMean()) + "\n" + df.format(testingCorrectnessStat.getStandardDeviation()) + "\n" + + df.format(testingCompletenessStat.getMean()) + "\n" + df.format(testingCompletenessStat.getStandardDeviation()) + "\n" + + df.format(avgPartialDefinitionLength.getMean()) + "\n" + df.format(avgPartialDefinitionLength.getStandardDeviation()) + "\n" + ); + + + outputWriter("***with fortify 1 (f-measure, accuracy, correctness, completeness, fortified pdef length)***\n" + + df.format(fmeasureFortify1Stat.getMean()) + "\n" + df.format(fmeasureFortify1Stat.getStandardDeviation()) + "\n" + + df.format(accuracyFortify1Stat.getMean()) + "\n" + df.format(accuracyFortify1Stat.getStandardDeviation()) + "\n" + + df.format(correctnessFortify1Stat.getMean()) + "\n" + df.format(correctnessFortify1Stat.getStandardDeviation()) + "\n" + + df.format(testingCompletenessStat.getMean()) + "\n" + df.format(testingCompletenessStat.getStandardDeviation()) + "\n" + + df.format(avgFortifiedPartialDefinitionLengthStat.getMean()) + "\n" + df.format(avgFortifiedPartialDefinitionLengthStat.getStandardDeviation()) + "\n" + ); + + outputWriter("***Common dimensionss (no of pdef., learning time, no of des., no of cpdef., no of fdef.)***\n" + + df.format(noOfPartialDef.getMean()) + "\n" + df.format(noOfPartialDef.getStandardDeviation()) + "\n" + + df.format(learningTime.getMean()) + "\n" + df.format(learningTime.getStandardDeviation()) + "\n" + + df.format(totalNumberOfDescriptions.getMean()) + "\n" + df.format(totalNumberOfDescriptions.getStandardDeviation()) + "\n" + + df.format(noOfCounterPartialDefinitions.getMean()) + "\n" + df.format(noOfCounterPartialDefinitions.getStandardDeviation()) + "\n" + + df.format(avgNoOfFortifiedDefinitions.getMean()) + "\n" + df.format(avgNoOfFortifiedDefinitions.getStandardDeviation()) + "\n" + ); + + + outputWriter("***with fortify 2 (f-measure, accuracy, correctness, completeness, avg. fortified pdef length)***\n" + + df.format(fmeasureFortify2Stat.getMean()) + "\n" + df.format(fmeasureFortify1Stat.getStandardDeviation()) + "\n" + + df.format(accuracyFortify2Stat.getMean()) + "\n" + df.format(accuracyFortify1Stat.getStandardDeviation()) + "\n" + + df.format(correctnessFortify2Stat.getMean()) + "\n" + df.format(correctnessFortify1Stat.getStandardDeviation()) + "\n" + + df.format(completenessFortify2Stat.getMean()) + "\n" + df.format(completenessFortify2Stat.getStandardDeviation()) + "\n" + + df.format(avgFortifiedPartialDefinitionLengthStat.getMean()) + "\n" + df.format(avgFortifiedPartialDefinitionLengthStat.getStandardDeviation()) + "\n" + ); + + + if (noOfRuns > 1) { + //runtime + runtimeAvg.addNumber(runtime.getMean()); + runtimeMax.addNumber(runtime.getMax()); + runtimeMin.addNumber(runtime.getMin()); + runtimeDev.addNumber(runtime.getStandardDeviation()); + + //learning time + learningTimeAvg.addNumber(learningTime.getMean()); + learningTimeDev.addNumber(learningTime.getStandardDeviation()); + learningTimeMax.addNumber(learningTime.getMax()); + learningTimeMin.addNumber(learningTime.getMin()); + + //number of partial definitions + noOfPartialDefAvg.addNumber(noOfPartialDef.getMean()); + noOfPartialDefMax.addNumber(noOfPartialDef.getMax()); + noOfPartialDefMin.addNumber(noOfPartialDef.getMin()); + noOfPartialDefDev.addNumber(noOfPartialDef.getStandardDeviation()); + + //avg partial definition length + avgPartialDefLenAvg.addNumber(avgPartialDefinitionLength.getMean()); + avgPartialDefLenMax.addNumber(avgPartialDefinitionLength.getMax()); + avgPartialDefLenMin.addNumber(avgPartialDefinitionLength.getMin()); + avgPartialDefLenDev.addNumber(avgPartialDefinitionLength.getStandardDeviation()); + + avgFortifiedPartialDefLenAvg.addNumber(avgFortifiedPartialDefinitionLengthStat.getMean()); + avgFortifiedPartialDefLenMax.addNumber(avgFortifiedPartialDefinitionLengthStat.getMax()); + avgFortifiedPartialDefLenMin.addNumber(avgFortifiedPartialDefinitionLengthStat.getMin()); + avgFortifiedPartialDefLenDev.addNumber(avgFortifiedPartialDefinitionLengthStat.getStandardDeviation()); + + + defLenAvg.addNumber(length.getMean()); + defLenMax.addNumber(length.getMax()); + defLenMin.addNumber(length.getMin()); + defLenDev.addNumber(length.getStandardDeviation()); + + //counter partial definitions + noOfCounterPartialDefinitionsAvg.addNumber(noOfCounterPartialDefinitions.getMean()); + noOfCounterPartialDefinitionsDev.addNumber(noOfCounterPartialDefinitions.getStandardDeviation()); + noOfCounterPartialDefinitionsMax.addNumber(noOfCounterPartialDefinitions.getMax()); + noOfCounterPartialDefinitionsMin.addNumber(noOfCounterPartialDefinitions.getMin()); + + noOfCounterPartialDefinitionsUsedAvg.addNumber(noOfCounterPartialDefinitionsUsed.getMean()); + noOfCounterPartialDefinitionsUsedDev.addNumber(noOfCounterPartialDefinitionsUsed.getStandardDeviation()); + noOfCounterPartialDefinitionsUsedMax.addNumber(noOfCounterPartialDefinitionsUsed.getMax()); + noOfCounterPartialDefinitionsUsedMin.addNumber(noOfCounterPartialDefinitionsUsed.getMin()); + + //training accuracy + trainingAccAvg.addNumber(accuracyTraining.getMean()); + trainingAccDev.addNumber(accuracyTraining.getStandardDeviation()); + trainingAccMax.addNumber(accuracyTraining.getMax()); + trainingAccMin.addNumber(accuracyTraining.getMin()); + + trainingCorAvg.addNumber(trainingCorrectnessStat.getMean()); + trainingCorDev.addNumber(trainingCorrectnessStat.getStandardDeviation()); + trainingCorMax.addNumber(trainingCorrectnessStat.getMax()); + trainingCorMin.addNumber(trainingCorrectnessStat.getMin()); + + trainingComAvg.addNumber(trainingCompletenessStat.getMean()); + trainingComDev.addNumber(trainingCompletenessStat.getStandardDeviation()); + trainingComMax.addNumber(trainingCompletenessStat.getMax()); + trainingComMin.addNumber(trainingCompletenessStat.getMin()); + + testingAccAvg.addNumber(accuracy.getMean()); + testingAccMax.addNumber(accuracy.getMax()); + testingAccMin.addNumber(accuracy.getMin()); + testingAccDev.addNumber(accuracy.getStandardDeviation()); + + //fortify accuracy + fortify1AccAvg.addNumber(accuracyFortify1Stat.getMean()); + fortify1AccMax.addNumber(accuracyFortify1Stat.getMax()); + fortify1AccMin.addNumber(accuracyFortify1Stat.getMin()); + fortify1AccDev.addNumber(accuracyFortify1Stat.getStandardDeviation()); + + fortify2AccAvg.addNumber(accuracyFortify2Stat.getMean()); + fortify2AccMax.addNumber(accuracyFortify2Stat.getMax()); + fortify2AccMin.addNumber(accuracyFortify2Stat.getMin()); + fortify2AccDev.addNumber(accuracyFortify2Stat.getStandardDeviation()); + + + testingCorAvg.addNumber(testingCorrectnessStat.getMean()); + testingCorDev.addNumber(testingCorrectnessStat.getStandardDeviation()); + testingCorMax.addNumber(testingCorrectnessStat.getMax()); + testingCorMin.addNumber(testingCorrectnessStat.getMin()); + + //fortify correctness + fortify1CorAvg.addNumber(correctnessFortify1Stat.getMean()); + fortify1CorMax.addNumber(correctnessFortify1Stat.getMax()); + fortify1CorMin.addNumber(correctnessFortify1Stat.getMin()); + fortify1CorDev.addNumber(correctnessFortify1Stat.getStandardDeviation()); + + fortify2CorAvg.addNumber(correctnessFortify2Stat.getMean()); + fortify2CorMax.addNumber(correctnessFortify2Stat.getMax()); + fortify2CorMin.addNumber(correctnessFortify2Stat.getMin()); + fortify2CorDev.addNumber(correctnessFortify2Stat.getStandardDeviation()); + + + testingComAvg.addNumber(testingCompletenessStat.getMean()); + testingComDev.addNumber(testingCompletenessStat.getStandardDeviation()); + testingComMax.addNumber(testingCompletenessStat.getMax()); + testingComMin.addNumber(testingCompletenessStat.getMin()); + + //fortify completeness (level 1 fixing does not change the completeness + fortify2ComAvg.addNumber(completenessFortify2Stat.getMean()); + fortify2ComMax.addNumber(completenessFortify2Stat.getMax()); + fortify2ComMin.addNumber(completenessFortify2Stat.getMin()); + fortify2ComDev.addNumber(completenessFortify2Stat.getStandardDeviation()); + + + testingFMeasureAvg.addNumber(fMeasure.getMean()); + testingFMeasureDev.addNumber(fMeasure.getStandardDeviation()); + testingFMeasureMax.addNumber(fMeasure.getMax()); + testingFMeasureMin.addNumber(fMeasure.getMin()); + + trainingFMeasureAvg.addNumber(fMeasureTraining.getMean()); + trainingFMeasureDev.addNumber(fMeasureTraining.getStandardDeviation()); + trainingFMeasureMax.addNumber(fMeasureTraining.getMax()); + trainingFMeasureMin.addNumber(fMeasureTraining.getMin()); + + fortify1FmeasureAvg.addNumber(fmeasureFortify1Stat.getMean()); + fortify1FmeasureMax.addNumber(fmeasureFortify1Stat.getMax()); + fortify1FmeasureMin.addNumber(fmeasureFortify1Stat.getMin()); + fortify1FmeasureDev.addNumber(fmeasureFortify1Stat.getStandardDeviation()); + + fortify2FmeasureAvg.addNumber(fmeasureFortify2Stat.getMean()); + fortify2FmeasureMax.addNumber(fmeasureFortify2Stat.getMax()); + fortify2FmeasureMin.addNumber(fmeasureFortify2Stat.getMin()); + fortify2FmeasureDev.addNumber(fmeasureFortify2Stat.getStandardDeviation()); + + + noOfDescriptionsAgv.addNumber(totalNumberOfDescriptions.getMean()); + noOfDescriptionsMax.addNumber(totalNumberOfDescriptions.getMax()); + noOfDescriptionsMin.addNumber(totalNumberOfDescriptions.getMin()); + noOfDescriptionsDev.addNumber(totalNumberOfDescriptions.getStandardDeviation()); + } + + } //for kk folds + + if (noOfRuns > 1) { + + outputWriter(""); + outputWriter("Finished " + noOfRuns + " time(s) of the " + folds + "-folds cross-validations"); + + outputWriter("runtime: " + + "\n\t avg.: " + statOutput(df, runtimeAvg, "s") + + "\n\t dev.: " + statOutput(df, runtimeDev, "s") + + "\n\t max.: " + statOutput(df, runtimeMax, "s") + + "\n\t min.: " + statOutput(df, runtimeMin, "s")); + + outputWriter("learning time: " + + "\n\t avg.: " + statOutput(df, learningTimeAvg, "s") + + "\n\t dev.: " + statOutput(df, learningTimeDev, "s") + + "\n\t max.: " + statOutput(df, learningTimeMax, "s") + + "\n\t min.: " + statOutput(df, learningTimeMin, "s")); + + outputWriter("no of descriptions: " + + "\n\t avg.: " + statOutput(df, noOfDescriptionsAgv, "") + + "\n\t dev.: " + statOutput(df, noOfDescriptionsDev, "") + + "\n\t max.: " + statOutput(df, noOfDescriptionsMax, "") + + "\n\t min.: " + statOutput(df, noOfDescriptionsMin, "")); + + outputWriter("number of partial definitions: " + + "\n\t avg.: " + statOutput(df, noOfPartialDefAvg, "") + + "\n\t dev.: " + statOutput(df, noOfPartialDefDev, "") + + "\n\t max.: " + statOutput(df, noOfPartialDefMax, "") + + "\n\t min.: " + statOutput(df, noOfPartialDefMin, "")); + + outputWriter("avg. partial definition length: " + + "\n\t avg.: " + statOutput(df, avgPartialDefLenAvg, "") + + "\n\t dev.: " + statOutput(df, avgPartialDefLenDev, "") + + "\n\t max.: " + statOutput(df, avgPartialDefLenMax, "") + + "\n\t min.: " + statOutput(df, avgPartialDefLenMin, "")); + + outputWriter("definition length: " + + "\n\t avg.: " + statOutput(df, defLenAvg, "") + + "\n\t dev.: " + statOutput(df, defLenDev, "") + + "\n\t max.: " + statOutput(df, defLenMax, "") + + "\n\t min.: " + statOutput(df, defLenMin, "")); + + outputWriter("number of counter partial definitions: " + + "\n\t avg.: " + statOutput(df, noOfCounterPartialDefinitionsAvg, "") + + "\n\t dev.: " + statOutput(df, noOfCounterPartialDefinitionsDev, "") + + "\n\t max.: " + statOutput(df, noOfCounterPartialDefinitionsMax, "") + + "\n\t min.: " + statOutput(df, noOfCounterPartialDefinitionsMin, "")); + + outputWriter("number of counter partial definitions used: " + + "\n\t avg.: " + statOutput(df, noOfCounterPartialDefinitionsUsedAvg, "") + + "\n\t dev.: " + statOutput(df, noOfCounterPartialDefinitionsUsedDev, "") + + "\n\t max.: " + statOutput(df, noOfCounterPartialDefinitionsUsedMax, "") + + "\n\t min.: " + statOutput(df, noOfCounterPartialDefinitionsUsedMin, "")); + + outputWriter("accuracy on training set:" + + "\n\t avg.: " + statOutput(df, trainingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingAccDev, "%") + + "\n\t max.: " + statOutput(df, trainingAccMax, "%") + + "\n\t min.: " + statOutput(df, trainingAccMin, "%")); + + outputWriter("correctness on training set: " + + "\n\t avg.: " + statOutput(df, trainingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingCorDev, "%") + + "\n\t max.: " + statOutput(df, trainingCorMax, "%") + + "\n\t min.: " + statOutput(df, trainingCorMin, "%")); + + outputWriter("completeness on training set: " + + "\n\t avg.: " + statOutput(df, trainingComAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingCorDev, "%") + + "\n\t max.: " + statOutput(df, trainingComMax, "%") + + "\n\t min.: " + statOutput(df, trainingComMin, "%")); + + outputWriter("FMeasure on training set: " + + "\n\t avg.: " + statOutput(df, trainingFMeasureAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingFMeasureDev, "%") + + "\n\t max.: " + statOutput(df, trainingFMeasureMax, "%") + + "\n\t min.: " + statOutput(df, trainingFMeasureMin, "%")); + + outputWriter("accuracy on testing set: " + + "\n\t avg.: " + statOutput(df, testingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, testingAccDev, "%") + + "\n\t max.: " + statOutput(df, testingAccMax, "%") + + "\n\t min.: " + statOutput(df, testingAccMin, "%")); + + outputWriter("correctness on testing set: " + + "\n\t avg.: " + statOutput(df, testingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, testingCorDev, "%") + + "\n\t max.: " + statOutput(df, testingCorMax, "%") + + "\n\t min.: " + statOutput(df, testingCorMin, "%")); + + outputWriter("completeness on testing set: " + + "\n\t avg.: " + statOutput(df, testingComAvg, "%") + + "\n\t dev.: " + statOutput(df, testingComDev, "%") + + "\n\t max.: " + statOutput(df, testingComMax, "%") + + "\n\t min.: " + statOutput(df, testingComMin, "%")); + + outputWriter("FMeasure on testing set: " + + "\n\t avg.: " + statOutput(df, testingFMeasureAvg, "%") + + "\n\t dev.: " + statOutput(df, testingFMeasureDev, "%") + + "\n\t max.: " + statOutput(df, testingFMeasureMax, "%") + + "\n\t min.: " + statOutput(df, testingFMeasureMin, "%")); + + + //this is for copying to word document + //f-measure, accuracy, correctness, completeness, avg pdef length, no of pdef, time, no of des, no of cpdef + outputWriter("***without fortify (f-measure, accuracy, correctness, completeness, avg. pdef length)***\n" + + df.format(testingFMeasureAvg.getMean()) + "\n" + df.format(testingFMeasureDev.getMean())+ "\n" + + df.format(testingAccAvg.getMean()) + "\n" + df.format(testingAccDev.getMean()) + "\n" + + df.format(testingCorAvg.getMean()) + "\n" + df.format(testingCorDev.getMean()) + "\n" + + df.format(testingComAvg.getMean()) + "\n" + df.format(testingComDev.getMean()) + "\n" + + df.format(avgPartialDefLenAvg.getMean()) + "\n" + df.format(avgPartialDefLenDev.getMean()) + "\n"); + + + outputWriter("***with fortify 1 (f-measure, accuracy, correctness, completeness)***\n" + + df.format(fortify1FmeasureAvg.getMean()) + "\n" + df.format(fortify1FmeasureDev.getMean()) + "\n" + + df.format(fortify1AccAvg.getMean()) + "\n" + df.format(fortify1AccDev.getMean()) + "\n" + + df.format(fortify1CorAvg.getMean()) + "\n" + df.format(fortify1CorDev.getMean()) + "\n" + + df.format(testingComAvg.getMean()) + "\n" + df.format(testingComDev.getMean()) + "\n" + + df.format(avgFortifiedPartialDefLenAvg.getMean()) + "\n" + df.format(avgFortifiedPartialDefLenDev.getMean()) + "\n"); + + outputWriter("***Common dimensions (no of pdef., learning time, no of des., no of cpdef., avg. no of fdef.)***\n" + + df.format(noOfPartialDefAvg.getMean()) + "\n" + df.format(noOfPartialDefDev.getMean()) + "\n" + + df.format(learningTime.getMean()) + "\n" + df.format(learningTime.getStandardDeviation()) + "\n" + + df.format(noOfDescriptionsAgv.getMean()) + "\n" + df.format(noOfDescriptionsDev.getMean()) + "\n" + + df.format(noOfCounterPartialDefinitionsAvg.getMean()) + "\n" + df.format(noOfCounterPartialDefinitionsDev.getMean()) + "\n" + + df.format(avgNoOfFortifiedDefinitions.getMean()) + "\n" + df.format(avgNoOfFortifiedDefinitions.getStandardDeviation()) + "\n" + ); + + + outputWriter("***with fortify 2 (f-measure, accuracy, correctness, completeness, avg. fortified pdef length)***\n" + + df.format(fortify2FmeasureAvg.getMean()) + "\n" + df.format(fortify2FmeasureDev.getMean()) + "\n" + + df.format(fortify2AccAvg.getMean()) + "\n" + df.format(fortify2AccDev.getMean()) + "\n" + + df.format(fortify2CorAvg.getMean()) + "\n" + df.format(fortify2CorDev.getMean()) + "\n" + + df.format(fortify2ComAvg.getMean()) + "\n" + df.format(fortify2ComDev.getMean()) + "\n" + + df.format(avgFortifiedPartialDefLenAvg.getMean()) + "\n" + df.format(avgFortifiedPartialDefLenDev.getMean()) + "\n"); + } + + if (la instanceof ParCELExAbstract) + outputWriter("terminated by: partial def.: " + terminatedBypartialDefinition + "; counter partial def.: " + terminatedByCounterPartialDefinitions); + + + //reset the set of positive and negative examples for the learning problem for further experiment if any + lp.setPositiveExamples(posExamples); + lp.setNegativeExamples(negExamples); + + + } //constructor + + + /* + private String getOrderUnit(int order) { + switch (order) { + case 1: return "st"; + case 2: return "nd"; + case 3: return "rd"; + default: return "th"; + } + } + */ + + @Override + protected void outputWriter(String output) { + logger.info(output); + + if (writeToFile) + Files.appendToFile(outputFile, output + "\n"); + } +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation3Phases.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation3Phases.java new file mode 100644 index 0000000000..49104422f4 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExFortifiedCrossValidation3Phases.java @@ -0,0 +1,2165 @@ +package org.dllearner.cli.parcel; + +import java.text.DecimalFormat; +import java.util.*; + +import com.clarkparsia.pellet.owlapiv3.PelletReasoner; +import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory; +import com.google.common.collect.Sets; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.algorithms.parcel.celoe.CELOEPartial; +import org.dllearner.algorithms.parcelex.ParCELExAbstract; +import org.dllearner.cli.CrossValidation; +import org.dllearner.cli.parcel.fortification.FortificationUtils; +import org.dllearner.cli.parcel.fortification.JaccardSimilarity; +import org.dllearner.core.AbstractCELA; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentInitException; +import org.dllearner.kb.OWLFile; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.dllearner.utilities.statistics.Stat; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.*; + +/** + * Add PDLL cross validation support to Jens Lehmann work ( + * {@link CrossValidation}). In this cross validation, + * some more addition dimensions will be investigated such as: + * number partial definitions, partial definition length, etc. + * + * + * @author actran + * + */ + +public class ParCELExFortifiedCrossValidation3Phases extends CrossValidation { + + //pdef + private Stat noOfPdefStat; + private Stat noOfUsedPdefStat; + private Stat avgUsedPartialDefinitionLengthStat; + + //cpdef + private Stat noOfCpdefStat; + private Stat noOfCpdefUsedStat; + private Stat avgCpdefLengthStat; + private Stat totalCPDefLengthStat; + private Stat avgCpdefCoverageTrainingStat; + + + //learning time + private Stat learningTime; + + + //fortify strategy statistical variables + /* + private Stat accuracyFortifyStat; + private Stat correctnessFortifyStat; + private Stat completenessFortifyStat; + private Stat fmeasureFortifyStat; + //private Stat avgFortifiedPartialDefinitionLengthStat; + */ + + + //blind fortification + private Stat accuracyBlindFortifyStat; + private Stat correctnessBlindFortifyStat; + private Stat completenessBlindFortifyStat; + private Stat fmeasureBlindFortifyStat; + + + //labeled fortification + private Stat labelFortifyCpdefTrainingCoverageStat; + private Stat noOfLabelFortifySelectedCpdefStat; + private Stat avgLabelCpdefLengthStat; + private Stat labelFortifiedDefinitionLengthStat; + private Stat accuracyLabelFortifyStat; + private Stat correctnessLabelFortifyStat; + private Stat completenessLabelFortifyStat; + private Stat fmeasureLabelFortifyStat; + + + + //multi-step fortification + protected Stat[][] accuracyPercentageFortifyStepStat; //hold the fortified accuracy at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] completenessPercentageFortifyStepStat; //hold the fortified completeness at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] correctnessPercentageFortifyStepStat; //hold the fortified correctness at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] fmeasurePercentageFortifyStepStat; //hold the fortified correctness at 5,10,20,30,40,50% (multi-strategies) + + protected Stat[] noOfCpdefUsedMultiStepFortStat; + + + protected double[][] accuracyHalfFullStep; + protected double[][] fmeasureHalfFullStep; + + protected Stat[][] accuracyFullStepStat; + protected Stat[][] fmeasureFullStepStat; + protected Stat[][] correctnessFullStepStat; + protected Stat[][] completenessFullStepStat; + + + Logger logger = Logger.getLogger(this.getClass()); + + protected boolean interupted = false; + + /** + * Default constructor + */ + + public ParCELExFortifiedCrossValidation3Phases(AbstractCELA la, PosNegLP lp, AbstractReasonerComponent rs, + int folds, boolean leaveOneOut, int noOfRuns) { + super(la, lp, rs, folds, leaveOneOut); // TODO nrOfRuns not available in CV class + } + + /** + * This is for PDLL cross validation + * + * @param la + * @param lp + * @param rs + * @param folds + * @param leaveOneOut + * @param noOfRuns Number of k-fold runs, i.e. the validation will run kk times of k-fold validations + */ + public ParCELExFortifiedCrossValidation3Phases(AbstractCELA la, ParCELPosNegLP lp, AbstractReasonerComponent rs, + int folds, boolean leaveOneOut, int noOfRuns) { + + super(); // do nothing + + //-------------------------- + //setting up + //-------------------------- + DecimalFormat df = new DecimalFormat(); + + // the training and test sets used later on + List> trainingSetsPos = new LinkedList<>(); + List> trainingSetsNeg = new LinkedList<>(); + List> testSetsPos = new LinkedList<>(); + List> testSetsNeg = new LinkedList<>(); + List> fortificationSetsPos = new LinkedList<>(); + List> fortificationSetsNeg = new LinkedList<>(); + + + // get examples and shuffle them too + Set posExamples = lp.getPositiveExamples(); + List posExamplesList = new LinkedList<>(posExamples); + //Collections.shuffle(posExamplesList, new Random(1)); + Set negExamples = lp.getNegativeExamples(); + List negExamplesList = new LinkedList<>(negExamples); + //Collections.shuffle(negExamplesList, new Random(2)); + + String baseURI = rs.getBaseURI(); + Map prefixes = rs.getPrefixes(); + + //---------------------- + //end of setting up + //---------------------- + + // sanity check whether nr. of folds makes sense for this benchmark + if(!leaveOneOut && (posExamples.size() testPos = getTestingSet(posExamplesList, splitsPos, i); + Set testNeg = getTestingSet(negExamplesList, splitsNeg, i); + testSetsPos.add(i, testPos); + testSetsNeg.add(i, testNeg); + + //fortification training sets + Set fortPos = getTestingSet(posExamplesList, splitsPos, (i+1) % folds); + Set fortNeg = getTestingSet(negExamplesList, splitsNeg, (i+1) % folds); + fortificationSetsPos.add(i, fortPos); + fortificationSetsNeg.add(i, fortNeg); + + //training sets + Set trainingPos = getTrainingSet(posExamples, testPos); + Set trainingNeg = getTrainingSet(negExamples, testNeg); + + trainingPos.removeAll(fortPos); + trainingNeg.removeAll(fortNeg); + + trainingSetsPos.add(i, trainingPos); + trainingSetsNeg.add(i, trainingNeg); + } + + + + // run the algorithm + int terminatedBypartialDefinition=0, terminatedByCounterPartialDefinitions=0; + + //--------------------------------- + //k-fold cross validation + //--------------------------------- + + Stat runtimeAvg = new Stat(); + Stat runtimeMax = new Stat(); + Stat runtimeMin = new Stat(); + Stat runtimeDev = new Stat(); + + Stat learningTimeAvg = new Stat(); + Stat learningTimeMax = new Stat(); + Stat learningTimeMin = new Stat(); + Stat learningTimeDev = new Stat(); + + Stat noOfPartialDefAvg = new Stat(); + Stat noOfPartialDefDev = new Stat(); + Stat noOfPartialDefMax = new Stat(); + Stat noOfPartialDefMin = new Stat(); + + Stat avgPartialDefLenAvg = new Stat(); + Stat avgPartialDefLenDev = new Stat(); + Stat avgPartialDefLenMax = new Stat(); + Stat avgPartialDefLenMin = new Stat(); + + Stat avgFortifiedPartialDefLenAvg = new Stat(); + Stat avgFortifiedPartialDefLenDev = new Stat(); + Stat avgFortifiedPartialDefLenMax = new Stat(); + Stat avgFortifiedPartialDefLenMin = new Stat(); + + Stat defLenAvg = new Stat(); + Stat defLenDev = new Stat(); + Stat defLenMax = new Stat(); + Stat defLenMin = new Stat(); + + Stat trainingAccAvg = new Stat(); + Stat trainingAccDev= new Stat(); + Stat trainingAccMax = new Stat(); + Stat trainingAccMin = new Stat(); + + Stat trainingCorAvg = new Stat(); + Stat trainingCorDev = new Stat(); + Stat trainingCorMax = new Stat(); + Stat trainingCorMin = new Stat(); + + Stat trainingComAvg = new Stat(); + Stat trainingComDev = new Stat(); + Stat trainingComMax = new Stat(); + Stat trainingComMin = new Stat(); + + Stat testingAccAvg = new Stat(); + Stat testingAccMax = new Stat(); + Stat testingAccMin = new Stat(); + Stat testingAccDev = new Stat(); + + Stat fortifyAccAvg = new Stat(); + Stat fortifyAccMax = new Stat(); + Stat fortifyAccMin = new Stat(); + Stat fortifyAccDev = new Stat(); + + + Stat testingCorAvg = new Stat(); + Stat testingCorMax = new Stat(); + Stat testingCorMin = new Stat(); + Stat testingCorDev = new Stat(); + + Stat fortifyCorAvg = new Stat(); + Stat fortifyCorMax = new Stat(); + Stat fortifyCorMin = new Stat(); + Stat fortifyCorDev = new Stat(); + + Stat testingComAvg = new Stat(); + Stat testingComMax = new Stat(); + Stat testingComMin = new Stat(); + Stat testingComDev = new Stat(); + + Stat fortifyComAvg = new Stat(); + Stat fortifyComMax = new Stat(); + Stat fortifyComMin = new Stat(); + Stat fortifyComDev = new Stat(); + + + Stat testingFMeasureAvg = new Stat(); + Stat testingFMeasureMax = new Stat(); + Stat testingFMeasureMin = new Stat(); + Stat testingFMeasureDev = new Stat(); + + Stat trainingFMeasureAvg = new Stat(); + Stat trainingFMeasureMax = new Stat(); + Stat trainingFMeasureMin = new Stat(); + Stat trainingFMeasureDev = new Stat(); + + Stat fortifyFmeasureAvg = new Stat(); + Stat fortifyFmeasureMax = new Stat(); + Stat fortifyFmeasureMin = new Stat(); + Stat fortifyFmeasureDev = new Stat(); + + + Stat noOfDescriptionsAgv = new Stat(); + Stat noOfDescriptionsMax = new Stat(); + Stat noOfDescriptionsMin = new Stat(); + Stat noOfDescriptionsDev = new Stat(); + + Stat noOfCounterPartialDefinitionsAvg = new Stat(); + Stat noOfCounterPartialDefinitionsDev = new Stat(); + Stat noOfCounterPartialDefinitionsMax = new Stat(); + Stat noOfCounterPartialDefinitionsMin = new Stat(); + + Stat noOfCounterPartialDefinitionsUsedAvg = new Stat(); + Stat noOfCounterPartialDefinitionsUsedDev = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMax = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMin = new Stat(); + + + /* + long orthAllCheckCountFold[] = new long[5]; + long orthSelectedCheckCountFold[] = new long[5]; + + long orthAllCheckCountTotal[] = new long[5]; + long orthSelectedCheckCountTotal[] = new long[5]; + + + orthAllCheckCountTotal[0] = orthAllCheckCountTotal[1] = orthAllCheckCountTotal[2] = + orthAllCheckCountTotal[3] = orthAllCheckCountTotal[4] = 0; + + orthSelectedCheckCountTotal[0] = orthSelectedCheckCountTotal[1] = orthSelectedCheckCountTotal[2] = + orthSelectedCheckCountTotal[3] = orthSelectedCheckCountTotal[4] = 0; + */ + + + //---------------------------------------------------------------------- + //loading ontology into Pellet reasoner for checking + //the orthogonality and satisfiability (fortification training strategy) + //---------------------------------------------------------------------- + long ontologyLoadStarttime = System.nanoTime(); + OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); + OWLOntology ontology = ((OWLFile)la.getReasoner().getSources().iterator().next()).createOWLOntology(manager); + outputWriter("Ontology created, axiom count: " + ontology.getAxiomCount()); + PelletReasoner pelletReasoner = PelletReasonerFactory.getInstance().createReasoner(ontology); + outputWriter("Pellet creared and binded with the ontology: " + pelletReasoner.getReasonerName()); + long ontologyLoadDuration = System.nanoTime() - ontologyLoadStarttime; + outputWriter("Total time for creating and binding ontology: " + ontologyLoadDuration/1000000000d + "ms"); + + OWLDataFactory dataFactory = OWLManager.getOWLDataFactory(); + + + for (int kk=0; kk < noOfRuns; kk++) { + + //general statistics + runtime = new Stat(); + learningTime = new Stat(); + length = new Stat(); + totalNumberOfDescriptions = new Stat(); + + + //pdef + noOfPdefStat = new Stat(); + noOfUsedPdefStat = new Stat(); + avgUsedPartialDefinitionLengthStat = new Stat(); + + //cpdef + noOfCpdefStat = new Stat(); + noOfCpdefUsedStat = new Stat(); + totalCPDefLengthStat = new Stat(); + avgCpdefLengthStat = new Stat(); + avgCpdefCoverageTrainingStat = new Stat(); + + + //training + accuracyTraining = new Stat(); + trainingCorrectnessStat= new Stat(); + trainingCompletenessStat = new Stat(); + fMeasureTraining = new Stat(); + + //test + accuracy = new Stat(); + fMeasure = new Stat(); + testingCorrectnessStat = new Stat(); + testingCompletenessStat = new Stat(); + + + //blind fortification + accuracyBlindFortifyStat = new Stat(); + correctnessBlindFortifyStat = new Stat(); + completenessBlindFortifyStat = new Stat(); + fmeasureBlindFortifyStat = new Stat(); + + + //labled fortification + labelFortifyCpdefTrainingCoverageStat = new Stat(); + noOfLabelFortifySelectedCpdefStat = new Stat(); + avgLabelCpdefLengthStat = new Stat(); + labelFortifiedDefinitionLengthStat = new Stat(); + accuracyLabelFortifyStat = new Stat(); + correctnessLabelFortifyStat= new Stat(); + completenessLabelFortifyStat = new Stat(); + fmeasureLabelFortifyStat = new Stat(); + + + int noOfStrategies = FortificationUtils.strategyNames.length; + + + //fortification accuracy + accuracyPercentageFortifyStepStat = new Stat[noOfStrategies][6]; //6 elements for six values of 5%, 10%, ..., 50% + completenessPercentageFortifyStepStat = new Stat[noOfStrategies][6]; + correctnessPercentageFortifyStepStat = new Stat[noOfStrategies][6]; + fmeasurePercentageFortifyStepStat = new Stat[noOfStrategies][6]; + + + //initial fortification accuracy by PERCENTAGE + for (int i=0; i partialDefinitions = parcelEx.getReducedPartialDefinition(); + long noOfPdef = parcelEx.getNumberOfPartialDefinitions(); + long noOfUsedPdef = parcelEx.getNoOfReducedPartialDefinition(); + double avgPdefLength = conceptLength / (double)noOfUsedPdef; + noOfPdefStat.addNumber(noOfPdef); + noOfUsedPdefStat.addNumber(noOfUsedPdef); + avgUsedPartialDefinitionLengthStat.addNumber(avgPdefLength); + + //descriptions + totalNumberOfDescriptions.addNumber(parcelEx.getTotalNumberOfDescriptionsGenerated()); + + + //print the coverage of the counter partial definitions + outputWriter("Number of counter partial definitions: " + noOfCpdef); + + + //-------------------------------------- + //get the COUNTER PARTIAL DEFINITIONs + //-------------------------------------- + //sorted by training coverage by default + TreeSet counterPartialDefinitions = new TreeSet<>(new FortificationUtils.CoverageComparator()); + + //------------------------------- + //training sets + //------------------------------- + Set curFoldPosTrainingSet = trainingSetsPos.get(currFold); + Set curFoldNegTrainingSet = trainingSetsNeg.get(currFold); + + int trainingPosSize = curFoldPosTrainingSet.size() ; + int trainingNegSize = curFoldNegTrainingSet.size(); + + + //----------------------- + // 2. Check if any CPDEFs generated + // Note that this algorithm generate both pdefs and cpdef + // However, sometime there is no cpdef as the definition had been found "too" fast + // Therefore, we will reverse training set to produce some cpdef if necessary + //----------------------- + + if (noOfCpdef < 5) { + //================================================================ + //2. Phase 2: Learn Counter Partial Definitions + // Reverse the pos/neg and let the learner start + //================================================================ + + outputWriter("* Number of counter partial definitions is too small, reverse the examples and learn again!!!"); + + //reverse the pos/neg examples + lp.setPositiveExamples(trainingSetsNeg.get(currFold)); + lp.setNegativeExamples(trainingSetsPos.get(currFold)); + + //re-initialize the learner + try { + lp.init(); + la.init(); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + + outputWriter("\n** Phase 2 - Learning COUNTER PARTIAL DEFINITIONS"); + outputWriter("Timeout=" + ((ParCELExAbstract)la).getMaxExecutionTimeInSeconds() + "s"); + + //start the learner + long algorithmStartTime1 = System.nanoTime(); + try { + la.start(); + } + catch (OutOfMemoryError e) { + System.out.println("out of memory at " + (System.currentTimeMillis() - algorithmStartTime1)/1000 + "s"); + } + + + + //calculate the counter partial definitions' avg. coverage + //(note that the positive and negative examples are swapped) + for (ParCELExtraNode cpdef : ((ParCELExAbstract)la).getPartialDefinitions()) { + + int trainingCp = cpdef.getCoveredPositiveExamples().size(); //positive examples of cpdef is the + + counterPartialDefinitions.add(new CELOEPartial.PartialDefinition( dataFactory.getOWLObjectComplementOf(cpdef.getDescription()), trainingCp)); + + avgCpdefCoverageTrainingStat.addNumber(trainingCp/(double)trainingSetsNeg.get(currFold).size()); + } + + outputWriter("Finish learning, number of counter partial definitions: " + counterPartialDefinitions.size()); + } + else { + //calculate the counter partial definitions' avg coverage + for (ParCELExtraNode cpdef : parcelEx.getCounterPartialDefinitions()) { + + int trainingCn = cpdef.getCoveredNegativeExamples().size(); + + counterPartialDefinitions.add(new CELOEPartial.PartialDefinition(cpdef.getDescription(), trainingCn)); + + avgCpdefCoverageTrainingStat.addNumber(trainingCn/(double)trainingPosSize); + } + + } + + + outputWriter("------------------------------"); + + + //----------------------------- + //TRAINING accuracy + //----------------------------- + + //cp, cn of training sets + Set cpTraining = rs.hasType(concept, trainingSetsPos.get(currFold)); //positive examples covered by the learned concept + //Set upTraining = Helper.difference(trainingSetsPos.get(currFold), cpTraining); //false negative (pos as neg) + Set cnTraining = rs.hasType(concept, trainingSetsNeg.get(currFold)); //false positive (neg as pos) + + + //training completeness, correctness and accuracy + int trainingCorrectPosClassified = cpTraining.size(); + int trainingCorrectNegClassified = trainingNegSize - cnTraining.size(); //getCorrectNegClassified(rs, concept, trainingSetsNeg.get(currFold)); + int trainingCorrectExamples = trainingCorrectPosClassified + trainingCorrectNegClassified; + + double trainingAccuracy = 100*((double)trainingCorrectExamples/(trainingPosSize + trainingNegSize)); + double trainingCompleteness = 100*(double)trainingCorrectPosClassified/trainingPosSize; + double trainingCorrectness = 100*(double)trainingCorrectNegClassified/trainingNegSize; + + accuracyTraining.addNumber(trainingAccuracy); + trainingCompletenessStat.addNumber(trainingCompleteness); + trainingCorrectnessStat.addNumber(trainingCorrectness); + + //training F-Measure + int negAsPosTraining = cnTraining.size(); + double precisionTraining = (trainingCorrectPosClassified + negAsPosTraining) == 0 ? + 0 : trainingCorrectPosClassified / (double) (trainingCorrectPosClassified + negAsPosTraining); + double recallTraining = trainingCorrectPosClassified / (double) trainingPosSize; + double currFmeasureTraining = 100 * Heuristics.getFScore(recallTraining, precisionTraining); + fMeasureTraining.addNumber(currFmeasureTraining); + + + + //---------------------- + //TEST accuracy + //---------------------- + + //calculate the coverage + Set curFoldPosTestSet = testSetsPos.get(currFold); + Set curFoldNegTestSet = testSetsNeg.get(currFold); + + int testingPosSize = curFoldPosTestSet.size(); + int testingNegSize = curFoldNegTestSet.size(); + + Set cpTest = rs.hasType(concept, curFoldPosTestSet); //positive examples covered by the learned concept + Set upTest = Sets.difference(curFoldPosTestSet, cpTest); //false negative (pos as neg) + Set cnTest = rs.hasType(concept, curFoldNegTestSet); //false positive (neg as pos) + + + //calculate test accuracies + int correctTestPosClassified = cpTest.size(); //covered pos. in test set + int correctTestNegClassified = testingNegSize - cnTest.size(); //uncovered neg in test set + int correctTestExamples = correctTestPosClassified + correctTestNegClassified; + + double testingCompleteness = 100*(double)correctTestPosClassified/testingPosSize; + double testingCorrectness = 100*(double)correctTestNegClassified/testingNegSize; + double currAccuracy = 100*((double)correctTestExamples/(testingPosSize + testingNegSize)); + + accuracy.addNumber(currAccuracy); + testingCompletenessStat.addNumber(testingCompleteness); + testingCorrectnessStat.addNumber(testingCorrectness); + + + //F-Measure test set + int negAsPos = cnTest.size(); + double testPrecision = correctTestPosClassified + negAsPos == 0 ? + 0 : correctTestPosClassified / (double) (correctTestPosClassified + negAsPos); + double testRecall = correctTestPosClassified / (double) testingPosSize; + double currFmeasureTest = 100 * Heuristics.getFScore(testRecall, testPrecision); + + fMeasure.addNumber(currFmeasureTest); + + + //================================================== + //FORTIFICATION + //================================================== + + FortificationUtils.FortificationResult[] multiStepFortificationResult = new FortificationUtils.FortificationResult[noOfStrategies]; + + + + //--------------------------------- + // Fortification - ALL CPDEFs + // (BLIND Fortification) + //--------------------------------- + //NOTE: + //Since this will iterate all cpdef, we will calculate score for all other fortification strategies + // training coverage (done), jaccard, fortification training, + + outputWriter("---------------------------------------------------------------"); + outputWriter("BLIND fortification - All counter partial defintions are used"); + outputWriter("---------------------------------------------------------------"); + + + //get the set of pos and neg (in the test set) covered by counter partial definition + Set cpdefPositiveCovered = new HashSet<>(); + Set cpdefNegativeCovered = new HashSet<>(); + + long totalCPDefLength = 0; + + + //--------------------------------------------------- + //variables for fortification training + //--------------------------------------------------- + + //fortification validation (FV) dataset + Set fortificationTrainingPos = fortificationSetsPos.get(currFold); + Set fortificationTrainingNeg= fortificationSetsNeg.get(currFold); + + Set allFortificationExamples = new HashSet<>(); + + allFortificationExamples.addAll(fortificationTrainingPos); + allFortificationExamples.addAll(fortificationTrainingNeg); //duplicate will be remove automatically + + + //New Jaccard Similarity + JaccardSimilarity newJaccardSimilarity = new JaccardSimilarity(pelletReasoner); + + + ///------------------------------------------------------------ + //start the BLIND fortification and + // calculate the scores for other methods (use a common loop) + //------------------------------------------------------------ + int tmp_id = 1; + int count = 1; + for (CELOEPartial.PartialDefinition negCpdef : counterPartialDefinitions) { + + //in parcelEx, the cpdefs are negated by default ==> remove negation before process them + OWLClassExpression cpdef = ((OWLObjectComplementOf)negCpdef.getDescription()).getOperand(); + + //assign id for cpdef for debugging purpose + negCpdef.setId("#" + tmp_id++); + + + //-------------------- + //BLIND fortification + //-------------------- + + //cp and cn of the current cpdef + Set cpdefCp = rs.hasType(cpdef, curFoldPosTestSet); + Set cpdefCn = rs.hasType(cpdef, curFoldNegTestSet); + + + //-------------------------------- + //Fortification Validation (FV) + //-------------------------------- + Set fortCp = rs.hasType(cpdef, fortificationTrainingPos); + Set fortCn = rs.hasType(cpdef, fortificationTrainingNeg); + + + Set conceptCp = rs.hasType(concept, fortificationTrainingPos); + Set conceptCn = rs.hasType(concept, fortificationTrainingNeg); + + int cp = fortCp.size(); + int cn = fortCn.size(); + + //these are used to compute common instances between cpdef and learnt concept + Set commonCp = new HashSet<>(); + Set commonCn = new HashSet<>(); + commonCp.addAll(fortCp); + commonCn.addAll(fortCn); + commonCp.removeAll(conceptCp); + commonCn.removeAll(conceptCn); + + double fortificationValidationScore = FortificationUtils.fortificationScore(pelletReasoner, cpdef, concept, + cp, cn, fortificationTrainingPos.size(), fortificationTrainingNeg.size(), + cp-commonCp.size(), cn-commonCn.size(), ((ParCELExAbstract)la).getMaximumHorizontalExpansion()); + + + //---------------------------- + //Overlap + Similarity Score + //---------------------------- + double overlapNeg = FortificationUtils.getConceptOverlapSimple(fortCn, conceptCn); + double overlapPos = FortificationUtils.getConceptOverlapSimple(fortCp, conceptCp); + + + //--------------- + //NEW- JACCARD + //--------------- + double newJaccardSimilarityScore = 0; + try { + newJaccardSimilarityScore = newJaccardSimilarity.getJaccardSimilarityComplex(concept, cpdef); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + double conceptOverlapSimilairtyScore = overlapNeg + newJaccardSimilarityScore; + + double similarityPosNegScore = overlapNeg - 0.5 * overlapPos; + + + //--------------------------- + //TRAINING COVERAGE Score + //--------------------------- + double trainingCoverageScore = cpdefCn.size()/(double)curFoldNegTrainingSet.size(); + + + //---------------------------------- + //Assign all scores to the CPDEF + //new scoring: 21/4/2013 + //---------------------------------- + double allScores = conceptOverlapSimilairtyScore + fortificationValidationScore + + trainingCoverageScore*0.5; + + double randomScore = new Random().nextDouble(); + + negCpdef.setAdditionValue(0, trainingCoverageScore); //no of neg. examples in training set covered by the cpdef + negCpdef.setAdditionValue(1, conceptOverlapSimilairtyScore); //can be used to infer jaccard overlap score + negCpdef.setAdditionValue(2, fortificationValidationScore); //fortification validation strategy + negCpdef.setAdditionValue(3, similarityPosNegScore); + negCpdef.setAdditionValue(4, newJaccardSimilarityScore); + negCpdef.setAdditionValue(5, allScores); + negCpdef.setAdditionValue(6, randomScore); + + + //------------------------ + //BLIND fortification + //------------------------ + boolean cpChanged = cpdefPositiveCovered.addAll(cpdefCp); + boolean cnChanged = cpdefNegativeCovered.addAll(cpdefCn); + + cpdefPositiveCovered.addAll(cpdefCp); + cpdefNegativeCovered.addAll(cpdefCn); + + + totalCPDefLength += OWLClassExpressionUtils.getLength(cpdef); + + String changed = ""; + if (cpChanged || cnChanged) { + changed = "(" + (cpChanged?"-":"") + (cnChanged?"+":"") + ")"; + + outputWriter(count++ + changed + ". " + FortificationUtils.getCpdefString(negCpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef, curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef, curFoldNegTestSet)); + } + else if (logger.isDebugEnabled()) { + logger.debug(count++ + changed + ". " + FortificationUtils.getCpdefString(negCpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef, curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef, curFoldNegTestSet)); + } + /* + if (cpChanged || cnChanged) + changed = "(" + (cpChanged?"-":"") + (cnChanged?"+":"") + ")"; + + outputWriter(count++ + changed + ". " + FortificationUtils.getCpdefString(negCpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef, curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef, curFoldNegTestSet)); + */ + } + + outputWriter( " * Blind fortifcation summary: cp=" + cpdefPositiveCovered + " --- cn=" + cpdefNegativeCovered); + + + outputWriter("test set errors pos (" + upTest.size() + "): " + upTest); + outputWriter("test set errors neg (" + cnTest.size() + "): " + cnTest); + + //----------------------------------------- + //calculate BLIND fortification accuracy + //----------------------------------------- + + //fortify definition length: total length of all cpdef + totalCPDefLengthStat.addNumber(totalCPDefLength); + double avgCPDefLength = totalCPDefLength/(double)counterPartialDefinitions.size(); + avgCpdefLengthStat.addNumber(avgCPDefLength); + + //accuracy, completeness, correctness + int oldSizePosFort = cpdefPositiveCovered.size(); + int oldSizeNegFort = cpdefNegativeCovered.size(); + + cpdefPositiveCovered.removeAll(cpTest); + cpdefNegativeCovered.removeAll(cnTest); + + int commonPos = oldSizePosFort - cpdefPositiveCovered.size(); + int commonNeg = oldSizeNegFort - cpdefNegativeCovered.size(); + + + int cpFort = cpTest.size() - commonPos; //positive examples covered by fortified definition + int cnFort = cnTest.size() - commonNeg; //negative examples covered by fortified definition + + //correctness = un/negSize + double blindFortificationCorrectness = 100 * (curFoldNegTestSet.size() - cnFort)/(double)(curFoldNegTestSet.size()); + + //completeness = cp/posSize + double blindFortificationCompleteness = 100 * (cpFort)/(double)curFoldPosTestSet.size(); + + //accuracy = (cp + un)/(pos + neg) + double blindFortificationAccuracy = 100 * (cpFort + (curFoldNegTestSet.size() - cnFort))/ + (double)(curFoldPosTestSet.size() + curFoldNegTestSet.size()); + + //precision = right positive classified / total positive classified + // = cp / (cp + negAsPos) + double blindPrecission = (cpFort + cnFort) == 0 ? 0 : cpFort / (double)(cpFort + cnFort); + + //recall = right positive classified / total positive + double blindRecall = cpFort / (double)curFoldPosTestSet.size(); + + double blindFmeasure = 100 * Heuristics.getFScore(blindRecall, blindPrecission); + + //STAT values for Blind fortification + correctnessBlindFortifyStat.addNumber(blindFortificationCorrectness); + completenessBlindFortifyStat.addNumber(blindFortificationCompleteness); + accuracyBlindFortifyStat.addNumber(blindFortificationAccuracy); + fmeasureBlindFortifyStat.addNumber(blindFmeasure); + + //---------------------------------- + //end of blind fortification + //---------------------------------- + + //======================================================== + // process other fortification strategies (except BLIND) + //======================================================== + + + + + int INDEX; + + //--------------------------------------- + /// 1. Fortification - TRAINGING COVERAGE + //--------------------------------------- + outputWriter("---------------------------------------------"); + outputWriter("Fortification - TRAINGING COVERAGE"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.TRAINING_COVERAGE_INDEX; + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, counterPartialDefinitions, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + /* error: minCpdef has not assigned the value + for (int i=0; i similarityAndOverlapCpdef = new TreeSet<>(new FortificationUtils.AdditionalValueComparator(1)); + similarityAndOverlapCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, similarityAndOverlapCpdef, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + /* error: minCpdef has not assigned the value + for (int i=0; i< minCpdef; i++) { + outputWriter((i+1) + ": " + multiStepFortificationResult[INDEX].fortificationAccuracyStepByStep[i] + + "\t" + multiStepFortificationResult[INDEX].fortificationCorrectnessStepByStep[i] + + "\t" + multiStepFortificationResult[INDEX].fortificationCompletenessStepByStep[i] + ); + } + */ + + //------------------------------------------------ + /// 3. Fortification - FORTIFICATION VALIDATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - FORTIFICATION VALIDATION"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.FORTIFICATION_VALIDATION_INDEX; + + SortedSet fortificationValidationCpdef = new TreeSet<>(new FortificationUtils.AdditionalValueComparator(2)); + fortificationValidationCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, fortificationValidationCpdef, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 4. Fortification - SIMILARITY NEG-POS + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - SIMILARITY NEG-POS"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.SIMILARITY_POS_NEG_INDEX; + + SortedSet similarityNegPosCpdef = new TreeSet<>(new FortificationUtils.AdditionalValueComparator(3)); + similarityNegPosCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, similarityNegPosCpdef, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 5. Fortification - JACCARD OVERLAP + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - JACCARD OVERLAP"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.NEW_JACCARD_OVERLAP_INDEX; + + SortedSet jaccardOverlapCpdef = new TreeSet<>(new FortificationUtils.AdditionalValueComparator(4)); + jaccardOverlapCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, jaccardOverlapCpdef, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 6. Fortification - JACCARD DISTANCE + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - JACCARD DISTANCE"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.NEW_JACCARD_DISTANCE_INDEX; + + SortedSet jaccardDistanceCpdef = new TreeSet<>(new FortificationUtils.AdditionalValueComparator(4, false)); + jaccardDistanceCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, jaccardDistanceCpdef, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + + //------------------------------------------------ + /// 7. Fortification - COMBINATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - COMBINATION SCORES"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.CONBINATION_INDEX; + + SortedSet combinationScoreCpdef = new TreeSet<>(new FortificationUtils.AdditionalValueComparator(5)); + combinationScoreCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, combinationScoreCpdef, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 7. Fortification - COMBINATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - RANDOM"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.RANDOM_INDEX; + + SortedSet randomCpdef = new TreeSet<>(new FortificationUtils.AdditionalValueComparator(6)); + randomCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, randomCpdef, curFoldPosTestSet, curFoldNegTestSet, true); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------ + // Fortification - LABEL DATA + // LABLED TEST DATA + //------------------------------ + //if there exists covered negative examples ==> check if there are any counter partial definitions + //can be used to remove covered negative examples + + int fixedNeg = 0; + int fixedPos = 0; + int noOfSelectedCpdef = 0; + int totalSelectedCpdefLength = 0; + double avgTrainingCoverageSelectedCpdef = 0; + + /** + * selected cpdef which are selected based on the test labled data + * given a set of wrong classified neg., select a set of cpdef to remove the wrong classified neg examples + * the cpdef are sorted based on the training neg. example coverage + */ + TreeSet selectedCounterPartialDefinitions = new TreeSet<>(new FortificationUtils.CoverageComparator()); + + if (cnTest.size() > 0) { + + TreeSet tempCoveredNeg = new TreeSet<>(); + tempCoveredNeg.addAll(cnTest); + + TreeSet tempUncoveredPos = new TreeSet<>(); + tempUncoveredPos.addAll(upTest); + + //check each counter partial definitions + for (CELOEPartial.PartialDefinition negCpdef : counterPartialDefinitions) { + + OWLClassExpression cpdef = ((OWLObjectComplementOf)negCpdef.getDescription()).getOperand(); + + //set of neg examples covered by the counter partial definition + Set desCoveredNeg = new HashSet<>(rs.hasType(cpdef, curFoldNegTestSet)); + + //if the current counter partial definition can help to remove some neg examples + //int oldNoOfCoveredNeg=tempCoveredNeg.size(); + if (tempCoveredNeg.removeAll(desCoveredNeg)) { + + //assign cn on test set to additionalValue + selectedCounterPartialDefinitions.add(negCpdef); + + //check if it may remove some positive examples or not + Set desCoveredPos = new HashSet<>(rs.hasType(cpdef, curFoldPosTestSet)); + tempUncoveredPos.addAll(desCoveredPos); + + //count the total number of counter partial definition selected and their total length + noOfSelectedCpdef++; + totalSelectedCpdefLength += OWLClassExpressionUtils.getLength(cpdef); + avgTrainingCoverageSelectedCpdef += negCpdef.getCoverage(); + } + + if (tempCoveredNeg.size() == 0) + break; + } + + fixedNeg = cnTest.size() - tempCoveredNeg.size(); + fixedPos = tempUncoveredPos.size() - upTest.size(); + avgTrainingCoverageSelectedCpdef /= noOfSelectedCpdef; + + + } + + noOfLabelFortifySelectedCpdefStat.addNumber(noOfSelectedCpdef); + labelFortifyCpdefTrainingCoverageStat.addNumber(avgTrainingCoverageSelectedCpdef); + + + //----------------------------- + // Labeled fortification + // stat calculation + //----------------------------- + + //def length + double labelFortifyDefinitionLength = OWLClassExpressionUtils.getLength(concept) + totalSelectedCpdefLength + noOfSelectedCpdef; //-1 from the selected cpdef and +1 for NOT + labelFortifiedDefinitionLengthStat.addNumber(labelFortifyDefinitionLength); + + double avgLabelFortifyDefinitionLength = 0; + + if (noOfSelectedCpdef > 0) { + avgLabelFortifyDefinitionLength = (double)totalSelectedCpdefLength/noOfSelectedCpdef; + avgLabelCpdefLengthStat.addNumber(totalSelectedCpdefLength/(double)noOfSelectedCpdef); + } + + //accuracy = test accuracy + fortification adjustment + double labelFortifyAccuracy = 100 * ((double)(correctTestExamples + fixedNeg - fixedPos)/ + (curFoldPosTestSet.size() + curFoldNegTestSet.size())); + accuracyLabelFortifyStat.addNumber(labelFortifyAccuracy); + + //completeness + double labelFortifyCompleteness = 100 * ((double)(correctTestPosClassified - fixedPos)/curFoldPosTestSet.size()); + completenessLabelFortifyStat.addNumber(labelFortifyCompleteness); + + //correctness + double labelFortifyCorrectness = 100 * ((double)(correctTestNegClassified + fixedNeg)/curFoldNegTestSet.size()); + correctnessLabelFortifyStat.addNumber(labelFortifyCorrectness); + + //precision, recall, f-measure + double labelFortifyPrecision = 0.0; //percent of correct pos examples in total pos examples classified (= correct pos classified + neg as pos) + if (((correctTestPosClassified - fixedPos) + (cnTest.size() - fixedNeg)) > 0) + labelFortifyPrecision = (double)(correctTestPosClassified - fixedPos)/ + (correctTestPosClassified - fixedPos + cnTest.size() - fixedNeg); //tmp3: neg as pos <=> false pos + + double labelFortifyRecall = (double)(correctTestPosClassified - fixedPos) / curFoldPosTestSet.size(); + + double labelFortifyFmeasure = 100 * Heuristics.getFScore(labelFortifyRecall, labelFortifyPrecision); + fmeasureLabelFortifyStat.addNumber(labelFortifyFmeasure); + + + + outputWriter("---------------------------------------------"); + outputWriter("LABEL fortify counter partial definitions: "); + outputWriter("---------------------------------------------"); + count = 1; + //output the selected counter partial definition information + if (noOfSelectedCpdef > 0) { + for (CELOEPartial.PartialDefinition cpdef : selectedCounterPartialDefinitions) { + + outputWriter(count++ + cpdef.getId() + ". " + cpdef.getId() + " " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + } + + } + + + + outputWriter("----------------------"); + + int[] noOfCpdefMultiStep = FortificationUtils.getMultiStepFortificationStep(counterPartialDefinitions.size()); + + for (int i=0; i<6; i++) { + noOfCpdefUsedMultiStepFortStat[i].addNumber(noOfCpdefMultiStep[i]); + + //minimal value of 50% of the cpdef used in the fortification + //NOTE: no of cpdef descreases after added into other sets for fortification + // Cause has not been investigated + minOfHalfCpdef = (minOfHalfCpdef > noOfCpdefMultiStep[i])? noOfCpdefMultiStep[i] : minOfHalfCpdef; + + //minimal number of counter partial definitions till the current run + //the above problem happens for this case as well + minCpdef = (minCpdef > multiStepFortificationResult[i].fortificationAccuracyStepByStep.length)? + multiStepFortificationResult[i].fortificationAccuracyStepByStep.length : minCpdef; + } + + + //create data structure to hold the fortification result + if (currFold == 0) { //have not initiallised + accuracyHalfFullStep = new double[noOfStrategies][minOfHalfCpdef]; //4 strategies + fmeasureHalfFullStep = new double[noOfStrategies][minOfHalfCpdef]; + + accuracyFullStepStat = new Stat[noOfStrategies][minCpdef]; + fmeasureFullStepStat = new Stat[noOfStrategies][minCpdef]; + correctnessFullStepStat = new Stat[noOfStrategies][minCpdef]; + completenessFullStepStat = new Stat[noOfStrategies][minCpdef]; + + //run a loop to create a set of Stat objects + for (int i=0; i < noOfStrategies; i++) { + for (int j = 0; j < minCpdef; j++) { + accuracyFullStepStat[i][j] = new Stat(); + fmeasureFullStepStat[i][j] = new Stat(); + correctnessFullStepStat[i][j] = new Stat(); + completenessFullStepStat[i][j] = new Stat(); + } + } + } + + + //sum up the accuracy and fmeasure directly, do not use Stat for simplicity + outputWriter("*** Calculate full step accuracy: minCpdef = " + minCpdef); + + outputWriter("\tcounter partial deifnition size=" + + counterPartialDefinitions.size()); + + //calculate accuracy, fmeasure of the cpdef HALF FULL STEP + for (int i=0; i 0) //this is for a weird side-affect of the floating point such that the getMax return a very small number >0 even if the acutuall value is zero + cutOffPoint = (int)Math.round(Math.ceil(noOfLabelFortifySelectedCpdefStat.getMax())); + + //outputWriter("\n CUT-OFF point computation: " + noOfLabelFortifySelectedCpdefStat.getMax()); + //outputWriter("\n test: " + Math.round(Math.ceil(noOfLabelFortifySelectedCpdefStat.getMean()))); + outputWriter("\n CUT-OFF point computation: " + cutOffPoint); + if (cutOffPoint == 0) { + outputWriter("\tNo fortifying definition is used, the accuracy is unchanged"); + outputWriter("\t\taccuracy: " + df.format(accuracy.getMean()) + ", " + df.format(accuracy.getStandardDeviation()) + + "; correctness: " + df.format(testingCorrectnessStat.getMean()) + ", " + df.format(testingCorrectnessStat.getStandardDeviation()) + + "; completeness: " + df.format(testingCompletenessStat.getMean()) + ", " + df.format(testingCompletenessStat.getStandardDeviation())); + } + else { + cutOffPoint--; + for (int i=0; i < noOfStrategies; i++) { + outputWriter("\t" + FortificationUtils.strategyNames[i] + ":"); + outputWriter("\t accuracy: " + df.format(accuracyFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(accuracyFullStepStat[i][cutOffPoint].getStandardDeviation()) + + "; correctness: " + df.format(correctnessFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(correctnessFullStepStat[i][cutOffPoint].getStandardDeviation()) + + "; completeness: " + df.format(completenessFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(completenessFullStepStat[i][cutOffPoint].getStandardDeviation()) + ); + /* + cutOffAvg[0][i] = accuracyFullStepStat[i][cutOffPoint].getMean(); + cutOffAvg[1][i] = correctnessFullStepStat[i][cutOffPoint].getMean(); + cutOffAvg[2][i] = completenessFullStepStat[i][cutOffPoint].getMean(); + + cutOffDev[0][i] = accuracyFullStepStat[i][cutOffPoint].getStandardDeviation(); + cutOffDev[1][i] = correctnessFullStepStat[i][cutOffPoint].getStandardDeviation(); + cutOffDev[2][i] = completenessFullStepStat[i][cutOffPoint].getStandardDeviation(); + */ + } + } + //end of cut-off point processing + + outputWriter(""); + + for (int i=0; i< noOfStrategies; i++) { + + outputWriter(" multi-step fortified accuracy by " + FortificationUtils.strategyNames[i] + ":"); + + outputWriter("\t 5%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][0], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][0], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][0], "%") + ); + outputWriter("\t 10%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][1], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][1], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][1], "%") + ); + outputWriter("\t 20%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][2], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][2], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][2], "%") + ); + outputWriter("\t 30%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][3], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][3], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][3], "%") + ); + outputWriter("\t 40%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][4], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][4], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][4], "%") + ); + outputWriter("\t 50%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][5], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][5], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][5], "%") + ); + + } + + //outputWriter(" total no of counter partial definition: " + statOutput(df, noOfCpdefStat, "")); + //outputWriter(" avg. no of counter partial definition used in label fortification: " + statOutput(df, noOfLabelFortifySelectedCpdefStat,"")); + + outputWriter(" no of cpdef used in multi-step fortification:"); + outputWriter("\t5%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[0], "")); + outputWriter("\t10%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[1], "")); + outputWriter("\t20%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[2], "")); + outputWriter("\t30%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[3], "")); + outputWriter("\t40%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[4], "")); + outputWriter("\t50%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[5], "")); + + + + //----------------------------------------- + //this is for copying to word document + //----------------------------------------- + outputWriter("======= RESULT SUMMARY PERCENTAGE (5%, 10%, 20%, 30%, 40%, 50%) ======="); + + //fmeasure + outputWriter("\n***f-measure test/blind"); + outputWriter(df.format(fMeasure.getMean()) + " " + df.format(fMeasure.getStandardDeviation()) + + "\n" + df.format(fmeasureBlindFortifyStat.getMean()) + " " + df.format(fmeasureBlindFortifyStat.getStandardDeviation()) + ); + + //for each strategy: strategy name, f-measure (5-50%) + for (int i=0; i 1) { + //runtime + runtimeAvg.addNumber(runtime.getMean()); + runtimeMax.addNumber(runtime.getMax()); + runtimeMin.addNumber(runtime.getMin()); + runtimeDev.addNumber(runtime.getStandardDeviation()); + + //learning time + learningTimeAvg.addNumber(learningTime.getMean()); + learningTimeDev.addNumber(learningTime.getStandardDeviation()); + learningTimeMax.addNumber(learningTime.getMax()); + learningTimeMin.addNumber(learningTime.getMin()); + + //number of partial definitions + noOfPartialDefAvg.addNumber(noOfPdefStat.getMean()); + noOfPartialDefMax.addNumber(noOfPdefStat.getMax()); + noOfPartialDefMin.addNumber(noOfPdefStat.getMin()); + noOfPartialDefDev.addNumber(noOfPdefStat.getStandardDeviation()); + + //avg partial definition length + avgPartialDefLenAvg.addNumber(avgUsedPartialDefinitionLengthStat.getMean()); + avgPartialDefLenMax.addNumber(avgUsedPartialDefinitionLengthStat.getMax()); + avgPartialDefLenMin.addNumber(avgUsedPartialDefinitionLengthStat.getMin()); + avgPartialDefLenDev.addNumber(avgUsedPartialDefinitionLengthStat.getStandardDeviation()); + + avgFortifiedPartialDefLenAvg.addNumber(labelFortifiedDefinitionLengthStat.getMean()); + avgFortifiedPartialDefLenMax.addNumber(labelFortifiedDefinitionLengthStat.getMax()); + avgFortifiedPartialDefLenMin.addNumber(labelFortifiedDefinitionLengthStat.getMin()); + avgFortifiedPartialDefLenDev.addNumber(labelFortifiedDefinitionLengthStat.getStandardDeviation()); + + + defLenAvg.addNumber(length.getMean()); + defLenMax.addNumber(length.getMax()); + defLenMin.addNumber(length.getMin()); + defLenDev.addNumber(length.getStandardDeviation()); + + //counter partial definitions + noOfCounterPartialDefinitionsAvg.addNumber(noOfCpdefStat.getMean()); + noOfCounterPartialDefinitionsDev.addNumber(noOfCpdefStat.getStandardDeviation()); + noOfCounterPartialDefinitionsMax.addNumber(noOfCpdefStat.getMax()); + noOfCounterPartialDefinitionsMin.addNumber(noOfCpdefStat.getMin()); + + noOfCounterPartialDefinitionsUsedAvg.addNumber(noOfCpdefUsedStat.getMean()); + noOfCounterPartialDefinitionsUsedDev.addNumber(noOfCpdefUsedStat.getStandardDeviation()); + noOfCounterPartialDefinitionsUsedMax.addNumber(noOfCpdefUsedStat.getMax()); + noOfCounterPartialDefinitionsUsedMin.addNumber(noOfCpdefUsedStat.getMin()); + + //training accuracy + trainingAccAvg.addNumber(accuracyTraining.getMean()); + trainingAccDev.addNumber(accuracyTraining.getStandardDeviation()); + trainingAccMax.addNumber(accuracyTraining.getMax()); + trainingAccMin.addNumber(accuracyTraining.getMin()); + + trainingCorAvg.addNumber(trainingCorrectnessStat.getMean()); + trainingCorDev.addNumber(trainingCorrectnessStat.getStandardDeviation()); + trainingCorMax.addNumber(trainingCorrectnessStat.getMax()); + trainingCorMin.addNumber(trainingCorrectnessStat.getMin()); + + trainingComAvg.addNumber(trainingCompletenessStat.getMean()); + trainingComDev.addNumber(trainingCompletenessStat.getStandardDeviation()); + trainingComMax.addNumber(trainingCompletenessStat.getMax()); + trainingComMin.addNumber(trainingCompletenessStat.getMin()); + + testingAccAvg.addNumber(accuracy.getMean()); + testingAccMax.addNumber(accuracy.getMax()); + testingAccMin.addNumber(accuracy.getMin()); + testingAccDev.addNumber(accuracy.getStandardDeviation()); + + //fortify accuracy + fortifyAccAvg.addNumber(accuracyLabelFortifyStat.getMean()); + fortifyAccMax.addNumber(accuracyLabelFortifyStat.getMax()); + fortifyAccMin.addNumber(accuracyLabelFortifyStat.getMin()); + fortifyAccDev.addNumber(accuracyLabelFortifyStat.getStandardDeviation()); + + + testingCorAvg.addNumber(testingCorrectnessStat.getMean()); + testingCorDev.addNumber(testingCorrectnessStat.getStandardDeviation()); + testingCorMax.addNumber(testingCorrectnessStat.getMax()); + testingCorMin.addNumber(testingCorrectnessStat.getMin()); + + //fortify correctness + fortifyCorAvg.addNumber(correctnessLabelFortifyStat.getMean()); + fortifyCorMax.addNumber(correctnessLabelFortifyStat.getMax()); + fortifyCorMin.addNumber(correctnessLabelFortifyStat.getMin()); + fortifyCorDev.addNumber(correctnessLabelFortifyStat.getStandardDeviation()); + + testingComAvg.addNumber(testingCompletenessStat.getMean()); + testingComDev.addNumber(testingCompletenessStat.getStandardDeviation()); + testingComMax.addNumber(testingCompletenessStat.getMax()); + testingComMin.addNumber(testingCompletenessStat.getMin()); + + //fortify completeness (level 1 fixing does not change the completeness + fortifyComAvg.addNumber(completenessLabelFortifyStat.getMean()); + fortifyComMax.addNumber(completenessLabelFortifyStat.getMax()); + fortifyComMin.addNumber(completenessLabelFortifyStat.getMin()); + fortifyComDev.addNumber(completenessLabelFortifyStat.getStandardDeviation()); + + + testingFMeasureAvg.addNumber(fMeasure.getMean()); + testingFMeasureDev.addNumber(fMeasure.getStandardDeviation()); + testingFMeasureMax.addNumber(fMeasure.getMax()); + testingFMeasureMin.addNumber(fMeasure.getMin()); + + trainingFMeasureAvg.addNumber(fMeasureTraining.getMean()); + trainingFMeasureDev.addNumber(fMeasureTraining.getStandardDeviation()); + trainingFMeasureMax.addNumber(fMeasureTraining.getMax()); + trainingFMeasureMin.addNumber(fMeasureTraining.getMin()); + + fortifyFmeasureAvg.addNumber(fmeasureLabelFortifyStat.getMean()); + fortifyFmeasureMax.addNumber(fmeasureLabelFortifyStat.getMax()); + fortifyFmeasureMin.addNumber(fmeasureLabelFortifyStat.getMin()); + fortifyFmeasureDev.addNumber(fmeasureLabelFortifyStat.getStandardDeviation()); + + noOfDescriptionsAgv.addNumber(totalNumberOfDescriptions.getMean()); + noOfDescriptionsMax.addNumber(totalNumberOfDescriptions.getMax()); + noOfDescriptionsMin.addNumber(totalNumberOfDescriptions.getMin()); + noOfDescriptionsDev.addNumber(totalNumberOfDescriptions.getStandardDeviation()); + } + + } //for kk folds + + if (noOfRuns > 1) { + + //TODO: this needs to be revised using a loop instead if multi-run is used + outputWriter(""); + outputWriter("Finished " + noOfRuns + " time(s) of the " + folds + "-folds cross-validations"); + + outputWriter("runtime: " + + "\n\t avg.: " + statOutput(df, runtimeAvg, "s") + + "\n\t dev.: " + statOutput(df, runtimeDev, "s") + + "\n\t max.: " + statOutput(df, runtimeMax, "s") + + "\n\t min.: " + statOutput(df, runtimeMin, "s")); + + outputWriter("learning time: " + + "\n\t avg.: " + statOutput(df, learningTimeAvg, "s") + + "\n\t dev.: " + statOutput(df, learningTimeDev, "s") + + "\n\t max.: " + statOutput(df, learningTimeMax, "s") + + "\n\t min.: " + statOutput(df, learningTimeMin, "s")); + + outputWriter("no of descriptions: " + + "\n\t avg.: " + statOutput(df, noOfDescriptionsAgv, "") + + "\n\t dev.: " + statOutput(df, noOfDescriptionsDev, "") + + "\n\t max.: " + statOutput(df, noOfDescriptionsMax, "") + + "\n\t min.: " + statOutput(df, noOfDescriptionsMin, "")); + + outputWriter("number of partial definitions: " + + "\n\t avg.: " + statOutput(df, noOfPartialDefAvg, "") + + "\n\t dev.: " + statOutput(df, noOfPartialDefDev, "") + + "\n\t max.: " + statOutput(df, noOfPartialDefMax, "") + + "\n\t min.: " + statOutput(df, noOfPartialDefMin, "")); + + outputWriter("avg. partial definition length: " + + "\n\t avg.: " + statOutput(df, avgPartialDefLenAvg, "") + + "\n\t dev.: " + statOutput(df, avgPartialDefLenDev, "") + + "\n\t max.: " + statOutput(df, avgPartialDefLenMax, "") + + "\n\t min.: " + statOutput(df, avgPartialDefLenMin, "")); + + outputWriter("definition length: " + + "\n\t avg.: " + statOutput(df, defLenAvg, "") + + "\n\t dev.: " + statOutput(df, defLenDev, "") + + "\n\t max.: " + statOutput(df, defLenMax, "") + + "\n\t min.: " + statOutput(df, defLenMin, "")); + + outputWriter("number of counter partial definitions: " + + "\n\t avg.: " + statOutput(df, noOfCounterPartialDefinitionsAvg, "") + + "\n\t dev.: " + statOutput(df, noOfCounterPartialDefinitionsDev, "") + + "\n\t max.: " + statOutput(df, noOfCounterPartialDefinitionsMax, "") + + "\n\t min.: " + statOutput(df, noOfCounterPartialDefinitionsMin, "")); + + outputWriter("number of counter partial definitions used: " + + "\n\t avg.: " + statOutput(df, noOfCounterPartialDefinitionsUsedAvg, "") + + "\n\t dev.: " + statOutput(df, noOfCounterPartialDefinitionsUsedDev, "") + + "\n\t max.: " + statOutput(df, noOfCounterPartialDefinitionsUsedMax, "") + + "\n\t min.: " + statOutput(df, noOfCounterPartialDefinitionsUsedMin, "")); + + outputWriter("accuracy on training set:" + + "\n\t avg.: " + statOutput(df, trainingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingAccDev, "%") + + "\n\t max.: " + statOutput(df, trainingAccMax, "%") + + "\n\t min.: " + statOutput(df, trainingAccMin, "%")); + + outputWriter("correctness on training set: " + + "\n\t avg.: " + statOutput(df, trainingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingCorDev, "%") + + "\n\t max.: " + statOutput(df, trainingCorMax, "%") + + "\n\t min.: " + statOutput(df, trainingCorMin, "%")); + + outputWriter("completeness on training set: " + + "\n\t avg.: " + statOutput(df, trainingComAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingCorDev, "%") + + "\n\t max.: " + statOutput(df, trainingComMax, "%") + + "\n\t min.: " + statOutput(df, trainingComMin, "%")); + + outputWriter("FMeasure on training set: " + + "\n\t avg.: " + statOutput(df, trainingFMeasureAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingFMeasureDev, "%") + + "\n\t max.: " + statOutput(df, trainingFMeasureMax, "%") + + "\n\t min.: " + statOutput(df, trainingFMeasureMin, "%")); + + outputWriter("accuracy on testing set: " + + "\n\t avg.: " + statOutput(df, testingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, testingAccDev, "%") + + "\n\t max.: " + statOutput(df, testingAccMax, "%") + + "\n\t min.: " + statOutput(df, testingAccMin, "%")); + + outputWriter("correctness on testing set: " + + "\n\t avg.: " + statOutput(df, testingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, testingCorDev, "%") + + "\n\t max.: " + statOutput(df, testingCorMax, "%") + + "\n\t min.: " + statOutput(df, testingCorMin, "%")); + + outputWriter("completeness on testing set: " + + "\n\t avg.: " + statOutput(df, testingComAvg, "%") + + "\n\t dev.: " + statOutput(df, testingComDev, "%") + + "\n\t max.: " + statOutput(df, testingComMax, "%") + + "\n\t min.: " + statOutput(df, testingComMin, "%")); + + outputWriter("FMeasure on testing set: " + + "\n\t avg.: " + statOutput(df, testingFMeasureAvg, "%") + + "\n\t dev.: " + statOutput(df, testingFMeasureDev, "%") + + "\n\t max.: " + statOutput(df, testingFMeasureMax, "%") + + "\n\t min.: " + statOutput(df, testingFMeasureMin, "%")); + + + } + + //if (la instanceof ParCELExAbstract) + // outputWriter("terminated by: partial def.: " + terminatedBypartialDefinition + "; counter partial def.: " + terminatedByCounterPartialDefinitions); + + + //reset the set of positive and negative examples for the learning problem for further experiment if any + lp.setPositiveExamples(posExamples); + lp.setNegativeExamples(negExamples); + + + } //constructor + +} + + diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExtraTestingNode.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExtraTestingNode.java new file mode 100644 index 0000000000..946621497b --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELExtraTestingNode.java @@ -0,0 +1,67 @@ +package org.dllearner.cli.parcel; + +import java.util.HashSet; +import java.util.Set; + +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.semanticweb.owlapi.model.OWLIndividual; + + +/** + * + * @author An C. Tran + * + */ +public class ParCELExtraTestingNode { + + protected ParCELExtraNode extraNode; + + protected Set coveredPositiveExamplesTestSet = new HashSet<>(); + protected Set coveredNegativeExamplestestSet = new HashSet<>(); + + + public ParCELExtraTestingNode(ParCELExtraNode node) { + extraNode = node; + } + + + public ParCELExtraTestingNode(ParCELExtraNode node, Set coveredPositiveExamplesTestSet, + Set coveredNegativeExamplesTestSet) { + this.extraNode = node; + this.coveredPositiveExamplesTestSet.addAll(coveredPositiveExamplesTestSet); + this.coveredNegativeExamplestestSet.addAll(coveredNegativeExamplesTestSet); + } + + + public ParCELExtraNode getExtraNode() { + return extraNode; + } + + + public void setExtraNode(ParCELExtraNode extraNode) { + this.extraNode = extraNode; + } + + + public Set getCoveredPositiveExamplesTestSet() { + return coveredPositiveExamplesTestSet; + } + + + public void setCoveredPositiveExamplesTestSet(Set coveredPositiveExamplesTestSet) { + this.coveredPositiveExamplesTestSet = coveredPositiveExamplesTestSet; + } + + + public Set getCoveredNegativeExamplestestSet() { + return coveredNegativeExamplestestSet; + } + + + public void setCoveredNegativeExamplestestSet(Set coveredNegativeExamplestestSet) { + this.coveredNegativeExamplestestSet = coveredNegativeExamplestestSet; + } + + + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELFortifiedCrossValidation3PhasesFair.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELFortifiedCrossValidation3PhasesFair.java new file mode 100644 index 0000000000..c36260f029 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELFortifiedCrossValidation3PhasesFair.java @@ -0,0 +1,2092 @@ +package org.dllearner.cli.parcel; + +import java.text.DecimalFormat; +import java.util.*; + +import com.google.common.collect.Sets; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.celoe.CELOEPartial; +import org.dllearner.cli.parcel.fortification.FortificationUtils; +import org.dllearner.cli.parcel.fortification.JaccardSimilarity; +import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.cli.CrossValidation; +import org.dllearner.core.ComponentInitException; +import org.dllearner.core.AbstractCELA; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.kb.OWLFile; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.dllearner.utilities.statistics.Stat; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyManager; + +import com.clarkparsia.pellet.owlapiv3.PelletReasoner; +import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory; + +/** + * Performs cross validation for the given problem. Supports k-fold cross-validation and + * leave-one-out cross-validation. + * + * @author Jens Lehmann + * + */ +public class ParCELFortifiedCrossValidation3PhasesFair extends CrossValidation { + + //pdef + protected Stat noOfPartialDefinitionStat; + protected Stat noOfReducedPartialDefinitionStat; + protected Stat avgPdefLengthStat; + + //cpdef + protected Stat noOfCounterPartialDefinitions; + protected Stat noOfLabelFortifyDefinitions; + protected Stat avgLabelCpdefLengthStat; + protected Stat avgLabelFortifyCpdefCoverage; + + //fortify variables + protected Stat lableFortifyDefinitionLengthStat; + protected Stat labelFortifyDefinitionLengthStat; + + //label fortification + protected Stat accuracyLabelFortifyStat; + protected Stat correctnessLabelFortifyStat; + protected Stat completenessLabelFortifyStat; + protected Stat fmeasureLabelFortifyStat; + + protected Stat avgFortifyCoverageTraingStat; + protected Stat avgFortifyCoverageTestStat; + + protected Stat fortifiedRuntime; + + //blind fortification + protected Stat accuracyBlindFortifyStat; + protected Stat correctnessBlindFortifyStat; + protected Stat completenessBlindFortifyStat; + protected Stat fmeasureBlindFortifyStat; + + protected Stat totalCPDefLengthStat; + protected Stat avgCPDefLengthStat; + + + //hold the fortified accuracy, fmeasure,... of 5%, 10%, 20%, ..., 50% of cpdef used + protected Stat[][] accuracyPercentageFortifyStepStat; //hold the fortified accuracy at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] completenessPercentageFortifyStepStat; //hold the fortified completeness at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] correctnessPercentageFortifyStepStat; //hold the fortified correctness at 5,10,20,30,40,50% (multi-strategies) + protected Stat[][] fmeasurePercentageFortifyStepStat; //hold the fortified correctness at 5,10,20,30,40,50% (multi-strategies) + + protected Stat[] noOfCpdefUsedMultiStepFortStat; + + protected double[][] accuracyHalfFullStep; + protected double[][] fmeasureHalfFullStep; + + protected Stat[][] accuracyFullStepStat; + protected Stat[][] fmeasureFullStepStat; + protected Stat[][] correctnessFullStepStat; + protected Stat[][] completenessFullStepStat; + + + //---------------------------------- + //FAIR comparison + protected Stat fairLearningTimeStat; + protected Stat fairAccuracyStat; + protected Stat fairFmeasureStat; + protected Stat fairCorrectnessStat; + protected Stat fairCompletenessStat; + //---------------------------------- + + Logger logger = Logger.getLogger(this.getClass()); + + public ParCELFortifiedCrossValidation3PhasesFair() { + + } + + public ParCELFortifiedCrossValidation3PhasesFair(AbstractCELA la, ParCELPosNegLP lp, AbstractReasonerComponent rs, int folds, + boolean leaveOneOut) { + + this(la, lp, rs, folds, leaveOneOut, 1, 0, false); + + } + + + public ParCELFortifiedCrossValidation3PhasesFair(AbstractCELA la, ParCELPosNegLP lp, AbstractReasonerComponent rs, int folds, + boolean leaveOneOut, int noOfRuns) { + + this(la, lp, rs, folds, leaveOneOut, noOfRuns, 0, false); + } + + //ParCELFortifiedCrossValidation2PhasesFair + public ParCELFortifiedCrossValidation3PhasesFair(AbstractCELA la, ParCELPosNegLP lp, AbstractReasonerComponent rs, int folds, + boolean leaveOneOut, int noOfRuns, int fortificationTimeout, boolean fairComparison) { + + DecimalFormat df = new DecimalFormat(); + + String baseURI = rs.getBaseURI(); + Map prefixes = rs.getPrefixes(); + + // the training and test sets used later on + List> trainingSetsPos = new LinkedList<>(); + List> trainingSetsNeg = new LinkedList<>(); + List> testSetsPos = new LinkedList<>(); + List> testSetsNeg = new LinkedList<>(); + List> fortificationSetsPos = new LinkedList<>(); + List> fortificationSetsNeg = new LinkedList<>(); + + // get examples and shuffle them too + Set posExamples = ((ParCELPosNegLP) lp).getPositiveExamples(); + List posExamplesList = new LinkedList<>(posExamples); + //Collections.shuffle(posExamplesList, new Random(1)); + Set negExamples = ((ParCELPosNegLP) lp).getNegativeExamples(); + List negExamplesList = new LinkedList<>(negExamples); + //Collections.shuffle(negExamplesList, new Random(2)); + + // sanity check whether nr. of folds makes sense for this benchmark + if (!leaveOneOut && (posExamples.size() < folds && negExamples.size() < folds)) { + System.out.println("The number of folds is higher than the number of " + + "positive/negative examples. This can result in empty test sets. Exiting."); + System.exit(0); + } + + // calculating where to split the sets, ; note that we split + // positive and negative examples separately such that the + // distribution of positive and negative examples remains similar + // (note that there are better but more complex ways to implement this, + // which guarantee that the sum of the elements of a fold for pos + // and neg differs by at most 1 - it can differ by 2 in our implementation, + // e.g. with 3 folds, 4 pos. examples, 4 neg. examples) + int[] splitsPos = calculateSplits(posExamples.size(), folds); + int[] splitsNeg = calculateSplits(negExamples.size(), folds); + + //for orthogonality check + long orthAllCheckCount[] = new long[5]; + orthAllCheckCount[0] = orthAllCheckCount[1] = orthAllCheckCount[2] = orthAllCheckCount[3] = orthAllCheckCount[4] = 0; + + long orthSelectedCheckCount[] = new long[5]; + orthSelectedCheckCount[0] = orthSelectedCheckCount[1] = orthSelectedCheckCount[2] = orthSelectedCheckCount[3] = orthSelectedCheckCount[4] = 0; + + + // calculating training and test sets + for (int i = 0; i < folds; i++) { + Set testPos = getTestingSet(posExamplesList, splitsPos, i); + Set testNeg = getTestingSet(negExamplesList, splitsNeg, i); + testSetsPos.add(i, testPos); + testSetsNeg.add(i, testNeg); + + //fortification training set + Set fortPos = getTestingSet(posExamplesList, splitsPos, (i+1) % folds); + Set fortNeg = getTestingSet(negExamplesList, splitsNeg, (i+1) % folds); + fortificationSetsPos.add(i, fortPos); + fortificationSetsNeg.add(i, fortNeg); + + Set trainingPos = getTrainingSet(posExamples, testPos); + Set trainingNeg = getTrainingSet(negExamples, testNeg); + + trainingPos.removeAll(fortPos); + trainingNeg.removeAll(fortNeg); + + trainingSetsPos.add(i, trainingPos); + trainingSetsNeg.add(i, trainingNeg); + } + + // --------------------------------- + // k-fold cross validation + // --------------------------------- + + Stat runtimeAvg = new Stat(); + Stat runtimeMax = new Stat(); + Stat runtimeMin = new Stat(); + Stat runtimeDev = new Stat(); + + Stat defLenAvg = new Stat(); + Stat defLenDev = new Stat(); + Stat defLenMax = new Stat(); + Stat defLenMin = new Stat(); + + Stat trainingAccAvg = new Stat(); + Stat trainingAccDev = new Stat(); + Stat trainingAccMax = new Stat(); + Stat trainingAccMin = new Stat(); + + Stat trainingCorAvg = new Stat(); + Stat trainingCorDev = new Stat(); + Stat trainingCorMax = new Stat(); + Stat trainingCorMin = new Stat(); + + Stat trainingComAvg = new Stat(); + Stat trainingComDev = new Stat(); + Stat trainingComMax = new Stat(); + Stat trainingComMin = new Stat(); + + Stat testingAccAvg = new Stat(); + Stat testingAccMax = new Stat(); + Stat testingAccMin = new Stat(); + Stat testingAccDev = new Stat(); + + Stat testingCorAvg = new Stat(); + Stat testingCorDev = new Stat(); + Stat testingCorMax = new Stat(); + Stat testingCorMin = new Stat(); + + Stat testingComAvg = new Stat(); + Stat testingComDev = new Stat(); + Stat testingComMax = new Stat(); + Stat testingComMin = new Stat(); + + Stat testingFMesureAvg = new Stat(); + Stat testingFMesureDev = new Stat(); + Stat testingFMesureMax = new Stat(); + Stat testingFMesureMin = new Stat(); + + Stat trainingFMesureAvg = new Stat(); + Stat trainingFMesureDev = new Stat(); + Stat trainingFMesureMax = new Stat(); + Stat trainingFMesureMin = new Stat(); + + Stat noOfDescriptionsAgv = new Stat(); + Stat noOfDescriptionsMax = new Stat(); + Stat noOfDescriptionsMin = new Stat(); + Stat noOfDescriptionsDev = new Stat(); + + //fortify stat. variables + Stat noOfCounterPartialDefinitionsAvg = new Stat(); + Stat noOfCounterPartialDefinitionsDev = new Stat(); + Stat noOfCounterPartialDefinitionsMax = new Stat(); + Stat noOfCounterPartialDefinitionsMin = new Stat(); + + //this is for ParCELEx only + Stat noOfCounterPartialDefinitionsUsedAvg = new Stat(); + Stat noOfCounterPartialDefinitionsUsedDev = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMax = new Stat(); + Stat noOfCounterPartialDefinitionsUsedMin = new Stat(); + + Stat avgCounterPartialDefinitionLengthAvg = new Stat(); + Stat avgCounterPartialDefinitionLengthDev = new Stat(); + Stat avgCounterPartialDefinitionLengthMax = new Stat(); + Stat avgCounterPartialDefinitionLengthMin = new Stat(); + + + Stat avgFirtifiedDefinitionLengthAvg = new Stat(); + Stat avgFirtifiedDefinitionLengthDev = new Stat(); + Stat avgFirtifiedDefinitionLengthMax = new Stat(); + Stat avgFirtifiedDefinitionLengthMin = new Stat(); + + Stat accuracyFortifyAvg = new Stat(); + Stat accuracyFortifyDev = new Stat(); + Stat accuracyFortifyMax = new Stat(); + Stat accuracyFortifyMin = new Stat(); + + Stat correctnessFortifyAvg = new Stat(); + Stat correctnessFortifyDev = new Stat(); + Stat correctnessFortifyMax = new Stat(); + Stat correctnessFortifyMin = new Stat(); + + Stat completenessFortifyAvg = new Stat(); + Stat completenessFortifyDev = new Stat(); + Stat completenessFortifyMax = new Stat(); + Stat completenessFortifyMin = new Stat(); + + Stat fmeasureFortifyAvg = new Stat(); + Stat fmeasureFortifyDev = new Stat(); + Stat fmeasureFortifyMax = new Stat(); + Stat fmeasureFortifyMin = new Stat(); + + Stat avgFortifyCoverageTraingAvg = new Stat(); + Stat avgFortifyCoverageTraingDev = new Stat(); + Stat avgFortifyCoverageTraingMax = new Stat(); + Stat avgFortifyCoverageTraingMin = new Stat(); + + Stat avgFortifyCoverageTestAvg = new Stat(); + Stat avgFortifyCoverageTestDev = new Stat(); + Stat avgFortifyCoverageTestMax = new Stat(); + Stat avgFortifyCoverageTestMin = new Stat(); + + + //---------------------------------------------------------------------- + //loading ontology into Pellet reasoner for checking + //the orthogonality and satisfiability (fortification training strategy) + //---------------------------------------------------------------------- + long ontologyLoadStarttime = System.nanoTime(); + OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); + OWLOntology ontology = ((OWLFile)la.getReasoner().getSources().iterator().next()).createOWLOntology(manager); + outputWriter("Ontology created, axiom count: " + ontology.getAxiomCount()); + PelletReasoner pelletReasoner = PelletReasonerFactory.getInstance().createReasoner(ontology); + outputWriter("Pellet creared and binded with the ontology: " + pelletReasoner.getReasonerName()); + long ontologyLoadDuration = System.nanoTime() - ontologyLoadStarttime; + outputWriter("Total time for creating and binding ontology: " + ontologyLoadDuration/1000000000d + "ms"); + //---------------------------------------------------------------------- + + + for (int kk = 0; kk < noOfRuns; kk++) { + + //stat. variables for each fold ==> need to be re-created after each fold + runtime = new Stat(); + length = new Stat(); + accuracyTraining = new Stat(); + trainingCorrectnessStat = new Stat(); + trainingCompletenessStat = new Stat(); + accuracy = new Stat(); + testingCorrectnessStat = new Stat(); + testingCompletenessStat = new Stat(); + fMeasure = new Stat(); + fMeasureTraining = new Stat(); + + noOfPartialDefinitionStat = new Stat(); + noOfReducedPartialDefinitionStat = new Stat(); + avgPdefLengthStat = new Stat(); + + noOfCounterPartialDefinitions = new Stat(); + noOfLabelFortifyDefinitions = new Stat(); + avgLabelCpdefLengthStat = new Stat(); + avgLabelFortifyCpdefCoverage = new Stat(); + + totalNumberOfDescriptions = new Stat(); + + //fortify variables + lableFortifyDefinitionLengthStat = new Stat(); + labelFortifyDefinitionLengthStat = new Stat(); + + accuracyLabelFortifyStat = new Stat(); + correctnessLabelFortifyStat = new Stat(); + completenessLabelFortifyStat = new Stat(); + fmeasureLabelFortifyStat = new Stat(); + + avgFortifyCoverageTraingStat = new Stat(); + avgFortifyCoverageTestStat = new Stat(); + + fortifiedRuntime = new Stat(); + + //blind fortification + accuracyBlindFortifyStat = new Stat(); + correctnessBlindFortifyStat = new Stat(); + completenessBlindFortifyStat = new Stat(); + fmeasureBlindFortifyStat = new Stat(); + + totalCPDefLengthStat = new Stat(); + avgCPDefLengthStat = new Stat(); + + + //fair evaluation variables initialization + fairAccuracyStat = new Stat(); + fairFmeasureStat = new Stat(); + fairCorrectnessStat = new Stat(); + fairCompletenessStat = new Stat(); + fairLearningTimeStat = new Stat(); + + + + int noOfStrategies = FortificationUtils.strategyNames.length; + + + //fortification accuracy + accuracyPercentageFortifyStepStat = new Stat[noOfStrategies][6]; //6 elements for six values of 5%, 10%, ..., 50% + completenessPercentageFortifyStepStat = new Stat[noOfStrategies][6]; + correctnessPercentageFortifyStepStat = new Stat[noOfStrategies][6]; + fmeasurePercentageFortifyStepStat = new Stat[noOfStrategies][6]; + + //initial fortification accuracy by PERCENTAGE + for (int i=0; i= ((ParCELAbstract)la).getMaxExecutionTimeInSeconds()) { + fairEvaluationNeeded = true; + + + long fairLearningTimeout = orgTimeout; + if (fortificationTimeout == 0) + fairLearningTimeout *= 2; + else + fairLearningTimeout += fortificationTimeout; + + + outputWriter("** Phase 3 - Learning the main concept again with double timeout value (for fair comparison): " + + fairLearningTimeout + "s"); + + //init the learner + //set the pos/neg examples + lp.setPositiveExamples(trainingSetsPos.get(currFold)); + lp.setNegativeExamples(trainingSetsNeg.get(currFold)); + try { + lp.init(); + la.init(); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + + //set the fair learning timeout + ((ParCELAbstract)la).setMaxExecutionTimeInSeconds(fairLearningTimeout); + + + //----------------------------- + //start learning the 2nd phase + //----------------------------- + long algorithmStartTimeFair = System.nanoTime(); + la.start(); + long algorithmDurationFair = System.nanoTime() - algorithmStartTimeFair; + fairLearningTimeStat.addNumber(algorithmDurationFair / (double) 1000000000); + + //reset the timeout value + ((ParCELAbstract)la).setMaxExecutionTimeInSeconds(orgTimeout); + + conceptFair = ((ParCELAbstract)la).getUnionCurrentlyBestDescription(); + } + else { + fairLearningTimeStat.addNumber(algorithmDurationPdef); + } + + + //---------------------------- + //TRAINING accuracy + //---------------------------- + Set curFoldPosTrainingSet = trainingSetsPos.get(currFold); + Set curFoldNegTrainingSet = trainingSetsNeg.get(currFold); + + int correctTrainingPosClassified = getCorrectPosClassified(rs, concept, curFoldPosTrainingSet); + int correctTrainingNegClassified = getCorrectNegClassified(rs, concept, curFoldNegTrainingSet); + int correctTrainingExamples = correctTrainingPosClassified + correctTrainingNegClassified; + + double trainingAccuracy = 100 * ((double) correctTrainingExamples / + (curFoldPosTrainingSet.size() + curFoldNegTrainingSet.size())); + double trainingCompleteness = 100*(double)correctTrainingPosClassified/curFoldPosTrainingSet.size(); + double trainingCorrectness = 100*(double)correctTrainingNegClassified/curFoldNegTrainingSet.size(); + + accuracyTraining.addNumber(trainingAccuracy); + trainingCompletenessStat.addNumber(trainingCompleteness); + trainingCorrectnessStat.addNumber(trainingCorrectness); + + // calculate training F-Score + int negAsPosTraining = curFoldNegTrainingSet.size() - correctTrainingNegClassified; //neg - un = cn + double precisionTraining = (correctTrainingPosClassified + negAsPosTraining) == 0 ? 0 + : correctTrainingPosClassified / (double) (correctTrainingPosClassified + negAsPosTraining); + double recallTraining = correctTrainingPosClassified / (double) curFoldPosTrainingSet.size(); + double fMeasureTrainingFold = 100 * Heuristics.getFScore(recallTraining, precisionTraining); + + fMeasureTraining.addNumber(fMeasureTrainingFold); + + + //--------------------- + //TEST accuracy + //--------------------- + Set curFoldPosTestSet = testSetsPos.get(currFold); + Set curFoldNegTestSet = testSetsNeg.get(currFold); + + + //calculate testing coverage + Set cpTest = rs.hasType(concept, curFoldPosTestSet); //cp + Set upTest = Sets.difference(curFoldPosTestSet, cpTest); //up: false negative + Set cnTest = rs.hasType(concept, curFoldNegTestSet); //cn + + // calculate test accuracies + int correctTestPosClassified = cpTest.size(); //covered positive examples //curFoldPosTestSet.size() - upTest.size(); //getCorrectPosClassified(rs, concept, curFoldPosTestSet); + int correctTestNegClassified = curFoldNegTestSet.size() - cnTest.size(); //getCorrectNegClassified(rs, concept, curFoldNegTestSet); + int correctTestExamples = correctTestPosClassified + correctTestNegClassified; + + double testingAccuracyCurrFold = 100 * ((double) correctTestExamples / + (curFoldPosTestSet.size() + curFoldNegTestSet.size())); + double testingCompleteness = 100*(double)correctTestPosClassified/curFoldPosTestSet.size(); + double testingCorrectness = 100*(double)correctTestNegClassified/curFoldNegTestSet.size(); + + accuracy.addNumber(testingAccuracyCurrFold); + testingCompletenessStat.addNumber(testingCompleteness); + testingCorrectnessStat.addNumber(testingCorrectness); + + + // calculate test F-Score + int negAsPos = cnTest.size(); + double testPrecision = correctTestPosClassified + negAsPos == 0 ? 0 : correctTestPosClassified + / (double) (correctTestPosClassified + negAsPos); + double testRecall = correctTestPosClassified / (double) curFoldPosTestSet.size(); + + double fMeasureTestingFold = 100 * Heuristics.getFScore(testRecall, testPrecision); + fMeasure.addNumber(fMeasureTestingFold); + + length.addNumber(OWLClassExpressionUtils.getLength(concept)); + + + + //================================================== + //FORTIFICATION + //================================================== + double fairAccuracyCurrFold = testingAccuracyCurrFold; + double fairCompleteness = testingCompleteness; + double fairCorrectness = testingCorrectness; + double fairFMeasureCurrFold = fMeasureTestingFold; + + if (fairEvaluationNeeded) { + //calculate FAIR coverage + Set cpFair = rs.hasType(conceptFair, curFoldPosTestSet); //cp + //Set upFair = Helper.difference(curFoldPosTestSet, cpTest); //up + Set cnFair = rs.hasType(conceptFair, curFoldNegTestSet); //cn + + // calculate FAIR accuracy + int correctFairPosClassified = cpFair.size(); //covered positive examples //curFoldPosTestSet.size() - upTest.size(); //getCorrectPosClassified(rs, concept, curFoldPosTestSet); + int correctFairNegClassified = curFoldNegTestSet.size() - cnFair.size(); //getCorrectNegClassified(rs, concept, curFoldNegTestSet); + int correctFairExamples = correctFairPosClassified + correctFairNegClassified; + + fairAccuracyCurrFold = 100 * ((double) correctFairExamples / + (curFoldPosTestSet.size() + curFoldNegTestSet.size())); + fairCompleteness = 100*(double)correctFairPosClassified/curFoldPosTestSet.size(); + fairCorrectness = 100*(double)correctFairNegClassified/curFoldNegTestSet.size(); + + // calculate FAIR F-measure + int fairNegAsPos = cnTest.size(); + double fairPrecision = correctFairPosClassified + fairNegAsPos == 0 ? 0 : correctFairPosClassified + / (double) (correctFairPosClassified + fairNegAsPos); + double fairRecall = correctFairPosClassified / (double) curFoldPosTestSet.size(); + + fairFMeasureCurrFold = 100 * Heuristics.getFScore(fairRecall, fairPrecision); + } + + fairAccuracyStat.addNumber(fairAccuracyCurrFold); + fairCorrectnessStat.addNumber(fairCorrectness); + fairCompletenessStat.addNumber(fairCompleteness); + fairFmeasureStat.addNumber(fairFMeasureCurrFold); + + //--------------------------------------- + //FORTIFICATION + //--------------------------------------- + FortificationUtils.FortificationResult[] multiStepFortificationResult = new FortificationUtils.FortificationResult[noOfStrategies]; + + + + //--------------------------------- + // Fortification - ALL CPDEF + // (BLIND Fortification) + //--------------------------------- + //NOTE: + //Since this will iterate all cpdef, we will calculate score for all other fortification strategies + // training coverage (done), jaccard, fortification training, + + outputWriter("---------------------------------------------------------------"); + outputWriter("BLIND fortification - All counter partial defintions are used"); + outputWriter("---------------------------------------------------------------"); + + + //get the set of pos and neg (in the test set) covered by counter partial definition + Set cpdefPositiveCovered = new HashSet<>(); + Set cpdefNegativeCovered = new HashSet<>(); + + long totalCPDefLength = 0; + + + //variables for fortification training + Set fortificationTrainingPos = fortificationSetsPos.get(currFold); + Set fortificationTrainingNeg= fortificationSetsNeg.get(currFold); + + Set allFortificationExamples = new HashSet<>(); + + allFortificationExamples.addAll(fortificationTrainingPos); + allFortificationExamples.addAll(fortificationTrainingNeg); //duplicate will be remove automatically + + + JaccardSimilarity newJaccardSimilarity = new JaccardSimilarity(pelletReasoner); + + //start the BLIND fortification and calculate the scores + int count = 1; //count the step of fortification + int tmp_id = 1; + for (CELOEPartial.PartialDefinition cpdef : counterPartialDefinitions) { + + //assign id for cpdef for debugging purpose + cpdef.setId("#" + tmp_id++); + + + + //-------------------- + //blind fortification + //-------------------- + Set cpdefCp = rs.hasType(cpdef.getDescription(), curFoldPosTestSet); + Set cpdefCn = rs.hasType(cpdef.getDescription(), curFoldNegTestSet); + + + //-------------------------------- + //Fortification Validation (FV) + //-------------------------------- + Set fortCp = rs.hasType(cpdef.getDescription(), fortificationTrainingPos); + Set fortCn = rs.hasType(cpdef.getDescription(), fortificationTrainingNeg); + + + Set conceptCp = rs.hasType(concept, fortificationTrainingPos); + Set conceptCn = rs.hasType(concept, fortificationTrainingNeg); + + + int cp = fortCp.size(); + int cn = fortCn.size(); + + //this needs to be revised: calculate cfp, cfn once + fortCp.removeAll(conceptCp); + fortCn.removeAll(conceptCn); + + + double fortificationValidationScore = FortificationUtils.fortificationScore(pelletReasoner, cpdef.getDescription(), concept, + cp, cn, fortificationTrainingPos.size(), fortificationTrainingNeg.size(), + cp-fortCp.size(), cn-fortCn.size(), ((ParCELAbstract)la).getMaximumHorizontalExpansion()); + + + //---------------------------- + //Overlap + Similarity Score + //---------------------------- + double overlapNeg = FortificationUtils.getConceptOverlapSimple(fortCn, conceptCn); + double overlapPos = FortificationUtils.getConceptOverlapSimple(fortCp, conceptCp); + + + //--------------- + //NEW- JACCARD + //--------------- + double newJaccardSimilarityScore = 0; + try { + newJaccardSimilarityScore = newJaccardSimilarity.getJaccardSimilarityComplex(concept, cpdef.getDescription()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + double conceptOverlapSimilairtyScore = overlapNeg + newJaccardSimilarityScore; + + double similarityPosNegScore = overlapNeg - 0.5 * overlapPos; + + + + //--------------------------- + //TRAINING COVERAGE Score + //--------------------------- + double trainingCoverageScore = cpdefCn.size()/(double)curFoldNegTrainingSet.size(); + + + //---------------------------------- + //Assign all scores to the CPDEF + //new scoring: 21/4/2013 + //---------------------------------- + double allScores = conceptOverlapSimilairtyScore + fortificationValidationScore + + trainingCoverageScore*0.5; + + double randomScore = new Random().nextDouble(); + + cpdef.setAdditionValue(0, trainingCoverageScore); //no of neg. examples in training set covered by the cpdef + cpdef.setAdditionValue(1, conceptOverlapSimilairtyScore); //can be used to infer jaccard overlap score + cpdef.setAdditionValue(2, fortificationValidationScore); //fortification validation strategy + cpdef.setAdditionValue(3, similarityPosNegScore); + cpdef.setAdditionValue(4, newJaccardSimilarityScore); + cpdef.setAdditionValue(5, allScores); + cpdef.setAdditionValue(6, randomScore); + + //------------------------ + //BLIND fortification + //------------------------ + boolean cpChanged = cpdefPositiveCovered.addAll(cpdefCp); + boolean cnChanged = cpdefNegativeCovered.addAll(cpdefCn); + + cpdefPositiveCovered.addAll(cpdefCp); + cpdefNegativeCovered.addAll(cpdefCn); + + + totalCPDefLength += OWLClassExpressionUtils.getLength(cpdef.getDescription()); + + //print the cpdef which covers some pos. examples + String changed = ""; + if (cpChanged || cnChanged) { + changed = "(" + (cpChanged?"-":"") + (cnChanged?"+":"") + ")"; + + outputWriter(count++ + changed + ". " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + } + else if (logger.isDebugEnabled()) { + logger.debug(count++ + changed + ". " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + } + /* + if (cpChanged || cnChanged) + changed = "(" + (cpChanged?"-":"") + (cnChanged?"+":"") + ")"; + + outputWriter(count++ + changed + ". " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + */ + } + + outputWriter( " * Blind fortifcation summary: cp=" + cpdefPositiveCovered + " --- cn=" + cpdefNegativeCovered); + + outputWriter("test set errors pos (" + upTest.size() + "): " + upTest); + outputWriter("test set errors neg (" + cnTest.size() + "): " + cnTest); + + //----------------------------------------- + //calculate BLIND fortification accuracy + //----------------------------------------- + + //fortify definition length: total length of all cpdef + totalCPDefLengthStat.addNumber(totalCPDefLength); + double avgCPDefLength = totalCPDefLength/(double)counterPartialDefinitions.size(); + avgCPDefLengthStat.addNumber(avgCPDefLength); + + //accuracy, completeness, correctness + int oldSizePosFort = cpdefPositiveCovered.size(); + int oldSizeNegFort = cpdefNegativeCovered.size(); + + cpdefPositiveCovered.removeAll(cpTest); + cpdefNegativeCovered.removeAll(cnTest); + + int commonPos = oldSizePosFort - cpdefPositiveCovered.size(); + int commonNeg = oldSizeNegFort - cpdefNegativeCovered.size(); + + + int cpFort = cpTest.size() - commonPos; //positive examples covered by fortified definition + int cnFort = cnTest.size() - commonNeg; //negative examples covered by fortified definition + + //correctness = un/negSize + double blindFortificationCorrectness = 100 * (curFoldNegTestSet.size() - cnFort)/(double)(curFoldNegTestSet.size()); + + //completeness = cp/posSize + double blindFortificationCompleteness = 100 * (cpFort)/(double)curFoldPosTestSet.size(); + + //accuracy = (cp + un)/(pos + neg) + double blindFortificationAccuracy = 100 * (cpFort + (curFoldNegTestSet.size() - cnFort))/ + (double)(curFoldPosTestSet.size() + curFoldNegTestSet.size()); + + //precision = right positive classified / total positive classified + // = cp / (cp + negAsPos) + double blindPrecission = (cpFort + cnFort) == 0 ? 0 : cpFort / (double)(cpFort + cnFort); + + //recall = right positive classified / total positive + double blindRecall = cpFort / (double)curFoldPosTestSet.size(); + + double blindFmeasure = 100 * Heuristics.getFScore(blindRecall, blindPrecission); + + //STAT values for Blind fortification + correctnessBlindFortifyStat.addNumber(blindFortificationCorrectness); + completenessBlindFortifyStat.addNumber(blindFortificationCompleteness); + accuracyBlindFortifyStat.addNumber(blindFortificationAccuracy); + fmeasureBlindFortifyStat.addNumber(blindFmeasure); + + + //======================================================== + // process other fortification strategies (except BLIND) + //======================================================== + + int INDEX; + + //--------------------------------------- + /// 1. Fortification - TRAINGING COVERAGE + //--------------------------------------- + outputWriter("---------------------------------------------"); + outputWriter("Fortification - TRAINGING COVERAGE"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.TRAINING_COVERAGE_INDEX; + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, counterPartialDefinitions, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 2. Fortification - CONCEPT SIMILARITY & OVERLAP + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - CONCEPT SIMILARITY & OVERLAP"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.CONCEPT_OVERL_SIM_INDEX; + + SortedSet similarityAndOverlapCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(1)); + similarityAndOverlapCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, similarityAndOverlapCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 3. Fortification - FORTIFICATION VALIDATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - FORTIFICATION VALIDATION"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.FORTIFICATION_VALIDATION_INDEX; + + SortedSet fortificationValidationCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(2)); + fortificationValidationCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, fortificationValidationCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 4. Fortification - SIMILARITY NEG-POS + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - SIMILARITY NEG-POS"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.SIMILARITY_POS_NEG_INDEX; + + SortedSet similarityNegPosCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(3)); + similarityNegPosCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, similarityNegPosCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 5. Fortification - JACCARD OVERLAP + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - JACCARD OVERLAP"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.NEW_JACCARD_OVERLAP_INDEX; + + SortedSet jaccardOverlapCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(4)); + jaccardOverlapCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, jaccardOverlapCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + //------------------------------------------------ + /// 6. Fortification - JACCARD DISTANCE + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - JACCARD DISTANCE"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.NEW_JACCARD_DISTANCE_INDEX; + + SortedSet jaccardDistanceCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(4, false)); + jaccardDistanceCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, jaccardDistanceCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + + //------------------------------------------------ + /// 7. Fortification - COMBINATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - COMBINATION SCORES"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.CONBINATION_INDEX; + + SortedSet combinationScoreCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(5)); + combinationScoreCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, combinationScoreCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + + + //------------------------------------------------ + /// 7. Fortification - COMBINATION + //------------------------------------------------ + outputWriter("---------------------------------------------"); + outputWriter("Fortification - RANDOM"); + outputWriter("---------------------------------------------"); + + INDEX = FortificationUtils.RANDOM_INDEX; + + SortedSet randomCpdef = new TreeSet(new FortificationUtils.AdditionalValueComparator(6)); + randomCpdef.addAll(counterPartialDefinitions); + + + //counter partial definition is sorted by training coverage by default ==> don't need to sort the cpdef set + multiStepFortificationResult[INDEX] = FortificationUtils.fortifyAccuracyMultiSteps( + rs, concept, randomCpdef, curFoldPosTestSet, curFoldNegTestSet, false); + + //accumulate the accuracy, fmeasure,... for the TRAINING_COVERAGE strategy at 5%, 10%, 20%,... + for (int i=0; i<6; i++) { //6: the number of steps: 5%, 10%, 20%,..., 50% + accuracyPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationAccuracy[i+1]); + completenessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCompleteness[i+1]); + correctnessPercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationCorrectness[i+1]); + fmeasurePercentageFortifyStepStat[INDEX][i]. + addNumber(multiStepFortificationResult[INDEX].fortificationFmeasure[i+1]); + } + + //------------------------------ + // Fortification with + // LABLED TEST DATA + //------------------------------ + //if there exists covered negative examples ==> check if there are any counter partial definitions + //can be used to remove covered negative examples + + int fixedNeg = 0; + int fixedPos = 0; + int selectedCpdef = 0; + int totalSelectedCpdefLength = 0; + double avgTrainingCoverage = 0; + + /** + * selected cpdef which are selected based on the test labled data + * given a set of wrong classified neg., select a set of cpdef to remove the wrong classified neg examples + * the cpdef are sorted based on the training neg. example coverage + */ + TreeSet selectedCounterPartialDefinitions = new TreeSet(new FortificationUtils.CoverageComparator()); + + if (cnTest.size() > 0) { + + TreeSet tempCoveredNeg = new TreeSet<>(); + tempCoveredNeg.addAll(cnTest); + + TreeSet tempUncoveredPos = new TreeSet<>(); + tempUncoveredPos.addAll(upTest); + + //check each counter partial definitions + for (CELOEPartial.PartialDefinition cpdef : counterPartialDefinitions) { + + //set of neg examples covered by the counter partial definition + Set desCoveredNeg = new HashSet<>(rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + + //if the current counter partial definition can help to remove some neg examples + //int oldNoOfCoveredNeg=tempCoveredNeg.size(); + if (tempCoveredNeg.removeAll(desCoveredNeg)) { + + //assign cn on test set to additionalValue + selectedCounterPartialDefinitions.add(cpdef); + + //check if it may remove some positive examples or not + Set desCoveredPos = new HashSet<>(rs.hasType(cpdef.getDescription(), curFoldPosTestSet)); + tempUncoveredPos.addAll(desCoveredPos); + + //count the total number of counter partial definition selected and their total length + selectedCpdef++; + totalSelectedCpdefLength += OWLClassExpressionUtils.getLength(cpdef.getDescription()); + avgTrainingCoverage += cpdef.getCoverage(); + } + + if (tempCoveredNeg.size() == 0) + break; + } + + fixedNeg = cnTest.size() - tempCoveredNeg.size(); + fixedPos = tempUncoveredPos.size() - upTest.size(); + avgTrainingCoverage /= selectedCpdef; + } + + + noOfLabelFortifyDefinitions.addNumber(selectedCpdef); + avgLabelFortifyCpdefCoverage.addNumber(avgTrainingCoverage); + + + //----------------------------- + // Labeled fortification + // stat calculation + //----------------------------- + //def length + double labelFortifiedDefinitionLength = OWLClassExpressionUtils.getLength(concept) + totalSelectedCpdefLength + selectedCpdef; //-1 from the selected cpdef and +1 for NOT + lableFortifyDefinitionLengthStat.addNumber(labelFortifiedDefinitionLength); + + double avgLabelFortifyDefinitionLength = 0; + + if (selectedCpdef > 0) { + avgLabelFortifyDefinitionLength = (double)totalSelectedCpdefLength/selectedCpdef; + avgLabelCpdefLengthStat.addNumber(totalSelectedCpdefLength/(double)selectedCpdef); + } + + //accuracy + double fortifiedAccuracy = 100 * ((double)(correctTestExamples + fixedNeg - fixedPos)/ + (curFoldPosTestSet.size() + curFoldNegTestSet.size())); + accuracyLabelFortifyStat.addNumber(fortifiedAccuracy); + + //completeness + double fortifiedCompleteness = 100 * ((double)(correctTestPosClassified - fixedPos)/curFoldPosTestSet.size()); + completenessLabelFortifyStat.addNumber(fortifiedCompleteness); + + //correctness + double fortifiedCorrectness = 100 * ((double)(correctTestNegClassified + fixedNeg)/curFoldNegTestSet.size()); + correctnessLabelFortifyStat.addNumber(fortifiedCorrectness); + + //precision, recall, f-measure + double labelFortifiedPrecision = 0.0; //percent of correct pos examples in total pos examples classified (= correct pos classified + neg as pos) + if (((correctTestPosClassified - fixedPos) + (cnTest.size() - fixedNeg)) > 0) + labelFortifiedPrecision = (double)(correctTestPosClassified - fixedPos)/ + (correctTestPosClassified - fixedPos + cnTest.size() - fixedNeg); //tmp3: neg as pos <=> false pos + + double labelFortifiedRecall = (double)(correctTestPosClassified - fixedPos) / curFoldPosTestSet.size(); + + double labelFortifiedFmeasure = 100 * Heuristics.getFScore(labelFortifiedRecall, labelFortifiedPrecision); + fmeasureLabelFortifyStat.addNumber(labelFortifiedFmeasure); + + + + outputWriter("---------------------------------------------"); + outputWriter("LABEL fortify counter partial definitions: "); + outputWriter("---------------------------------------------"); + count = 1; + //output the selected counter partial definition information + if (selectedCpdef > 0) { + for (CELOEPartial.PartialDefinition cpdef : selectedCounterPartialDefinitions) { + + outputWriter(count++ + cpdef.getId() + ". " + FortificationUtils.getCpdefString(cpdef, baseURI, prefixes) + + ", cp=" + rs.hasType(cpdef.getDescription(), curFoldPosTestSet) + + ", cn=" + rs.hasType(cpdef.getDescription(), curFoldNegTestSet)); + + } + + } //end of labelled fortification STAT + + + outputWriter("----------------------"); + + + int[] noOfCpdefMultiStep = FortificationUtils.getMultiStepFortificationStep(counterPartialDefinitions.size()); + + for (int i=0; i<6; i++) { + noOfCpdefUsedMultiStepFortStat[i].addNumber(noOfCpdefMultiStep[i]); + + //minimal value of 50% of the cpdef used in the fortification + //NOTE: no of cpdef descreases after added into other sets for fortification + // Cause has not been investigated + minOfHalfCpdef = (minOfHalfCpdef > noOfCpdefMultiStep[i])? noOfCpdefMultiStep[i] : minOfHalfCpdef; + + //minimal number of counter partial definitions till the current run + //the above problem happens for this case as well + minCpdef = (minCpdef > multiStepFortificationResult[i].fortificationAccuracyStepByStep.length)? + multiStepFortificationResult[i].fortificationAccuracyStepByStep.length : minCpdef; + } + + + + + //create data structure to hold the fortification result + if (currFold == 0) { //have not initiallised + accuracyHalfFullStep = new double[noOfStrategies][minOfHalfCpdef]; //4 strategies + fmeasureHalfFullStep = new double[noOfStrategies][minOfHalfCpdef]; + + accuracyFullStepStat = new Stat[noOfStrategies][minCpdef]; + fmeasureFullStepStat = new Stat[noOfStrategies][minCpdef]; + correctnessFullStepStat = new Stat[noOfStrategies][minCpdef]; + completenessFullStepStat = new Stat[noOfStrategies][minCpdef]; + + //run a loop to create a set of Stat objects + for (int i=0; i < noOfStrategies; i++) { + for (int j = 0; j < minCpdef; j++) { + accuracyFullStepStat[i][j] = new Stat(); + fmeasureFullStepStat[i][j] = new Stat(); + correctnessFullStepStat[i][j] = new Stat(); + completenessFullStepStat[i][j] = new Stat(); + } + } + } + + + //sum up the accuracy and fmeasure directly, do not use Stat for simplicity + outputWriter("*** Calculate full step accuracy: minCpdef = " + minCpdef); + + outputWriter("\tcounter partial deifnition size=" + + counterPartialDefinitions.size()); + + //calculate accuracy, fmeasure by HALF FULL of the cpdef + for (int i=0; i 0) //this is for a weird side-affect of the floating point such that the getMax return a very small number >0 even if the acutuall value is zero + cutOffPoint = (int)Math.round(Math.ceil(noOfLabelFortifyDefinitions.getMax())); + + outputWriter("\n CUT-OFF point computation: " + cutOffPoint); + if (cutOffPoint == 0) { + outputWriter("\tNo fortifying definition is used, the accuracy is unchanged"); + outputWriter("\t\taccuracy: " + df.format(accuracy.getMean()) + ", " + df.format(accuracy.getStandardDeviation()) + + "; correctness: " + df.format(testingCorrectnessStat.getMean()) + ", " + df.format(testingCorrectnessStat.getStandardDeviation()) + + "; completeness: " + df.format(testingCompletenessStat.getMean()) + ", " + df.format(testingCompletenessStat.getStandardDeviation())); + } + else { + cutOffPoint--; + for (int i=0; i < noOfStrategies; i++) { + outputWriter("\t" + FortificationUtils.strategyNames[i] + ":"); + outputWriter("\t accuracy: " + df.format(accuracyFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(accuracyFullStepStat[i][cutOffPoint].getStandardDeviation()) + + "; correctness: " + df.format(correctnessFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(correctnessFullStepStat[i][cutOffPoint].getStandardDeviation()) + + "; completeness: " + df.format(completenessFullStepStat[i][cutOffPoint].getMean()) + + ", " + df.format(completenessFullStepStat[i][cutOffPoint].getStandardDeviation()) + ); + /* + cutOffAvg[0][i] = accuracyFullStepStat[i][cutOffPoint].getMean(); + cutOffAvg[1][i] = correctnessFullStepStat[i][cutOffPoint].getMean(); + cutOffAvg[2][i] = completenessFullStepStat[i][cutOffPoint].getMean(); + + cutOffDev[0][i] = accuracyFullStepStat[i][cutOffPoint].getStandardDeviation(); + cutOffDev[1][i] = correctnessFullStepStat[i][cutOffPoint].getStandardDeviation(); + cutOffDev[2][i] = completenessFullStepStat[i][cutOffPoint].getStandardDeviation(); + */ + } + } + //end of cut-off point processing + + outputWriter(""); + + + //fortification by PERCENTAGE + for (int i=0; i< noOfStrategies; i++) { + + outputWriter(" multi-step fortified accuracy by " + FortificationUtils.strategyNames[i] + ":"); + + outputWriter("\t 5%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][0], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][0], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][0], "%") + ); + outputWriter("\t 10%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][1], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][1], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][1], "%") + ); + outputWriter("\t 20%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][2], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][2], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][2], "%") + ); + outputWriter("\t 30%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][3], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][3], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][3], "%") + ); + outputWriter("\t 40%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][4], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][4], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][4], "%") + ); + outputWriter("\t 50%: " + statOutput(df, accuracyPercentageFortifyStepStat[i][5], "%") + + " -- correctness: " + statOutput(df, correctnessPercentageFortifyStepStat[i][5], "%") + + " -- completeness: " + statOutput(df, completenessPercentageFortifyStepStat[i][5], "%") + ); + + } + + outputWriter(" no of cpdef used in multi-step fortification:"); + outputWriter("\t5%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[0], "")); + outputWriter("\t10%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[1], "")); + outputWriter("\t20%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[2], "")); + outputWriter("\t30%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[3], "")); + outputWriter("\t40%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[4], "")); + outputWriter("\t50%: " + statOutput(df, noOfCpdefUsedMultiStepFortStat[5], "")); + /* + outputWriter("======= Fmeasure full steps (of 50%) ======="); + for (int i=0; i 1) { + // runtime + runtimeAvg.addNumber(runtime.getMean()); + runtimeMax.addNumber(runtime.getMax()); + runtimeMin.addNumber(runtime.getMin()); + runtimeDev.addNumber(runtime.getStandardDeviation()); + + defLenAvg.addNumber(length.getMean()); + defLenMax.addNumber(length.getMax()); + defLenMin.addNumber(length.getMin()); + defLenDev.addNumber(length.getStandardDeviation()); + + trainingAccAvg.addNumber(accuracyTraining.getMean()); + trainingAccDev.addNumber(accuracyTraining.getStandardDeviation()); + trainingAccMax.addNumber(accuracyTraining.getMax()); + trainingAccMin.addNumber(accuracyTraining.getMin()); + + trainingCorAvg.addNumber(trainingCorrectnessStat.getMean()); + trainingCorDev.addNumber(trainingCorrectnessStat.getStandardDeviation()); + trainingCorMax.addNumber(trainingCorrectnessStat.getMax()); + trainingCorMin.addNumber(trainingCorrectnessStat.getMin()); + + trainingComAvg.addNumber(trainingCompletenessStat.getMean()); + trainingComDev.addNumber(trainingCompletenessStat.getStandardDeviation()); + trainingComMax.addNumber(trainingCompletenessStat.getMax()); + trainingComMin.addNumber(trainingCompletenessStat.getMin()); + + testingAccAvg.addNumber(accuracy.getMean()); + testingAccMax.addNumber(accuracy.getMax()); + testingAccMin.addNumber(accuracy.getMin()); + testingAccDev.addNumber(accuracy.getStandardDeviation()); + + testingCorAvg.addNumber(testingCorrectnessStat.getMean()); + testingCorDev.addNumber(testingCorrectnessStat.getStandardDeviation()); + testingCorMax.addNumber(testingCorrectnessStat.getMax()); + testingCorMin.addNumber(testingCorrectnessStat.getMin()); + + testingComAvg.addNumber(testingCompletenessStat.getMean()); + testingComDev.addNumber(testingCompletenessStat.getStandardDeviation()); + testingComMax.addNumber(testingCompletenessStat.getMax()); + testingComMin.addNumber(testingCompletenessStat.getMin()); + + testingFMesureAvg.addNumber(fMeasure.getMean()); + testingFMesureDev.addNumber(fMeasure.getStandardDeviation()); + testingFMesureMax.addNumber(fMeasure.getMax()); + testingFMesureMin.addNumber(fMeasure.getMin()); + + trainingFMesureAvg.addNumber(fMeasureTraining.getMean()); + trainingFMesureDev.addNumber(fMeasureTraining.getStandardDeviation()); + trainingFMesureMax.addNumber(fMeasureTraining.getMax()); + trainingFMesureMin.addNumber(fMeasureTraining.getMin()); + + noOfDescriptionsAgv.addNumber(totalNumberOfDescriptions.getMean()); + noOfDescriptionsMax.addNumber(totalNumberOfDescriptions.getMax()); + noOfDescriptionsMin.addNumber(totalNumberOfDescriptions.getMin()); + noOfDescriptionsDev.addNumber(totalNumberOfDescriptions.getStandardDeviation()); + } + } // for kk folds + + + if (noOfRuns > 1) { + outputWriter(""); + outputWriter("Finished " + noOfRuns + " time(s) of the " + folds + "-folds cross-validations"); + + outputWriter("runtime: " + + "\n\t avg.: " + statOutput(df, runtimeAvg, "s") + + "\n\t dev.: " + statOutput(df, runtimeDev, "s") + + "\n\t max.: " + statOutput(df, runtimeMax, "s") + + "\n\t min.: " + statOutput(df, runtimeMin, "s")); + + + outputWriter("no of descriptions: " + + "\n\t avg.: " + statOutput(df, noOfDescriptionsAgv, "") + + "\n\t dev.: " + statOutput(df, noOfDescriptionsDev, "") + + "\n\t max.: " + statOutput(df, noOfDescriptionsMax, "") + + "\n\t min.: " + statOutput(df, noOfDescriptionsMin, "")); + + outputWriter("definition length: " + + "\n\t avg.: " + statOutput(df, defLenAvg, "") + + "\n\t dev.: " + statOutput(df, defLenDev, "") + + "\n\t max.: " + statOutput(df, defLenMax, "") + + "\n\t min.: " + statOutput(df, defLenMin, "")); + + outputWriter("accuracy on training set:" + + "\n\t avg.: " + statOutput(df, trainingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingAccDev, "%") + + "\n\t max.: " + statOutput(df, trainingAccMax, "%") + + "\n\t min.: " + statOutput(df, trainingAccMin, "%")); + + outputWriter("correctness on training set: " + + "\n\t avg.: " + statOutput(df, trainingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingCorDev, "%") + + "\n\t max.: " + statOutput(df, trainingCorMax, "%") + + "\n\t min.: " + statOutput(df, trainingCorMin, "%")); + + outputWriter("completeness on training set: " + + "\n\t avg.: " + statOutput(df, trainingComAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingComDev, "%") + + "\n\t max.: " + statOutput(df, trainingComMax, "%") + + "\n\t min.: " + statOutput(df, trainingComMin, "%")); + + outputWriter("FMesure on training set: " + + "\n\t avg.: " + statOutput(df, trainingFMesureAvg, "%") + + "\n\t dev.: " + statOutput(df, trainingFMesureDev, "%") + + "\n\t max.: " + statOutput(df, trainingFMesureMax, "%") + + "\n\t min.: " + statOutput(df, trainingFMesureMin, "%")); + + outputWriter("accuracy on testing set: " + + "\n\t avg.: " + statOutput(df, testingAccAvg, "%") + + "\n\t dev.: " + statOutput(df, testingAccDev, "%") + + "\n\t max.: " + statOutput(df, testingAccMax, "%") + + "\n\t min.: " + statOutput(df, testingAccMin, "%")); + + outputWriter("correctness on testing set: " + + "\n\t avg.: " + statOutput(df, testingCorAvg, "%") + + "\n\t dev.: " + statOutput(df, testingCorDev, "%") + + "\n\t max.: " + statOutput(df, testingCorMax, "%") + + "\n\t min.: " + statOutput(df, testingCorMin, "%")); + + outputWriter("completeness on testing set: " + + "\n\t avg.: " + statOutput(df, testingComAvg, "%") + + "\n\t dev.: " + statOutput(df, testingComDev, "%") + + "\n\t max.: " + statOutput(df, testingComMax, "%") + + "\n\t min.: " + statOutput(df, testingComMin, "%")); + + outputWriter("FMesure on testing set: " + + "\n\t avg.: " + statOutput(df, testingFMesureAvg, "%") + + "\n\t dev.: " + statOutput(df, testingFMesureDev, "%") + + "\n\t max.: " + statOutput(df, testingFMesureMax, "%") + + "\n\t min.: " + statOutput(df, testingFMesureMin, "%")); + } + } + + + /* + class URIComparator implements Comparator { + @Override + public int compare(Individual o1, Individual o2) { + return o1.getURI().compareTo(o2.getURI()); + } + + } + */ + + + /* + class CoverageComparator implements Comparator { + @Override + public int compare(CELOEPartial.PartialDefinition p1, CELOEPartial.PartialDefinition p2) { + if (p1.getCoverage() > p2.getCoverage()) + return -1; + else if (p1.getCoverage() < p2.getCoverage()) + return 1; + else + return new ConceptComparator().compare(p1.getDescription(), p2.getDescription()); + + } + } + */ + + + /** + * Sort descreasingly + * + * @author An C. Tran + * + */ + /* + class AdditionalValueComparator implements Comparator { + int index = 0; + boolean descending; + + public AdditionalValueComparator(int index) { + this.index = index; + this.descending = true; + } + + + public AdditionalValueComparator(int index, boolean descending) { + this.index = index; + this.descending = descending; + } + + + + @Override + public int compare(CELOEPartial.PartialDefinition pdef1, CELOEPartial.PartialDefinition pdef2) { + if (pdef1.getAdditionValue(index) > pdef2.getAdditionValue(index)) { + if (this.descending) + return -1; + else + return 1; + } + else if (pdef1.getAdditionValue(index) < pdef2.getAdditionValue(index)) { + if (this.descending) + return 1; + else + return -1; + } + else + return new ConceptComparator().compare(pdef1.getDescription(), pdef2.getDescription()); + + } //compare() + + } //AdditionalValueComparator + */ + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELTestingCorrectnessComparator.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELTestingCorrectnessComparator.java new file mode 100644 index 0000000000..7ca820eec8 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELTestingCorrectnessComparator.java @@ -0,0 +1,58 @@ +package org.dllearner.cli.parcel; + +import java.util.Comparator; + + +/** + * This is a comparator for ParCELExtraTestinhNode based on the correctness + * It is mainly used in fortified strategy to select the counter partial definition + * to form fortified partial definitions. + * + * @author An C. Tran + * + */ +public class ParCELTestingCorrectnessComparator implements Comparator { + + + /** + * Note: this is a simple version of the comparator. The total number of positive and negative examples + * should be taken into consideration. + * + * Currently, the counter partial definitions that cover no positive examples will be placed on the top + * based on their coverage of negative examples. + */ + @Override + public int compare(ParCELExtraTestingNode node1, ParCELExtraTestingNode node2) { + + int cp1 = node1.getCoveredPositiveExamplesTestSet().size(); + int cn1 = node1.getCoveredNegativeExamplestestSet().size(); + int cp2 = node2.getCoveredPositiveExamplesTestSet().size(); + int cn2 = node2.getCoveredNegativeExamplestestSet().size(); + + if (cp1 == 0) { + if (cp2 != 0) + return -1; + else + return compareInt(cn1, cn2); + } + else { + if (cp2 == 0) + return 1; + else + return compareInt(cn1, cn2); + } + + } + + + private int compareInt(int v1, int v2) { + if (v1 < v2) + return -1; + else if (v1 > v2) + return 1; + else + return 0; + + } + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELValidationMultiReducers.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELValidationMultiReducers.java new file mode 100644 index 0000000000..72dec13287 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELValidationMultiReducers.java @@ -0,0 +1,506 @@ +package org.dllearner.cli.parcel; + +import java.text.DecimalFormat; +import java.util.*; + +import com.google.common.collect.Sets; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; +import org.dllearner.cli.CrossValidation; +import org.dllearner.cli.parcel.modeling.PhaseInfor; +import org.dllearner.core.AbstractCELA; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentInitException; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLIndividual; + +/** + * Use testing data to analyse the learning partial definitions. + * + * @author An C. Tran + * + */ + +public class ParCELValidationMultiReducers { + + Logger logger = Logger.getLogger(this.getClass()); + + Map validationData = new HashMap(); + + private OWLDataFactory dataFactory = OWLManager.getOWLDataFactory(); + + /** + * Running k-fold cross evaluation for ParCEL-based algorithm with multi-reducers supported + * + * @param la Learning algorithm + * @param lp Learning problem + * @param rs Reasoner + * @param folds Number of folds + * @param leaveOneOut Using leave-one-out + */ + public ParCELValidationMultiReducers(AbstractCELA la, ParCELPosNegLP lp, AbstractReasonerComponent rs, + int folds, boolean leaveOneOut, int kkFold, Set reducers) { + + //this validation support ParCEL only + if (!(la instanceof ParCELAbstract)) { + outputWriter("Only ParCEL algorithm family is supported!"); + return; + } + + ParCELAbstract parcel = (ParCELAbstract)la; + + //-------------------------- + //setting up + //-------------------------- + DecimalFormat df = new DecimalFormat(); + + // the training and test sets used later on + List> trainingSetsPos = new LinkedList<>(); + List> trainingSetsNeg = new LinkedList<>(); + List> testingSetsPos = new LinkedList<>(); + List> testingSetsNeg = new LinkedList<>(); + + // get examples and shuffle them too + Set posExamples = lp.getPositiveExamples(); + List posExamplesList = new LinkedList<>(posExamples); + Collections.shuffle(posExamplesList, new Random(1)); + Set negExamples = lp.getNegativeExamples(); + List negExamplesList = new LinkedList<>(negExamples); + Collections.shuffle(negExamplesList, new Random(2)); + + // sanity check whether nr. of folds makes sense for this benchmark + if(!leaveOneOut && (posExamples.size() testPos = CrossValidation.getTestingSet(posExamplesList, splitsPos, i); + Set testNeg = CrossValidation.getTestingSet(negExamplesList, splitsNeg, i); + testingSetsPos.add(i, testPos); + testingSetsNeg.add(i, testNeg); + trainingSetsPos.add(i, CrossValidation.getTrainingSet(posExamples, testPos)); + trainingSetsNeg.add(i, CrossValidation.getTrainingSet(negExamples, testNeg)); + } + + if (reducers == null) { + reducers = new HashSet(); + reducers.add(parcel.getReducer()); + } + else if (reducers.size() == 0) + reducers.add(parcel.getReducer()); + + //initialise the validation data for each reducer + for (ParCELReducer reducer : reducers) + validationData.put(reducer, new ParCELvaliadationData()); + + //---------------------- + //end of setting up + //---------------------- + + //hold all partial definitions for further analysis + //Map> allPartialDefinitions = new TreeMap>(new ConceptComparator()); + + //----------------------------------- + //start k-folds cross validation + //----------------------------------- + int maxPartialDefinitionLength=0; + for(int currFold=0; (currFold foldReducedPartialDefinitions = parcel.getReducedPartialDefinition(reducer); + + //get the learned concept + List reducedDescriptions = new LinkedList<>(); + + for (ParCELExtraNode def : foldReducedPartialDefinitions) + reducedDescriptions.add(def.getDescription()); + + OWLClassExpression concept = dataFactory.getOWLObjectUnionOf(new TreeSet<>(reducedDescriptions)); + + //--------------------------- + //validate learned result + //--------------------------- + outputWriter("fold " + currFold + " - " + reducer.getClass().getSimpleName() + ":"); + + Set tmp = rs.hasType(concept, trainingSetsPos.get(currFold)); + Set tmp2 = Sets.difference(trainingSetsPos.get(currFold), tmp); + Set tmp3 = rs.hasType(concept, trainingSetsNeg.get(currFold)); + + outputWriter(" training set errors pos (" + tmp2.size() + "): " + tmp2); + outputWriter(" training set errors neg (" + tmp3.size() + "): " + tmp3); + + tmp = rs.hasType(concept, testingSetsPos.get(currFold)); + tmp2 = Sets.difference(testingSetsPos.get(currFold), tmp); + tmp3 = rs.hasType(concept, testingSetsNeg.get(currFold)); + + outputWriter(" test set errors pos: " + tmp2); + outputWriter(" test set errors neg: " + tmp3); + + + // calculate training accuracies + int trainingCorrectPosClassified = getCorrectPosClassified(rs, concept, trainingSetsPos.get(currFold)); + int trainingCorrectNegClassified = getCorrectNegClassified(rs, concept, trainingSetsNeg.get(currFold)); + int trainingCorrectExamples = trainingCorrectPosClassified + trainingCorrectNegClassified; + double trainingAccuracy = 100*((double)trainingCorrectExamples/(trainingSetsPos.get(currFold).size()+ + trainingSetsNeg.get(currFold).size())); + + double trainingCompleteness = 100*(double)trainingCorrectPosClassified/trainingSetsPos.get(currFold).size(); + double trainingCorrectness = 100*(double)trainingCorrectNegClassified/trainingSetsNeg.get(currFold).size(); + + reducerValData.accuracyTraining.addNumber(trainingAccuracy); + reducerValData.trainingCompletenessStat.addNumber(trainingCompleteness); + reducerValData.trainingCorrectnessStat.addNumber(trainingCorrectness); + + // calculate test accuracies + int correctPosClassified = getCorrectPosClassified(rs, concept, testingSetsPos.get(currFold)); + int correctNegClassified = getCorrectNegClassified(rs, concept, testingSetsNeg.get(currFold)); + int correctExamples = correctPosClassified + correctNegClassified; + double currAccuracy = 100*((double)correctExamples/(testingSetsPos.get(currFold).size()+ + testingSetsNeg.get(currFold).size())); + + double testingCompleteness = 100*(double)correctPosClassified/testingSetsPos.get(currFold).size(); + double testingCorrectness = 100*(double)correctNegClassified/testingSetsNeg.get(currFold).size(); + + reducerValData.accuracy.addNumber(currAccuracy); + reducerValData.testingCompletenessStat.addNumber(testingCompleteness); + reducerValData.testingCorrectnessStat.addNumber(testingCorrectness); + + + // calculate training F-Score + int negAsPosTraining = rs.hasType(concept, trainingSetsNeg.get(currFold)).size(); + double precisionTraining = trainingCorrectPosClassified + negAsPosTraining == 0 ? 0 : trainingCorrectPosClassified / (double) (trainingCorrectPosClassified + negAsPosTraining); + double recallTraining = trainingCorrectPosClassified / (double) trainingSetsPos.get(currFold).size(); + + reducerValData.fMeasureTraining.addNumber(100*Heuristics.getFScore(recallTraining, precisionTraining)); + + // calculate test F-Score + int negAsPos = rs.hasType(concept, testingSetsNeg.get(currFold)).size(); + double precision = correctPosClassified + negAsPos == 0 ? 0 : correctPosClassified / (double) (correctPosClassified + negAsPos); + double recall = correctPosClassified / (double) testingSetsPos.get(currFold).size(); + + reducerValData.fMeasure.addNumber(100*Heuristics.getFScore(recall, precision)); + + //length of the definition + reducerValData.length.addNumber(OWLClassExpressionUtils.getLength(concept)); + + //print out the validation information + outputWriter(" training: " + trainingCorrectPosClassified + "/" + trainingSetsPos.get(currFold).size() + + " positive and " + trainingCorrectNegClassified + "/" + trainingSetsNeg.get(currFold).size() + " negative examples"); + outputWriter(" testing: " + correctPosClassified + "/" + testingSetsPos.get(currFold).size() + " correct positives, " + + correctNegClassified + "/" + testingSetsNeg.get(currFold).size() + " correct negatives"); + outputWriter(" concept: " + concept); + outputWriter(" accuracy: " + df.format(currAccuracy) + "% (corr:"+ df.format(testingCorrectness) + + "%, comp:" + df.format(testingCompleteness) + "%) --- training:" + + df.format(trainingAccuracy) + "% (corr:"+ df.format(trainingCorrectness) + + "%, comp:" + df.format(trainingCompleteness) + "%)"); + outputWriter(" length: " + df.format(OWLClassExpressionUtils.getLength(concept))); + outputWriter(" runtime: " + df.format(algorithmDuration/(double)1000000000) + "s"); + + outputWriter(" number of partial definitions: " + foldReducedPartialDefinitions.size() + + "/" + parcel.getNumberOfPartialDefinitions()); + + + //no of partial definitions + reducerValData.noOfPartialDef.addNumber(foldReducedPartialDefinitions.size()); + + //conculate the avg. partial definition length = total length of the concept / no of partila definitions + double pl = OWLClassExpressionUtils.getLength(concept)/(double)foldReducedPartialDefinitions.size(); + reducerValData.partialDefinitionLength.addNumber(pl); + outputWriter(" avarage partial definition length: " + df.format(pl)); + + + /* + * Analyse the partial definitions for the prediction model and the actual model + */ + + + //for (ParCELExtraNode node : foldReducedPartialDefinitions) + // allReducedPartialDefinitions.add(node.getDescription()); + + //infer and display the partial definition information + //outputWriter("---------- Fold " + currFold + " -----------"); + + //all partial definitions generated in the fold + Set foldPartialDefinitions = parcel.getPartialDefinitions(); + + + //get the training dataset of the current fold + Set trainingPos = trainingSetsPos.get(currFold); + Set trainingNeg = trainingSetsNeg.get(currFold); + Set testingPos = testingSetsPos.get(currFold); + Set testingNeg = testingSetsNeg.get(currFold); + + //--------------------- + // PREDICTION model + //--------------------- + + //calculate prediction-model-score for all partial definition generated of the current fold + //Map predictionScores = ParCELPredictionModelScoring.scoringComplex( + // foldPartialDefinitions, trainingPos); + + //---------------------------------------------------------- + // calculate fold information for each partial definition + // Note that the above is for the whole definition, + // in this step, we are evaluating each p/definition + //---------------------------------------------------------- + for (ParCELExtraNode def : foldPartialDefinitions) { + + Set trainingCoveredPos = rs.hasType(def.getDescription(), trainingPos); + Set trainingCoveredNeg = rs.hasType(def.getDescription(), trainingNeg); + Set testingCoveredPos = rs.hasType(def.getDescription(), testingPos); + Set testingCoveredNeg = rs.hasType(def.getDescription(), testingNeg); + + //-------------- + //add partial definition into the partial definition set + //-------------- + + //1. calculate the training infor and testing info + PhaseInfor trainingInfor = new PhaseInfor(trainingPos.size(), + trainingNeg.size(), trainingCoveredPos.size(), + trainingCoveredNeg.size()); + + PhaseInfor testingInfor = new PhaseInfor(testingPos.size(), + testingNeg.size(), testingCoveredPos.size() , testingCoveredNeg.size()); + + /* + //2. add the partial definitions of the current fold into all partial definition set with the above information + if (!allPartialDefinitions.containsKey(def.getDescription())) { + //if the description is in the list before, just add the evaluation info for that description + Set valInfor = new TreeSet(new FoldInforComparator()); + valInfor.add(new FoldInfor(currFold, trainingInfor, testingInfor)); + allPartialDefinitions.put(def.getDescription(), valInfor); + } + else { + //if the description is in the set of partial definition before, just add new evaluation info + allPartialDefinitions.get(def.getDescription()).add(new FoldInfor(currFold, trainingInfor, testingInfor)); + } + */ + //update the max partial definition length + if (maxPartialDefinitionLength < OWLClassExpressionUtils.getLength(def.getDescription())) + maxPartialDefinitionLength = OWLClassExpressionUtils.getLength(def.getDescription()); + + } //for each partial definition in the list of all partial definitions of the current fold + + + /* + //store the prediction score of the current fold into all partial definitions set + for (Description des : predictionScores.keySet()) { + //if the description is in the list of all partial definition + if (allPartialDefinitions.containsKey(des)) { + + //check for the corresponding fold of the description and assign the score + boolean found = false; + for (FoldInfor fold : allPartialDefinitions.get(des)) { + if (fold.getFold() == currFold) { + fold.setPredScore(predictionScores.get(des)); + + //add the current reducer into the list of reducers that select the partial definition as a part of the final definition + if (reducedDescriptions.contains(des)) + fold.getSelectedByReducers().add(reducer); + + found = true; + break; + } + } + + if (!found) + logger.error("Cannot find the corresponding fold of the partial definition"); + } + else + logger.error("Cannot find the partial definition in all partial definitions set"); + + + } //for each description in the all partial definitions set of the current fold - update pScore + */ + } //for each reducers + + } //for k folds + + + //------------------------------------------ + //end of k-fold cross validation + //output result of the k-fold + //TODO: display result for each reducer + //------------------------------------------ + + outputWriter(""); + outputWriter("Finished " + folds + "-folds cross-validation."); + + for (ParCELReducer reducer : reducers) { + + ParCELvaliadationData valData = validationData.get(reducer); + + outputWriter("----- Reducer: " + reducer.getClass().getSimpleName() + " ------"); + outputWriter("runtime: " + CrossValidation.statOutput(df, valData.runtime, "s")); + outputWriter("#partial definitions: " + CrossValidation.statOutput(df, valData.noOfPartialDef, "")); + outputWriter("avg. partial definition length: " + CrossValidation.statOutput(df, valData.partialDefinitionLength, "")); + outputWriter("length: " + CrossValidation.statOutput(df, valData.length, "")); + outputWriter("F-Measure on training set: " + CrossValidation.statOutput(df, valData.fMeasureTraining, "%")); + outputWriter("F-Measure: " + CrossValidation.statOutput(df, valData.fMeasure, "%")); + outputWriter("predictive accuracy on training set: " + CrossValidation.statOutput(df, valData.accuracyTraining, "%") + + " - corr: " + CrossValidation.statOutput(df, valData.trainingCorrectnessStat, "%") + + " - comp: " + CrossValidation.statOutput(df, valData.trainingCompletenessStat, "%")); + outputWriter("predictive accuracy on test set: " + CrossValidation.statOutput(df,valData. accuracy, "%") + + " - corr: " + CrossValidation.statOutput(df, valData.testingCorrectnessStat, "%") + + " - comp: " + CrossValidation.statOutput(df, valData.testingCompletenessStat, "%")); + } + + //=================== + //ACTUAL model + //=================== + + //display all partial definitions information produced in the validation group by partial definition + //and calculate the actual model score for the partial definition as well + /* + outputWriter("======================================="); + outputWriter("Partial definitions"); + outputWriter("======================================="); + int count=1; + for (Description def : allPartialDefinitions.keySet()) { + + double aScore = ParCELActualModelScoring.scoring(def, allPartialDefinitions.get(def), + folds, maxPartialDefinitionLength); + + Set infors = allPartialDefinitions.get(def); + + outputWriter(count++ + ". " + + def.toManchesterSyntaxString(rs.getBaseURI(), rs.getPrefixes()) + + ", length=" + def.getLength() + + ", folds=" + allPartialDefinitions.get(def).size() + + ", aScore=" + df.format(aScore)); + + for (FoldInfor info : infors) { + //assign the actual score for partial definitions + //NOTE: currently, actual score bases on the overall information of k-folds + // therefore, actual model score of a partial definition is equal for all folds + info.setActualScore(aScore); + + outputWriter("\t-" + info.toString() + + ", pScore=" + df.format(info.getPredScore()) + + (info.getSelectedByReducers().size() > 0 ? (", selected-by: " + info.getSelectedBy()):"")); + } + + } + */ + + //display all partial definitions information produced in the validation group by partial definition + /* + for (int curFold=0; curFold testSetPos) { + return rs.hasType(concept, testSetPos).size(); + } + + public static int getCorrectNegClassified(AbstractReasonerComponent rs, OWLClassExpression concept, + Set testSetNeg) { + return testSetNeg.size() - rs.hasType(concept, testSetNeg).size(); + } + + + protected void outputWriter(String output) { + logger.info(output); + } + + + + + + + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELvaliadationData.java b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELvaliadationData.java new file mode 100644 index 0000000000..aa8c9340ac --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/ParCELvaliadationData.java @@ -0,0 +1,22 @@ +package org.dllearner.cli.parcel; + +import org.dllearner.utilities.statistics.Stat; + +public class ParCELvaliadationData { + // statistical values + Stat runtime = new Stat(); + Stat accuracy = new Stat(); + Stat length = new Stat(); + Stat accuracyTraining = new Stat(); + Stat fMeasure = new Stat(); + Stat fMeasureTraining = new Stat(); + + Stat trainingCompletenessStat = new Stat(); + Stat trainingCorrectnessStat = new Stat(); + + Stat testingCompletenessStat = new Stat(); + Stat testingCorrectnessStat = new Stat(); + + Stat noOfPartialDef = new Stat(); + Stat partialDefinitionLength = new Stat(); +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/Test.java b/interfaces/src/main/java/org/dllearner/cli/parcel/Test.java new file mode 100644 index 0000000000..1efd50c602 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/Test.java @@ -0,0 +1,65 @@ +package org.dllearner.cli.parcel; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import org.dllearner.utilities.statistics.Stat; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.AxiomType; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.util.DLExpressivityChecker; + +public class Test { + + public static void main(String[] args) { + + + /* + Set setA, setB; + + Long l1 = new Long(1); + Long l2 = new Long(2); + Long l3 = new Long(3); + Long l4 = new Long(4); + Long l5 = new Long(5); + + + setA = new HashSet(); + setB = new HashSet(); + + + setA.add(l1); + setA.add(l2); + setA.add(l3); + + setB.add(l5); + setB.add(l4); + + + System.out.println(setA.removeAll(setB)); + */ + + Stat a[] = new Stat[3]; + a[0].addNumber(0); + + } + + + class MyLong { + public long value; + + public MyLong() { + this.value = 0; + } + } + + + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/ConceptSimilarity.java b/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/ConceptSimilarity.java new file mode 100644 index 0000000000..5eca289de2 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/ConceptSimilarity.java @@ -0,0 +1,1090 @@ +package org.dllearner.cli.parcel.fortification; + +import java.io.File; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.*; + +import org.semanticweb.owlapi.util.DefaultPrefixManager; +import uk.ac.manchester.cs.owl.owlapi.*; + +import com.clarkparsia.pellet.owlapiv3.PelletReasoner; +import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory; + + + +/** + * This class implements methods for calculating the concept similarity. + * + * @author An C. Tran + * + */ +public class ConceptSimilarity { + + private AbstractReasonerComponent reasoner; + private Set instances; + + private static Logger logger = Logger.getLogger(ConceptSimilarity.class); + + private static final OWLDataFactory df = OWLManager.getOWLDataFactory(); + + public ConceptSimilarity() { + this.reasoner = null; + } + + + + public static double getConceptOverlapSimple(Set coverC, Set coverD) { + + //compute the intersection between C and D + Set intersection = new HashSet<>(); + intersection.addAll(coverC); + intersection.retainAll(coverD); + + int commonInstances = intersection.size(); + int allInstances = coverC.size() + coverD.size() - commonInstances; + + double dissimilarity = commonInstances / (double)coverC.size(); + if (dissimilarity < (commonInstances / (double)coverD.size())) + dissimilarity = commonInstances / (double)coverD.size(); + + return commonInstances / (double)allInstances * dissimilarity; + } + + + public ConceptSimilarity(AbstractReasonerComponent reasoner, Set instances) { + this.reasoner = reasoner; + this.instances = new HashSet<>(); + this.instances.addAll(instances); + } + + /** + * Flatten disjunctive description into set of descriptions, e.g. A or (B and C) into {A, B and C} + * Note that this methods does not normalise the description. Therefore, it should be called after a normalisation call. + * + * @param description Description to be flattened + * + * @return List of description in conjunctive normal form + */ + /* + public static List disjunctiveNormalFormFlatten(OWLClassExpression description) { + List result = new LinkedList(); + + //check if the given description is in disjunctive normal form? return NULL if it is not + if (!isDisjunctiveNormalForm(description)) + return null; + + if (description instanceof Union) { + for (OWLClassExpression child : description.getChildren()) { + result.addAll(disjunctiveNormalFormFlatten(child)); + } + } + else + result.add(description); + + return result; + } + */ + + + /** + * Check if a given description is in disjunctive normal form or not. + * + * @param description Description to be checked + * + * @return true if the given description is in disjunctive normal form, false otherwise + */ + public static boolean isDisjunctiveNormalForm(OWLClassExpression description) { + + if ((description instanceof OWLClass) || (description.isOWLThing()) || description.isOWLNothing()) + return true; + else if (description instanceof OWLObjectComplementOfImpl) + return isDisjunctiveNormalForm(((OWLObjectComplementOfImpl) description).getOperand()); + else if (description instanceof OWLObjectUnionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + return isDisjunctiveNormalForm(child); + } + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + if (containDisjunction(child)) + return false; + + return true; + } + else if (description instanceof OWLRestriction) { + + if (((OWLRestriction) description).isDataRestriction() || (description instanceof OWLObjectHasValue)) + return true; + + return !(containDisjunction(((OWLQuantifiedObjectRestriction)description).getFiller())); + } + + return false; + } //isDisjunctiveNormalForm + + + /** + * Check if the given description contain disjunction or not. This method aims to support the disjunctive normal form checking + * + * @param description Description to check + * + * @return true if the given description contains disjunction, false otherwise + */ + public static boolean containDisjunction(OWLClassExpression description) { + if (OWLClassExpressionUtils.getLength(description) <= 2) + return false; + else if (description instanceof OWLObjectUnionOf) + return true; + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + if (containDisjunction(child)) + return true; + return false; + } + else if (description instanceof OWLRestriction) { + + if (((OWLRestriction) description).isDataRestriction() || (description instanceof OWLObjectHasValue)) + return false; + else { //object properties + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + return containDisjunction(child); + } + } + return false; + } //containDisjunction + + + + /** + * Flatten a disjunctive normal form into list of descriptions, e.g. (A or B or (A and D)) --> {A, B, (A and D)} + * This method does not perform the normalisation. Therefore, it should be called after a disjunctive normalisation. + * + * @param description + * @return + */ + public static List flattenDisjunctiveNormalDescription(OWLClassExpression description) { + List result = new LinkedList(); + + /* + if (!isDisjunctiveNormalForm(description)) { + System.out.println("**ERROR - " + description + " is not in disjunctive normal form"); + return null; + } + */ + + if (description instanceof OWLObjectUnionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + if (child instanceof OWLObjectUnionOf) + result.addAll(flattenDisjunctiveNormalDescription(child)); + else + result.add(child); + } + } + else { + result.add(description); + } + + return result; + } + + + + /** + * Normalise a description into disjunctive normal form + * + * @param description Description to be normalised + * + * @return Description in disjunctive normal form + */ + public static OWLClassExpression normalise(int level, OWLClassExpression description) { + + /* + for (int i=0; i children = new HashSet<>(); + + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(norm)) + children.add(df.getOWLObjectComplementOf(child)); + return df.getOWLObjectUnionOf(children); + } + else if (norm instanceof OWLObjectUnionOf) { + Set children = new HashSet<>(); + + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(norm)) + children.add(df.getOWLObjectComplementOf(child)); + return df.getOWLObjectIntersectionOf(children); + + } + else + return df.getOWLObjectComplementOf(norm); + } //negation + + //Union + else if (description instanceof OWLObjectUnionOf) { //A or B or C ... + Set children = new HashSet<>(); + + //normalise all description's children + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + OWLClassExpression norm = normalise(level+1,child); + + if (norm instanceof OWLObjectUnionOf) + children.addAll(OWLClassExpressionUtils.getChildren(norm)); + else + children.add(norm); + } + + return df.getOWLObjectUnionOf(children); + } //union + + //Intersection + else if (description instanceof OWLObjectIntersectionOf) { //A and B and C ... + Set children = new HashSet<>(); + + OWLClassExpression firstUnion = null; + + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + OWLClassExpression norm = normalise(level+1, child); + + if (norm instanceof OWLObjectIntersectionOf) //A and B + children.addAll(OWLClassExpressionUtils.getChildren(norm)); + else if (norm instanceof OWLObjectUnionOf) { + + //if the first Union is found, keep it for transformation: A and (B or C) = (A and B) or (A and C) + if (firstUnion == null) + firstUnion = norm; + else + children.add(norm); + } + else + children.add(norm); + } //for each child of the description + + if (firstUnion == null) + return df.getOWLObjectIntersectionOf(children); + else { //transform: A and (B or C) ==> (A and B) or (A and C) + + Set unionChildren = new HashSet<>(); + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(firstUnion)) { + Set tmp = new HashSet<>(); //contains Intersections + tmp.add(child); + tmp.addAll(children); + + unionChildren.add(df.getOWLObjectIntersectionOf(tmp)); + } + + return df.getOWLObjectUnionOf(unionChildren); //normalise(level+1, df.getOWLObjectUnionOf(unionChildren)); + } + + } //intersection + + //restrictions + else if (description instanceof OWLRestriction) { + + if (!(description instanceof OWLQuantifiedObjectRestriction)) //datatype property does not need to be normalised + return description; + else { //object properties, normalise its Range + //normalise the range of restriction and replace it with the normalised range + if (OWLClassExpressionUtils.getChildren(description).size() == 0) + logger.warn("**** ERROR: Restriction [" + description + "] has no child"); + + OWLClassExpression newChild = normalise(level + 1, ((OWLQuantifiedObjectRestriction)description).getFiller()); + return OWLClassExpressionUtils.replaceFiller((OWLQuantifiedObjectRestriction)description, newChild); + } + } + + return null; + } //normalise() + + + /** + * Extract the atomic/primary concepts at the top level of a description + * Why List, not Set???? + * + * @param description + * @return + */ + public static List prim(OWLClassExpression description) { + List result = new LinkedList(); + + if (!description.isAnonymous()) + result.add(description); + else if (description instanceof OWLObjectComplementOf) { + List primNegated = prim(((OWLObjectComplementOf) description).getOperand()); + if (primNegated.size() > 0) + result.add(description); //TODO: wrong here??? + } + else if ((description instanceof OWLObjectIntersectionOf) || (description instanceof OWLObjectUnionOf)) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + + List tmp = prim(child); + for (OWLClassExpression des : tmp) + if (!result.contains(des)) + result.add(des); + } + } + + return result; + } + + public static Set primSet(OWLClassExpression description) { + return new HashSet<>(prim(description)); + } + + /** + * Return a list of properties used in a given description. + * Why List, not Set??? + * + * @param description Description + * + * @return List of properties in the description + */ + public static List getProperty(OWLClassExpression description) { + List result = new LinkedList(); + + if ((description instanceof OWLRestriction)) + result.add(((OWLRestriction)description).getProperty()); + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + + //do not use addAll to avoid duplicate + List tmp = getProperty(child); + for (OWLPropertyExpression pro : tmp) + if (!result.contains(pro)) + result.add(pro); + } + } + + return result; + } + + + + public static Set getPropertySet(OWLClassExpression description) { + return new HashSet<>(getProperty(description)); + } + + /** + * Get the Range of a property in a given description + * + * @param property Property + * @param description Description + * + * @return Range of the given property in the description + */ + public static OWLClassExpression val(OWLPropertyExpression property, OWLClassExpression description) { + List innerVal = valInner(property, description); + + if (innerVal.size() == 0) + return df.getOWLThing(); + else if (innerVal.size() == 1) + return innerVal.get(0); + else + return df.getOWLObjectIntersectionOf(new HashSet<>(innerVal)); // TODO why not using sets directly instead of lists? + } //val() + + + private static List valInner(OWLPropertyExpression property, OWLClassExpression description) { + List result = new LinkedList<>(); + + //restriction + if (description instanceof OWLRestriction) { + OWLPropertyExpression pro = ((OWLRestriction) description).getProperty(); + if (pro == property) { + if (pro instanceof OWLDataProperty) { //for datatype property, val(.) = {Thing} + if (!result.contains(df.getOWLThing())) + result.add(df.getOWLThing()); + } else if (!(description instanceof OWLObjectHasValue)) { //object property ==> get its range + if (OWLClassExpressionUtils.getChildren(description).size() == 0) + logger.warn("***ERROR: Description [" + description + "] has no child"); + + result.add(((OWLQuantifiedObjectRestriction)description).getFiller()); + } + + } + + } + + //intersection + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + + //add each element to avoid the duplication + List tmp = new LinkedList(); + tmp = valInner(property, child); + for (OWLClassExpression t : tmp) { + if (!result.contains(t)) + result.add(t); + } + } + } + + //other types of Description is not taken into consideration + + return result; + } + + + public static int min(OWLPropertyExpression property, OWLClassExpression description) { + int m = minInner(property, description); + if (m == Integer.MAX_VALUE) + m = 0; + + return m; + } + + + private static int minInner(OWLPropertyExpression property, OWLClassExpression description) { + int m = Integer.MAX_VALUE; + + //restriction + if ((description instanceof OWLObjectMinCardinality) || + (description instanceof OWLObjectExactCardinality) || + (description instanceof OWLDataMinCardinality) || + (description instanceof OWLDataExactCardinality)) { + + OWLPropertyExpression pro = ((OWLRestriction) description).getProperty(); + + if (pro == property) { + int cardinality = ((OWLCardinalityRestriction) description).getCardinality(); + m = Math.min(cardinality, m); + } + } + + //intersection + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + int cardinality = minInner(property, child); + m = Math.min(cardinality, m); + } + } + return m; + } + + + private static int max(OWLPropertyExpression property, OWLClassExpression description) { + int m = maxInner(property, description); + if (m == Integer.MIN_VALUE) + m = 0; + + return m; + } + + + private static int maxInner(OWLPropertyExpression property, OWLClassExpression description) { + int m = Integer.MIN_VALUE; + + //restriction + if ((description instanceof OWLObjectMaxCardinality) || + (description instanceof OWLObjectExactCardinality) || + (description instanceof OWLDataMaxCardinality) || + (description instanceof OWLDataExactCardinality)) { + + OWLPropertyExpression pro = ((OWLRestriction)description).getProperty(); + + if (pro == property) { + int cardinary = ((OWLCardinalityRestriction)description).getCardinality(); + m = Math.max(cardinary, m); + } + } + + //intersection + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + int cardinary = maxInner(property, child); + m = Math.max(cardinary, m); + } + } + return m; + } + + + + /** + * Calculate Sp(C, D) - the similarity between atomic concepts of two descriptions + * + * @param C + * @param D + * + * @return + */ + public double simPrim(OWLClassExpression C, OWLClassExpression D) { + + //System.out.print(" ** sPrim(" + C + ", " + D +") = "); + + Set coverC = PE(C); + Set coverD = PE(D); + + if ((coverC == null) || (coverD == null)) { + //System.out.println(" 0 - null coverage returned"); + return 0; + } + + Set copyCoverC = new HashSet<>(); + copyCoverC.addAll(coverC); + + copyCoverC.removeAll(coverD); + + int intersection = coverC.size() - copyCoverC.size(); + int union = (coverC.size() + coverD.size() - intersection); + + double result = intersection / (double) union; + + //System.out.println(intersection + "/" + union + " = " + result); + + return result; + } + + + public double simPrim(List C, List D) { + OWLClassExpression intersectC, interesctD; + + if (C.size() < 1 || D.size() < 1) + return -1; + + if (C.size() > 1) + intersectC = df.getOWLObjectIntersectionOf(new HashSet<>(C)); // TODO why not using sets directly instead of lists? + else + intersectC = C.get(0); + + if (D.size() > 1) + interesctD = df.getOWLObjectIntersectionOf(new HashSet<>(D)); // TODO why not using sets directly instead of lists? + else + interesctD = D.get(0); + + return simPrim(intersectC, interesctD); + } //simPrim() + + + /** + * Calculate the similarity of the properties/roles.
+ *
    + *
  1. find all properties of C, D
  2. + *
  3. for each property p: calculate s_p = sim(p, val(p, C), val(p, D))
  4. + *
  5. return 1/n(sum(s_p)) + *
+ * + * @param C + * @param D + * @return + */ + public double simRole(List allPro, OWLClassExpression C, OWLClassExpression D) { + + if (allPro.size() == 0) { + //System.out.println(" ** simRole([] , " + C + ", " + D +") = 1"); + return 1; + } + + double sum = 0; + + /* + List proC = getProperty(C); + List proD = getProperty(D); + List allPro = new LinkedList(proC); + + //calculate allPro + for (PropertyExpression p : proD) { + if (!allPro.contains(p)) + allPro.add(p); + } + */ + + //calculate simRole for each property + for (OWLPropertyExpression p : allPro) { + OWLClassExpression valCP = val(p, C); + OWLClassExpression valDP = val(p, D); + + //System.out.println(" ** simRole(" + p + ", " + C + ", " + D +"):"); + sum += similarity(valCP, valDP); + } + + return 1d/allPro.size()*sum; + } //simRole() + + + /** + * Calculate similarity between two descriptions.
+ * sim(C, D) = a * ( simPrim(prim(C), prim(D)) + 1/n * sum_pi(simRole(pi, C, D)) + 1/n * sum_pi(simNum(pi, C, D))) + * + * @param C + * @param D + * @return + */ + private double similarityInner(List allPro, OWLClassExpression C, OWLClassExpression D) { + + double sp = 0; + double sr = 1; + double sn = 1; + + List primC = prim(C); + List primD = prim(D); + + sp = simPrim(primC, primD); + + if (allPro.size() > 0) { + sn = simNum(allPro, C, D); + sr = simRole(allPro, C, D); + return (1/3d)*(sp + sr + sn); + } + else + return sp; + + //return (1/3d)*(sp + sr + sn); + + } + + + public double similarity(OWLClassExpression C, OWLClassExpression D) { + + /* + if (containDisjunction(C)) { + //System.out.println("ERROR - [" + C + "] contains disjunction"); + return -1; + } + + if (containDisjunction(D)) { + //System.out.println("ERROR - [" + D + "] contains disjunction"); + return -1; + } + */ + + List proC = getProperty(C); + List proD = getProperty(D); + + List allPro= new LinkedList<>(); + allPro.addAll(proC); + for (OWLPropertyExpression p : proD) { + if (!allPro.contains(p)) + allPro.add(p); + } + + return similarityInner(allPro, C, D); + } + + + /** + * + * @param C + * @param D + * @return + */ + public double disjunctiveSimilarity(OWLClassExpression C, OWLClassExpression D) { + double sim = 0; + + //System.out.println("****normalise (l=" + C.getLength() + "): " + C); + OWLClassExpression normaliseC = normalise(0, C); + + //System.out.println("****flattening (l=" + normaliseC.getLength() + "): " + normaliseC); + List flattenC = flattenDisjunctiveNormalDescription(normaliseC); + + //System.out.println("****flattening result (l=" + flattenC.size() + "): " + flattenC); + + + //System.out.println("****normalise (l=" + D.getLength() + "): " + D); + OWLClassExpression normaliseD = normalise(0, D); + + //System.out.println("****flattening (l=" + normaliseC.getLength() + "): " + normaliseD); + List flattenD = flattenDisjunctiveNormalDescription(normaliseD); + + //System.out.println("****flattening result (l=" + flattenD.size() + "): " + flattenD); + + + + for (OWLClassExpression childC : flattenC) { + for (OWLClassExpression childD : flattenD) { + //System.out.println("* similarity(" + childC + ", " + childD + "):"); + double sim_i = similarity(childC, childD); + sim = (sim < sim_i)? sim_i : sim; + //System.out.println(" ==> return: " + sim); + } + } + + return sim; + } //disjunctiveSimilarity() + + + /** + * Compute similarity between a description and a set of descriptions (max similarity will be returned) + * + * @param descriptions Set of descriptions + * @param D A description + * @return + */ + public double disjunctiveSimilarity(Set descriptions, OWLClassExpression D) { + double similarity = 0; + + for (OWLClassExpression C : descriptions) { + double s_tmp = disjunctiveSimilarity(C, D); + similarity = Math.max(s_tmp, similarity); + } + + return similarity; + } + + + /** + * Compute similarity between a description and a set of ParCELNodes (max) + * + * @param descriptions Set of descriptions form of PerCELExNode + * @param D A description + * + * @return Maximal similarity between D and the set of descriptions + */ + public double disjunctiveSimilarityEx(Set descriptions, OWLClassExpression D) { + double similarity = 0; + + for (ParCELExtraNode C : descriptions) { + double s_tmp = disjunctiveSimilarity(C.getDescription(), D); + similarity = Math.max(s_tmp, similarity); + } + + return similarity; + } + /** + * Calculate similarity between numeric roles/properties of two descriptions
+ * + * simNum(C, D) = 1/n * sum_pi(sn(pi, min(pi, C), max(pi, C), min(pi, D), max(pi, D))) + * + * @param C + * @param D + * + * @return + */ + public static double simNum(List allPro, OWLClassExpression C, OWLClassExpression D) { + + //System.out.println(" ** simNum(" + C + ", " + D +"):"); + + if (allPro.size() == 0) { + //System.out.println("\t==> return: 1"); + return 1; + } + + double sn = 0; + + + /* + List roleC = getProperty(C); + List roleD = getProperty(D); + + Set allProperty = new HashSet(); + allProperty.addAll(roleC); + allProperty.addAll(roleD); + */ + + + for (OWLPropertyExpression property : allPro) { + int minC = min(property, C); + int maxC = max(property, C); + int minD = min(property, D); + int maxD = max(property, D); + + double tmp = simNumInner(minC, maxC, minD, maxD); + sn += tmp; + + //System.out.println("\tsn(" + property + ", (" + minC + ", " + maxC +") , (" + minD + ", " + maxD +")) = " + tmp); + } + + //System.out.println("\t==> return: " + sn + "/" + allPro.size() + "=" + (sn/(double)allPro.size())); + + return (sn/(double)allPro.size()); + } //simNum() + + /** + * Ref. paper "A similarity measure for the ALN Description Logic" + * + * @param minC + * @param maxC + * @param minD + * @param maxD + * @return (minMax - maxMin + 1)/(double)(maxMax - minMin + 1); + */ + private static double simNumInner(int minC, int maxC, int minD, int maxD) { + int minMax = Math.min(maxC, maxD); + int maxMin = Math.max(minC, minD); + + int maxMax = Math.max(maxC, maxD); + int minMin = Math.min(minC, minD); + + //if (minMax > maxMin) + return (minMax - maxMin + 1)/(double)(maxMax - minMin + 1); + //else + //return 0; + } + + + /** + * Simulates the reasoner to return the number of instances covered by a description + * + * @param description + * + * @return Number of instances covered by the given description + */ + private Set PE(OWLClassExpression description) { + + if (reasoner != null) { + return reasoner.hasType(description, instances); + } + + //below is for testing this class + Set result = new HashSet<>(); + + if ((description.isOWLThing()) || description.equals(Example2.person)) { + + String[] tmp = {"meg", "bod", "pat", "gwen", "ann", "sue", "tom"}; + for (String s : tmp) + result.add(df.getOWLNamedIndividual(s, pm)); + } + + else if (description.equals(Example2.male)) { + String[] tmp = {"bod", "pat", "tom"}; + for (String s : tmp) + result.add(df.getOWLNamedIndividual(s, pm)); + } + + else if ((description.equals(Example2.notMale)) || + (description.equals(Example2.person_and_not_male))) { + + String[] tmp = {"meg", "gwen", "ann", "sue"}; + for (String s : tmp) + result.add(df.getOWLNamedIndividual(s, pm)); + } + else if (description.equals(Example2.notMale)) { + String[] tmp = {"dog", "cat"}; + for (String s : tmp) + result.add(df.getOWLNamedIndividual(s, pm)); + } + else + return null; + + return result; + } + + + + /** + * MAIN: for testing + * + * @param args + * @throws OWLOntologyCreationException + */ + public static void main(String[] args) throws OWLOntologyCreationException { + + + ConceptSimilarity similarityChecker = new ConceptSimilarity(); + + + + + + System.out.println("----------------"); + System.out.println("Example 1:"); + System.out.println("----------------"); + + System.out.println("C = " + Example1.C); + System.out.println("D = " + Example1.D); + + System.out.println("prim(C1) = " + prim(Example1.C1)); + System.out.println("prim(D1) = " + prim(Example1.D1)); + + System.out.println("Properties(C1) = " + getProperty(Example1.C1)); + System.out.println("Properties(D1) = " + getProperty(Example1.D1)); + + List flattenC = flattenDisjunctiveNormalDescription(Example1.C); + List flattenD = flattenDisjunctiveNormalDescription(normalise(0, Example1.D)); + + System.out.println("Flatten(C) = " + flattenC); + System.out.println("Flatten(D) = " + flattenD); + + System.out.println("similarity(C, D) = " + similarityChecker.disjunctiveSimilarity(Example1.C, Example1.D)); + + //------------------------------------------------ + //example 2: A similarity measure for the ALN DL + //------------------------------------------------ + /* + Thing thing = Thing.instance; + NamedClass person = new NamedClass("Person"); + NamedClass male = new NamedClass("Male"); + ObjectProperty marriedTo = new ObjectProperty("marriedTo"); + ObjectProperty hasChild = new ObjectProperty("hasChild"); + Negation notMale = new Negation(male); + Intersection person_and_not_male = df.getOWLObjectIntersectionOf(person, notMale); + + ObjectAllRestriction marriedTo_all_Person = new ObjectAllRestriction(marriedTo, person); + ObjectAllRestriction marriedTo_all_person_and_not_male = new ObjectAllRestriction(marriedTo, person_and_not_male); + ObjectCardinalityRestriction hasChild_less_1 = new ObjectMaxCardinalityRestriction(1, hasChild, thing); + ObjectCardinalityRestriction hasChild_less_2 = new ObjectMaxCardinalityRestriction(2, hasChild, thing); + + OWLClassExpression CC = df.getOWLObjectIntersectionOf(person, marriedTo_all_Person, hasChild_less_1); + OWLClassExpression DD = df.getOWLObjectIntersectionOf(male, marriedTo_all_person_and_not_male, hasChild_less_2); + */ + + System.out.println("\n----------------"); + System.out.println("Example 2:"); + System.out.println("----------------"); + + System.out.println(" C = " + Example2.C); + System.out.println(" D = " + Example2.D); + + + //List flattenC2 = flattenDisjunctiveNormalDescription(Example2.C); + //List flattenD2 = flattenDisjunctiveNormalDescription(normalise(0, Example2.D)); + + //System.out.println("Flatten(C) = " + flattenC2); + //System.out.println("Flatten(D) = " + flattenD2); + + System.out.println("prim(C) = " + prim(Example2.C)); + System.out.println("prim(D) = " + prim(Example2.D)); + + List proC = getProperty(Example2.C); + List proD = getProperty(Example2.D); + + System.out.println("Properties(C) = " + proC); + System.out.println("Properties(D) = " + proD); + + List allPro = new LinkedList<>(); + allPro.addAll(proC); + for (OWLPropertyExpression p : proD) { + if (!proC.contains(proD)) + proC.add(p); + } + System.out.println("Properties(C, D) = " + allPro); + + System.out.println("val(marriedTo, C) = " + val(Example2.marriedTo, Example2.C)); + System.out.println("val(marriedTo, D) = " + val(Example2.marriedTo, Example2.D)); + + System.out.println("val(hasChild, C) = " + val(Example2.hasChild, Example2.C)); + System.out.println("val(hasChild, D) = " + val(Example2.hasChild, Example2.D)); + //val(Example2.hasParent, Example2.D); + System.out.println("val(hasParent, D) = " + val(Example2.hasParent, Example2.D)); + + System.out.println("sp(prim(C), prim(D)) = " + similarityChecker.simPrim(prim(Example2.C), prim(Example2.D))); + System.out.println("sp(val(C), val(D)) = " + + similarityChecker.simPrim(val(Example2.marriedTo, Example2.C), val(Example2.marriedTo, Example2.D))); + + System.out.println("min(hasChild, C) = " + min(Example2.hasChild, Example2.C)); + System.out.println("min(hasChild, D) = " + min(Example2.hasChild, Example2.D)); + System.out.println("min(marriedTo, C) = " + min(Example2.marriedTo, Example2.C)); + System.out.println("min(marriedTo, D) = " + min(Example2.marriedTo, Example2.D)); + + + System.out.println("max(hasChild, C) = " + max(Example2.hasChild, Example2.C)); + System.out.println("max(hasChild, D) = " + max(Example2.hasChild, Example2.D)); + System.out.println("max(marriedTo, C) = " + max(Example2.marriedTo, Example2.C)); + System.out.println("max(marriedTo, D) = " + max(Example2.marriedTo, Example2.D)); + + System.out.println("----------------"); + System.out.println("calculation"); + System.out.println("----------------"); + + //System.out.println("sn (C, D) = " + simNum(Example2.C, Example2.D)); + //System.out.println("similarity(person, animal) = " + similarityChecker.disjunctiveSimilarity(Example2.person, Example2.animal)); + System.out.println("similarity(C, D) = " + similarityChecker.disjunctiveSimilarity(Example2.C, Example2.D)); + + OWLObjectUnionOf person_or_not_male_and_person = df.getOWLObjectUnionOf(Example2.person_and_not_male, Example2.person); + + System.out.println(normalise(0, person_or_not_male_and_person)); + + } + + private static final PrefixManager pm = new DefaultPrefixManager("http://example.org/"); + + private static class Example1 { + //--------------------------------------------------- + // example 1: a dissimilarity measure for the ALC DL + //--------------------------------------------------- + public static OWLClass A1 = df.getOWLClass("A1", pm); + public static OWLClass A2 = df.getOWLClass("A2", pm); + public static OWLClass A3 = df.getOWLClass("A3", pm); + public static OWLClass A4 = df.getOWLClass("A4", pm); + public static OWLClass B1 = df.getOWLClass("B1", pm); + public static OWLClass B2 = df.getOWLClass("B2", pm); + public static OWLClass B3 = df.getOWLClass("B3", pm); + public static OWLClass B4 = df.getOWLClass("B4", pm); + public static OWLClass B5 = df.getOWLClass("B5", pm); + public static OWLClass B6 = df.getOWLClass("B6", pm); + + public static OWLObjectProperty Q = df.getOWLObjectProperty("Q", pm); + public static OWLObjectProperty R = df.getOWLObjectProperty("R", pm); + public static OWLObjectProperty S = df.getOWLObjectProperty("S", pm); + public static OWLObjectProperty T = df.getOWLObjectProperty("T", pm); + + // \some R. B1 + public static OWLObjectSomeValuesFrom R_some_B1 = df.getOWLObjectSomeValuesFrom(R, B1); + + // \all Q. (A4 and B5) + public static OWLObjectIntersectionOf A4_and_B5 = df.getOWLObjectIntersectionOf(A4, B5); + public static OWLObjectAllValuesFrom Q_all__A4_and_B5 = df.getOWLObjectAllValuesFrom(Q, A4_and_B5); + + // \all T. (\all Q. (A4 and B5)) + public static OWLObjectAllValuesFrom T_all__Q_all__A4_and_B5 = df.getOWLObjectAllValuesFrom(T, Q_all__A4_and_B5); + + // \some R. A3 + public static OWLObjectSomeValuesFrom R_some_A3 = df.getOWLObjectSomeValuesFrom(R, A3); + + // \some R. B2 + public static OWLObjectSomeValuesFrom R_some_B2 = df.getOWLObjectSomeValuesFrom(R, B2); + + // \all S. B3 + public static OWLObjectAllValuesFrom S_all_B3 = df.getOWLObjectAllValuesFrom(S, B3); + + + // \all T. (B6 and B4) + public static OWLObjectIntersectionOf B6_and_b4 = df.getOWLObjectIntersectionOf(B6, B4); + public static OWLObjectAllValuesFrom T_all__B6_and_B4 = df.getOWLObjectAllValuesFrom(T, B6_and_b4); + + public static OWLClassExpression C1 = df.getOWLObjectIntersectionOf(A2, R_some_B1, T_all__Q_all__A4_and_B5); + public static OWLClassExpression C = df.getOWLObjectUnionOf(C1, A1); + + public static OWLClassExpression D1 = df.getOWLObjectIntersectionOf(A1, B2, R_some_A3, R_some_B2, S_all_B3, T_all__B6_and_B4); + public static OWLClassExpression D = df.getOWLObjectUnionOf(D1, B2); + } + + + private static class Example2 { + public static OWLClass thing = df.getOWLThing(); + public static OWLClass person = df.getOWLClass("Person", pm); + public static OWLClass male = df.getOWLClass("Male", pm); + public static OWLObjectProperty marriedTo = df.getOWLObjectProperty("marriedTo", pm); + public static OWLObjectProperty hasChild = df.getOWLObjectProperty("hasChild", pm); + public static OWLObjectComplementOf notMale = df.getOWLObjectComplementOf(male); + public static OWLObjectIntersectionOf person_and_not_male = df.getOWLObjectIntersectionOf(person, notMale); + public static OWLObjectUnionOf person_or_not_male = df.getOWLObjectUnionOf(person, notMale); + + public static OWLClass animal = df.getOWLClass("animal", pm); + + public static OWLObjectSomeValuesFrom marriedTo_all_Person = df.getOWLObjectSomeValuesFrom(marriedTo, person); + public static OWLObjectAllValuesFrom marriedTo_all_person_and_not_male = df.getOWLObjectAllValuesFrom(marriedTo, person_and_not_male); + public static OWLObjectAllValuesFrom marriedTo_all_person_or_not_male = df.getOWLObjectAllValuesFrom(marriedTo, person_or_not_male); + public static OWLObjectCardinalityRestriction hasChild_less_1 = df.getOWLObjectMaxCardinality(1, hasChild, thing); + public static OWLObjectCardinalityRestriction hasChild_less_2 = df.getOWLObjectMaxCardinality(2, hasChild, thing); + + public static OWLClassExpression C = df.getOWLObjectIntersectionOf(person, marriedTo_all_Person, hasChild_less_1); + public static OWLClassExpression D = df.getOWLObjectIntersectionOf(male, marriedTo_all_person_or_not_male, hasChild_less_2, marriedTo_all_Person); + + public static OWLObjectProperty hasParent = df.getOWLObjectProperty("hasParent", pm); + } + + + +} + \ No newline at end of file diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/FortificationUtils.java b/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/FortificationUtils.java new file mode 100644 index 0000000000..1bf663a4a0 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/FortificationUtils.java @@ -0,0 +1,703 @@ +package org.dllearner.cli.parcel.fortification; + +import java.text.DecimalFormat; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.clarkparsia.pellet.owlapiv3.PelletReasoner; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.parcel.celoe.CELOEPartial; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.*; +import uk.ac.manchester.cs.owl.owlapi.OWLObjectComplementOfImpl; + +public class FortificationUtils { + + private static Logger logger = Logger.getLogger(FortificationUtils.class); + + private static final OWLDataFactory df = OWLManager.getOWLDataFactory(); + + + //fortification strategies + public static String[] strategyNames = {"TCScore", "CSScore", "FVScore", "SIMILARITY-NEG_POS", "NEW-JACCARD OVERLAP", "NEW-JACCARD DISTANCE", "COMBINATION", "Random"}; + //public static String[] strategyShortNames = {"TCScore", "CSScore", "FVScore", "Sim-NEG_POS", "NEW-JOverlap", "NEW-JDistance", "Combination"}; + + //constants used to index the fortification strategies in the result array + public static final int TRAINING_COVERAGE_INDEX = 0, CONCEPT_OVERL_SIM_INDEX = 1, + FORTIFICATION_VALIDATION_INDEX = 2, SIMILARITY_POS_NEG_INDEX = 3, + NEW_JACCARD_OVERLAP_INDEX = 4, NEW_JACCARD_DISTANCE_INDEX = 5, + CONBINATION_INDEX = 6, RANDOM_INDEX=7; + + + public static class CoverageComparator implements Comparator { + @Override + public int compare(CELOEPartial.PartialDefinition p1, CELOEPartial.PartialDefinition p2) { + if (p1.getCoverage() > p2.getCoverage()) + return -1; + else if (p1.getCoverage() < p2.getCoverage()) + return 1; + else if (OWLClassExpressionUtils.getLength(p1.getDescription()) > OWLClassExpressionUtils.getLength(p2.getDescription()))//the same coverage + return -1; + else if (OWLClassExpressionUtils.getLength(p1.getDescription()) < OWLClassExpressionUtils.getLength(p2.getDescription())) + return 1; + else + return p1.getDescription().compareTo(p2.getDescription()); + + } + } + + + public static double fortificationScore(PelletReasoner reasoner, OWLClassExpression cpdef, OWLClassExpression concept, + int noOfCp, int noOfCn, int noOfPos, int noOfNeg, int commonPos, int commonNeg, int maxLength) + { + double cnFactor=1.2, cpFactor=0.5, lenFactor = 0.1; + double commonFactor = 1.5; + + //Intersection intersection = new Intersection(concept, new Negation(cpdef)); + + //if (reasoner.isSatisfiable(OWLAPIConverter.getOWLAPIDescription(intersection))) + // return 0; + + double score1 = noOfCn/(double)noOfNeg*cnFactor - (noOfCp/(double)noOfPos)*cpFactor + lenFactor*(1-OWLClassExpressionUtils.getLength(cpdef)/maxLength); + double score2 = noOfCn/(double)noOfNeg*cnFactor - noOfCp/(double)noOfPos*cpFactor - commonPos/(double)noOfPos*commonFactor + commonNeg/(double)noOfNeg*commonFactor; + + return score1; + } + + + public static String getCpdefStringOldScore(CELOEPartial.PartialDefinition cpdef, String baseURI, Map prefixes) { + DecimalFormat df = new DecimalFormat(); + + String result = cpdef.getDescription() + + "(l=" + OWLClassExpressionUtils.getLength(cpdef.getDescription()) + + ", cn_training=" + df.format(cpdef.getCoverage()) + + ", ortho=" + df.format(cpdef.getAdditionValue(0)) + + ", cn_test=" + Math.round(cpdef.getAdditionValue(1)) + + ", old-jaccard OL=" + df.format(1-cpdef.getAdditionValue(2)) + + ", new-jaccard OL=" + df.format(cpdef.getAdditionValue(9)) + + ", fort_training_score(cn_test)=" + df.format(cpdef.getAdditionValue(3)) + + ", simAll=" + df.format(cpdef.getAdditionValue(4)) + + ", simPos=" + df.format(cpdef.getAdditionValue(5)) + + ", simNeg=" + df.format(cpdef.getAdditionValue(6)) + + ", combinedScore=" + df.format(cpdef.getAdditionValue(8)) + + ")"; + + return result; + } + + + public static String getCpdefString(CELOEPartial.PartialDefinition cpdef, String baseURI, Map prefixes) { + DecimalFormat df = new DecimalFormat(); + + String result = cpdef.getDescription() + + "(l=" + OWLClassExpressionUtils.getLength(cpdef.getDescription()) + + ", trainingCn=" + df.format(cpdef.getCoverage()) + + ", TCScore=" + df.format(cpdef.getAdditionValue(TRAINING_COVERAGE_INDEX)) + + ", CSScore=" + df.format(cpdef.getAdditionValue(CONCEPT_OVERL_SIM_INDEX)) + + ", FVScore=" + Math.round(cpdef.getAdditionValue(FORTIFICATION_VALIDATION_INDEX)) + + ", jaccard_Sim=" + df.format(cpdef.getAdditionValue(NEW_JACCARD_OVERLAP_INDEX)) + + ", jaccard_Dist=" + df.format(1-cpdef.getAdditionValue(NEW_JACCARD_DISTANCE_INDEX)) + + ", Sim_NegPos=" + df.format(cpdef.getAdditionValue(SIMILARITY_POS_NEG_INDEX)) + + ", combination=" + df.format(cpdef.getAdditionValue(CONBINATION_INDEX)) + + ")"; + + return result; + } + + + /** + * Convert an array of double that contains accuracy/completeness/correctness into a string (from the 1st..6th elements) + * + * @param df Decimal formatter + * @param arr Array of double (7 elements) + * + * @return A string of double values + */ + public static String arrayToString(DecimalFormat df, double[] arr) { + return "[" + Stream.of(arr).map(df::format).collect(Collectors.joining(";")) + "]"; + } + + + /** + * Normalise a description into disjunctive normal form + * + * @param description Description to be normalised + * + * @return Description in disjunctive normal form + */ + public static OWLClassExpression normalise(int level, OWLClassExpression description) { + + /* + for (int i=0; i children = new HashSet<>(); + + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(norm)) + children.add(df.getOWLObjectComplementOf(child)); + return df.getOWLObjectUnionOf(children); + } + else if (norm instanceof OWLObjectUnionOf) { + Set children = new HashSet<>(); + + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(norm)) + children.add(df.getOWLObjectComplementOf(child)); + return df.getOWLObjectIntersectionOf(children); + + } + else + return df.getOWLObjectComplementOf(norm); + } //negation + + //Union + else if (description instanceof OWLObjectUnionOf) { //A or B or C ... + Set children = new HashSet<>(); + + //normalise all description's children + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + OWLClassExpression norm = normalise(level+1,child); + + if (norm instanceof OWLObjectUnionOf) + children.addAll(OWLClassExpressionUtils.getChildren(norm)); + else + children.add(norm); + } + + return df.getOWLObjectUnionOf(children); + } //union + + //Intersection + else if (description instanceof OWLObjectIntersectionOf) { //A and B and C ... + Set children = new HashSet<>(); + + OWLClassExpression firstUnion = null; + + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + OWLClassExpression norm = normalise(level+1, child); + + if (norm instanceof OWLObjectIntersectionOf) //A and B + children.addAll(OWLClassExpressionUtils.getChildren(norm)); + else if (norm instanceof OWLObjectUnionOf) { + + //if the first Union is found, keep it for transformation: A and (B or C) = (A and B) or (A and C) + if (firstUnion == null) + firstUnion = norm; + else + children.add(norm); + } + else + children.add(norm); + } //for each child of the description + + if (firstUnion == null) + return df.getOWLObjectIntersectionOf(children); + else { //transform: A and (B or C) ==> (A and B) or (A and C) + + Set unionChildren = new HashSet<>(); + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(firstUnion)) { + Set tmp = new HashSet<>(); //contains Intersections + tmp.add(child); + tmp.addAll(children); + + unionChildren.add(df.getOWLObjectIntersectionOf(tmp)); + } + + return df.getOWLObjectUnionOf(unionChildren); //normalise(level+1, df.getOWLObjectUnionOf(unionChildren)); + } + + } //intersection + + //restrictions + else if (description instanceof OWLRestriction) { + + if (!(description instanceof OWLQuantifiedObjectRestriction)) //datatype property does not need to be normalised + return description; + else { //object properties, normalise its Range + //normalise the range of restriction and replace it with the normalised range + if (OWLClassExpressionUtils.getChildren(description).size() == 0) + logger.warn("**** ERROR: Restriction [" + description + "] has no child"); + + OWLClassExpression newChild = normalise(level + 1, ((OWLQuantifiedObjectRestriction)description).getFiller()); + return OWLClassExpressionUtils.replaceFiller((OWLQuantifiedObjectRestriction)description, newChild); + } + } + + return null; + } + + + + public static OWLClassExpression normalise(OWLClassExpression d) { + return normalise(0, d); + } + + + /** + * Check if a given description is in disjunctive normal form or not. + * + * @param description Description to be checked + * + * @return true if the given description is in disjunctive normal form, false otherwise + */ + public static boolean isDisjunctiveNormalForm(OWLClassExpression description) { + + if ((description instanceof OWLClass) || (description.isOWLThing()) || description.isOWLNothing()) + return true; + else if (description instanceof OWLObjectComplementOfImpl) + return isDisjunctiveNormalForm(((OWLObjectComplementOfImpl) description).getOperand()); + else if (description instanceof OWLObjectUnionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + return isDisjunctiveNormalForm(child); + } + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + if (containDisjunction(child)) + return false; + + return true; + } + else if (description instanceof OWLRestriction) { + + if (((OWLRestriction) description).isDataRestriction() || (description instanceof OWLObjectHasValue)) + return true; + + return !(containDisjunction(((OWLQuantifiedObjectRestriction)description).getFiller())); + } + + return false; + } //isDisjunctiveNormalForm + + + /** + * Check if the given description contain disjunction or not. This method aims to support the disjunctive normal form checking + * + * @param description Description to check + * + * @return true if the given description contains disjunction, false otherwise + */ + public static boolean containDisjunction(OWLClassExpression description) { + if (OWLClassExpressionUtils.getLength(description) <= 2) + return false; + else if (description instanceof OWLObjectUnionOf) + return true; + else if (description instanceof OWLObjectIntersectionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + if (containDisjunction(child)) + return true; + return false; + } + else if (description instanceof OWLRestriction) { + + if (((OWLRestriction) description).isDataRestriction() || (description instanceof OWLObjectHasValue)) + return false; + else { //object properties + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) + return containDisjunction(child); + } + } + return false; + } //containDisjunction + + + /** + * Get the primary concepts at the 1st level of a description + * + * @param description + * @return A set of primary concepts at the 1st level of a description + */ + public static Set getPrimaries(OWLClassExpression description) { + Set result = new HashSet<>(); + + if (!description.isAnonymous()) + result.add(description); + else if (description instanceof OWLObjectComplementOf) { + Set primNegated = getPrimaries(((OWLObjectComplementOf) description).getOperand()); + if (primNegated.size() > 0) + result.add(description); //TODO: wrong here??? + } + else if ((description instanceof OWLObjectIntersectionOf) || (description instanceof OWLObjectUnionOf)) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + + Set tmp = getPrimaries(child); + for (OWLClassExpression des : tmp) + if (!result.contains(des)) + result.add(des); + } + } + + return result; + } + + + /** + * Flatten a disjunctive normal form into list of descriptions, e.g. (A or B or (A and D)) --> {A, B, (A and D)} + * This method does not perform the normalisation. Therefore, it should be called after a disjunctive normalisation. + * + * @param description + * @return + */ + public static List flattenDisjunctiveNormalDescription(OWLClassExpression description) { + List result = new LinkedList(); + + /* + if (!isDisjunctiveNormalForm(description)) { + System.out.println("**ERROR - " + description + " is not in disjunctive normal form"); + return null; + } + */ + + if (description instanceof OWLObjectUnionOf) { + for (OWLClassExpression child : OWLClassExpressionUtils.getChildren(description)) { + if (child instanceof OWLObjectUnionOf) + result.addAll(flattenDisjunctiveNormalDescription(child)); + else + result.add(child); + } + } + else { + result.add(description); + } + + return result; + } + + + + /** + * Compute overlap between 2 descriptions (Nicola paper) + * + * @param coverC + * @param coverD + * @return + */ + public static double getConceptOverlapSimple(Set coverC, Set coverD) { + + if (coverC.size() == 0 || coverD.size() == 0) + return 0; + + //compute the intersection between C and D + Set intersection = new HashSet(); + intersection.addAll(coverC); + intersection.retainAll(coverD); + + int commonInstances = intersection.size(); + int allInstances = coverC.size() + coverD.size() - commonInstances; + + double dissimilarity = commonInstances / (double)coverC.size(); + if (dissimilarity < (commonInstances / (double)coverD.size())) + dissimilarity = commonInstances / (double)coverD.size(); + + return commonInstances / (double)allInstances * dissimilarity; + } + + + + + /** + * This is for testing utility methods in this class + * + * @param args + */ + public static void main(String []args) { + + } + + /** + * Used to hold the fortification accuracy + * + * @author An C. Tran + * + */ + public static class FortificationResult { + public double[] fortificationCompleteness; + public double[] fortificationCorrectness; + public double[] fortificationAccuracy; + public double[] fortificationFmeasure; + + public double[] fortificationAccuracyStepByStep; + public double[] fortificationFmeasureStepByStep; + public double[] fortificationCorrectnessStepByStep; + public double[] fortificationCompletenessStepByStep; + } + + + public static int[] getMultiStepFortificationStep(long noOfCpdef) { + double[] fortificationStep = {0.05, 0.1, 0.2, 0.3, 0.4, 0.5}; //do the fortification at 5, 10, 20, 30, 40, and 50% + int noOfFortification = fortificationStep.length; + + int[] fortificationDefinitions = new int[noOfFortification]; //corresponding number of cpdef for each fortification + for (int i=0; i 10) + fortificationDefinitions[i] = (int)Math.round(Math.ceil(fortificationStep[i]*noOfCpdef)); + else { + fortificationDefinitions[i] = (i < noOfCpdef)? i+1 : (int)noOfCpdef; + } + } + + return fortificationDefinitions; + } + + + /** + * Calculate the fortification accuracy with 5%, 10%, 20%, 30%, 40% and 50% of cpdef + * and for each cpdef as well
+ * + * Steps: + * 1. Calculate the original value of the metrics (without fortification) + * 2. For each CPDEF: + * 1) Calculate the CPDEF coverage (pos/neg) + * 2) Accumulate the covered pos/neg + * 3) Compute common covered pos/neg between the learnt concept and CPDEF + * 4) ... + * + * @param rs Reasoner used to check coverage + * @param concept Learned concept + * @param cpdefs Set of counter partial definitions + * @param testSetPos Set of positive examples + * @param testSetNeg Set of negative examples + * + * @return Accuracy, completeness and correctness of the fortification. The first value is the value without fortification, + * the 6 next value is for fortification with 5%, 10%, 20%, 30%, 40% and 50% of the best counter partial definitions. + */ + public static FortificationResult fortifyAccuracyMultiSteps(AbstractReasonerComponent rs, OWLClassExpression concept, + SortedSet cpdefs, + Set testSetPos, + Set testSetNeg, boolean negated) { + + + double[] fortificationStepByPercent = {0.05, 0.1, 0.2, 0.3, 0.4, 0.5}; //do the fortification at 5, 10, 20, 30, 40, and 50% + int noOfFortificationStep = fortificationStepByPercent.length; + + //how many cpdef for each step? + int[] fortificationStepByDefinitions = getMultiStepFortificationStep(cpdefs.size()); + + + //contain the fortification values by PERCENTAGE + double[] fortCompletenessPercentage = new double[noOfFortificationStep+1]; //+1 for the original value, i.e. without fortification + double[] fortCorrectnessPercentage = new double[noOfFortificationStep+1]; + double[] fortAccuracyPercentage = new double[noOfFortificationStep+1]; + double[] fortFmeasurePercentage= new double[noOfFortificationStep+1]; + + //full fortification by EACH cpdef + double[] fortAccuracyFull = new double[cpdefs.size()]; + double[] fortFmeasureFull = new double[cpdefs.size()]; + double[] fortCorrectnessFull = new double[cpdefs.size()]; + double[] fortCompletenessFull = new double[cpdefs.size()]; + + + //------------------------------ + //ORIGINAL accuracy + fmeasure + // i.e. without fortification + //------------------------------ + int posSize = testSetPos.size(); + int negSize = testSetNeg.size(); + + Set conceptCp = rs.hasType(concept, testSetPos); + Set conceptCn = rs.hasType(concept, testSetNeg); + + double orgPrecision = ((conceptCp.size() + conceptCn.size()) == 0)? + 0 : conceptCp.size() / (double)(conceptCp.size() + conceptCn.size()); + double orgRecall = conceptCp.size() / (double)posSize; + double orgFmeasure = 100 * Heuristics.getFScore(orgRecall, orgPrecision); + + //store the original accuracy into the first element of the returning result + fortCompletenessPercentage[0] = 100 * conceptCp.size() / (double)posSize; + fortCorrectnessPercentage[0] = 100 * ((negSize - conceptCn.size()) / (double)negSize); + fortAccuracyPercentage[0] = 100 * (conceptCp.size() + negSize - conceptCn.size()) / (double)(posSize + negSize); + fortFmeasurePercentage[0] = orgFmeasure; + + + //---------------------------- + //start the fortification + //---------------------------- + int cpdefUsed=0; //number of cpdef used in the fortification + int fortPercentageStep = 0; + + //accumulated cp and cn + Set accumulateFortificationCp = new HashSet(); //number of pos covered by the fortification + Set accumulateFortificationCn = new HashSet(); //number of neg covered by the fortification + + int priorNoOfAccumulatedCp = conceptCp.size(); + int priorNoOfAccumulatedCn = conceptCn.size(); + + for (CELOEPartial.PartialDefinition orgCpd : cpdefs) { + + OWLClassExpression cpd; + + if (negated) //the counter partial definition is negated before (ParCEL-Ex), get the original + cpd = ((OWLObjectComplementOf)orgCpd.getDescription()).getOperand(); + else + cpd = orgCpd.getDescription(); + + + cpdefUsed++; //number of cpdef used + + //calculate cn , cp of the cpdef + Set cpdefCp = rs.hasType(cpd, testSetPos); + Set cpdefCn = rs.hasType(cpd, testSetNeg); + + + //accumulate cn, cp + accumulateFortificationCp.addAll(cpdefCp); + accumulateFortificationCn.addAll(cpdefCn); + + //---------------------------------------- + //calculate the cp and cn + Set cpTmp = new HashSet(); + Set cnTmp = new HashSet(); + cpTmp.addAll(accumulateFortificationCp); + cnTmp.addAll(accumulateFortificationCn); + + //find the common pos/neg covered by the learnt concept and cpdef + cpTmp.removeAll(conceptCp); //find the common covered pos between concept and cpdef + cnTmp.removeAll(conceptCn); //find the common covered neg between concept and cpdef + + int updatedCp = conceptCp.size() - (accumulateFortificationCp.size() - cpTmp.size()); //some pos may be removed by cpdef + int updatedCn = conceptCn.size() - (accumulateFortificationCn.size() - cnTmp.size()); //some neg may be covered by cpdef + + //----------------------------------------------- + //DISPLAY the cpdefs that change the accuracy + // Debugging purpose + //----------------------------------------------- + //if (cpTmp.size() < fortificationCp.size() || cnTmp.size() < fortificationCn.size()) { + if ((priorNoOfAccumulatedCp != updatedCp) || (priorNoOfAccumulatedCn != updatedCn)) { + logger.debug(cpdefUsed + ". " + orgCpd.getId() + ". " + + FortificationUtils.getCpdefString(orgCpd, null, null) + + ", cp=" + cpdefCp + ", cn=" + cpdefCn + //+ ", removed pos=" + (fortificationCp.size() - cpTmp.size()) + //+ ", removed neg=" + (fortificationCn.size() - cnTmp.size())); + + ", removed pos=" + (priorNoOfAccumulatedCp - updatedCp) + + ", removed neg=" + (priorNoOfAccumulatedCn - updatedCn)); + } + + + //calculate f-measure + //precision = correct pos / all pos classified = cp / (cp + cn) + //recall = correct pos / no of pos = cp / pos.size() + double precision = ((updatedCp + updatedCn) == 0)? 0 : updatedCp / (double)(updatedCp + updatedCn); + double recall = updatedCp / (double)posSize; + double fmeasure = 100 * Heuristics.getFScore(recall, precision); + + + + //---------------------------------------- + //if it is the fortification step, calculate the accuracy + if (fortPercentageStep < noOfFortificationStep && cpdefUsed >= fortificationStepByDefinitions[fortPercentageStep]) { + + fortAccuracyPercentage[fortPercentageStep+1] = 100 * (updatedCp + (negSize - updatedCn)) / (double)(posSize + negSize); + fortFmeasurePercentage[fortPercentageStep+1] = fmeasure; + fortCorrectnessPercentage[fortPercentageStep+1] = 100 * (negSize - updatedCn) / (double)negSize; + fortCompletenessPercentage[fortPercentageStep+1] = 100 * updatedCp / (double)posSize; + + fortPercentageStep++; + //if (fortStep >= noOfFortification) //if the fortification reach the max number of steps, break + // break; + + } //calculate accuracy for a fortification step + + //assign the full step value after each cpdef + //if (cpdefUsed <= fortificationDefinitions[noOfFortification-1]) { + fortAccuracyFull[cpdefUsed-1] = 100 * (updatedCp + (negSize - updatedCn)) / (double)(posSize + negSize); + fortFmeasureFull[cpdefUsed-1] = fmeasure; + fortCorrectnessFull[cpdefUsed-1] = 100 * (negSize - updatedCn) / (double)negSize; // = un/neg (un=neg-cn) + fortCompletenessFull[cpdefUsed-1] = 100 * updatedCp / (double)posSize; + + //} + + priorNoOfAccumulatedCp = updatedCp; + priorNoOfAccumulatedCn = updatedCn; + + } //each cpdef + + + //sometime, the number of cpdef is too small ==> some fortification steps are not assigned the value + //therefore, we need to assign value for them + while (fortPercentageStep < noOfFortificationStep) { + fortAccuracyPercentage[fortPercentageStep+1] = fortAccuracyPercentage[fortPercentageStep]; + fortFmeasurePercentage[fortPercentageStep+1] = fortFmeasurePercentage[fortPercentageStep]; + fortCorrectnessPercentage[fortPercentageStep+1] = fortCorrectnessPercentage[fortPercentageStep]; + fortCompletenessPercentage[fortPercentageStep+1] = fortCompletenessPercentage[fortPercentageStep]; + fortPercentageStep++; + } + + //return the result + + FortificationResult result = new FortificationResult(); + + //percentage + result.fortificationCompleteness = fortCompletenessPercentage; + result.fortificationCorrectness = fortCorrectnessPercentage; + result.fortificationAccuracy = fortAccuracyPercentage; + result.fortificationFmeasure = fortFmeasurePercentage; + + //full steps + result.fortificationAccuracyStepByStep = fortAccuracyFull; + result.fortificationFmeasureStepByStep = fortFmeasureFull; + result.fortificationCorrectnessStepByStep = fortCorrectnessFull; + result.fortificationCompletenessStepByStep = fortCompletenessFull; + + return result; + + } //fortify method + + + /** + * Sort descreasingly according to the additional value of the fortifying definitions + * + * @author An C. Tran + * + */ + public static class AdditionalValueComparator implements Comparator { + int index = 0; + boolean descending; + + public AdditionalValueComparator(int index) { + this.index = index; + this.descending = true; + } + + + public AdditionalValueComparator(int index, boolean descending) { + this.index = index; + this.descending = descending; + } + + + @Override + public int compare(CELOEPartial.PartialDefinition pdef1, CELOEPartial.PartialDefinition pdef2) { + if (pdef1.getAdditionValue(index) > pdef2.getAdditionValue(index)) { + if (this.descending) + return -1; + else + return 1; + } + else if (pdef1.getAdditionValue(index) < pdef2.getAdditionValue(index)) { + if (this.descending) + return 1; + else + return -1; + } + else + return pdef1.getDescription().compareTo(pdef2.getDescription()); + + } + + } + +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/JaccardSimilarity.java b/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/JaccardSimilarity.java new file mode 100644 index 0000000000..70697babe3 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/fortification/JaccardSimilarity.java @@ -0,0 +1,473 @@ +package org.dllearner.cli.parcel.fortification; + +/* + * This file is part of the OWL API. + * + * The contents of this file are subject to the LGPL License, Version 3.0. + * + * Copyright (C) 2011, The University of Manchester + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + * + * Alternatively, the contents of this file may be used under the terms of the Apache License, Version 2.0 + * in which case, the provisions of the Apache License Version 2.0 are applicable instead of those above. + * + * Copyright 2011, University of Manchester + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.log4j.Logger; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.*; +import org.semanticweb.owlapi.reasoner.OWLReasoner; + + +public class JaccardSimilarity { + + private int INDENT = 4; + OWLReasoner reasoner; + //PelletReasoner pellet; + + Logger logger = Logger.getLogger(this.getClass()); + + private OWLDataFactory df = OWLManager.getOWLDataFactory(); + + public JaccardSimilarity(OWLReasoner reasoner) { + this.reasoner = reasoner; + //pellet = new PelletReasonerFactory().createNonBufferingReasoner(reasoner.getRootOntology()); + } + + /** Print the class hierarchy for the given ontology from this class down, + * assuming this class is at the given level. Makes no attempt to deal + * sensibly with multiple inheritance. */ + public void printHierarchy(OWLClass clazz) throws OWLException { + printHierarchy(reasoner, clazz, 0); + } + + + /** Print the class hierarchy from this class down, assuming this class is at + * the given level. Makes no attempt to deal sensibly with multiple + * inheritance. */ + private void printHierarchy(OWLReasoner reasoner, OWLClass clazz, int level) + throws OWLException { + /* + * Only print satisfiable classes -- otherwise we end up with bottom + * everywhere + */ + if (reasoner.isSatisfiable(clazz)) { + for (int i = 0; i < level * INDENT; i++) { + System.out.print(" "); + } + System.out.println(clazz); + /* Find the children and recurse */ + for (OWLClass child : reasoner.getSubClasses(clazz, true).getFlattened()) { + if (!child.equals(clazz)) { + printHierarchy(reasoner, child, level + 1); + } + } + } + } + + + /** + * Get all subclasses of a NamedClass (DLLearner API) + * + * @param clazz + * @return + */ + Set getsubClasses(OWLClassExpression clazz) { + return reasoner.getSubClasses(clazz, false) + .getNodes().stream() + .filter(n -> !n.isBottomNode()) + .flatMap(n -> n.getEntities().stream()) + .collect(Collectors.toSet()); + } + + + /** + * Get all subclasses of a OWLClass (OWLAPI) + * @param clazz + * @return + */ + Set getsubClasses(OWLClass clazz) { + return reasoner.getSubClasses(clazz, false).getFlattened(); + } + + + + /** + * Get Jaccard overlap (score) between two concepts. + * + * @return + * @throws Exception + */ + /* + public double getJaccardSimilaritySimple(Description des1, Description des2) throws Exception { + + Intersection conjunc = new Intersection(des1, des2); + + if (!reasoner.isSatisfiable(OWLAPIConverter.getOWLAPIDescription(conjunc))) { + //PelletExplanation exp = new PelletExplanation(pellet); + + //System.out.println("Unsatisfiable expression: \"" + conjunc + " --> " + pellet.isSatisfiable(OWLAPIConverter.getOWLAPIDescription(conjunc))); + //System.out.println("Explanation: " + exp.getUnsatisfiableExplanation(OWLAPIConverter.getOWLAPIDescription(conjunc))); + + return 0; + } + + Set flattenD1 = Orthogonality.flattenDescription(des1); + Set flattenD2 = Orthogonality.flattenDescription(des2); + + Set subclassesD1 = new HashSet(); + Set subclassesD2 = new HashSet(); + + OWLClass nothing = (OWLClass)reasoner.getBottomClassNode().getEntities().toArray()[0]; + + for (NamedKBElement d1 : flattenD1) { + if (d1 instanceof NamedClass) { + Set subClasses = this.getsubClasses((NamedClass)d1); + subClasses.remove(nothing); + + if (subClasses.size() == 0) + subclassesD1.add(d1); + + for (OWLClass c : subClasses) + subclassesD1.add(new NamedClass(c.getIRI().toString())); + } + else + subclassesD1.add((Property)d1); + } + + for (NamedKBElement d2 : flattenD2) { + if (d2 instanceof NamedClass) { + Set subClasses = this.getsubClasses((NamedClass)d2); + subClasses.remove(nothing); + + if (subClasses.size() == 0) + subclassesD2.add(d2); + + for (OWLClass c : subClasses) + subclassesD2.add(new NamedClass(c.getIRI().toString())); + } + else + subclassesD2.add((Property)d2); + } + + + int d1Size = subclassesD1.size(); + int d2Size = subclassesD2.size(); + + Set commonElements = new HashSet(); + commonElements.addAll(subclassesD1); + commonElements.retainAll(subclassesD2); + + int noOfCommonElements = commonElements.size(); + + //System.out.println("Set 1 (" + subclassesD1.size() + "): " + subclassesD1); + //System.out.println("Set 2 (" + subclassesD2.size() + "): " + subclassesD2); + + + //subclassesD1.removeAll(subclassesD2); + //int noOfCommonElements = d1Size - subclassesD1.size(); + + //if (noOfCommonElements != commonElements.size()) + // throw new Exception("jaccard similarity calculation error: intersection works wrong"); + + + //process the equivalent classes + //Set equivClassess = new TreeSet(); + for (NamedKBElement c : subclassesD1) { + if (c instanceof NamedClass) { + Set equivClassessTmp = reasoner.getEquivalentClasses(OWLAPIConverter.getOWLAPIDescription((NamedClass)c)).getEntities(); + + if (equivClassessTmp.size() > 1) { + Set tmp = new HashSet(); + + //convert equiv class into NamedClass(es) + for (OWLClass ec : equivClassessTmp) + tmp.add(new NamedClass(ec.getIRI().toString())); + + tmp.removeAll(subclassesD2); + if (tmp.size() < equivClassessTmp.size()) + for (OWLClass ec : equivClassessTmp) + commonElements.add(new NamedClass(ec.getIRI().toString())); + } + + } + } + + //System.out.println("Common elements (" + commonElements.size() + "): " + commonElements); + + double score = (commonElements.size())/(double)(d1Size + d2Size - noOfCommonElements); + + return score; + } + + + + /** + * Get Jaccard overlap (score) between two concepts in normal form. + * Step: i) get all concepts, ii) get all roles, iii) call function for computation of concept similarity, + * iv) call function for computation of role similarity, v) combine the results. + * + * @return + * @throws Exception + */ + public double getJaccardSimilarityComplex(OWLClassExpression des1, OWLClassExpression des2) throws Exception { + + OWLClassExpression conjunc = df.getOWLObjectIntersectionOf(des1, des2); + + if (!reasoner.isSatisfiable(conjunc)) { + //PelletExplanation exp = new PelletExplanation(pellet); + + //System.out.println("Unsatisfiable expression: \"" + conjunc + " --> " + pellet.isSatisfiable(OWLAPIConverter.getOWLAPIDescription(conjunc))); + //System.out.println("Explanation: " + exp.getUnsatisfiableExplanation(OWLAPIConverter.getOWLAPIDescription(conjunc))); + + return 0; + } + + + //get all concepts and roles + Set conceptD1 = ConceptSimilarity.primSet(des1); + Set conceptD2 = ConceptSimilarity.primSet(des2); + + Set allPropertiesD1 = ConceptSimilarity.getPropertySet(des1); + Set allPropertiesD2 = ConceptSimilarity.getPropertySet(des1); + + + //separate object and datatype properties + Set objPropertiesD1 = new HashSet<>(); + Set objPropertiesD2 = new HashSet<>(); + + for (OWLPropertyExpression p : allPropertiesD1) + if (!p.isAnonymous()) + objPropertiesD1.add(p); + + for (OWLPropertyExpression p : allPropertiesD2) + if (!p.isAnonymous()) + objPropertiesD2.add(p); + + + //calculate the similarity for concepts + double totalConceptSim = 0; + + if (conceptD1.size() == 0) //if a description has no primitive concept, it is considered as TOP + conceptD1.add(df.getOWLThing()); + if (conceptD2.size() == 0) + conceptD2.add(df.getOWLThing()); + + for (OWLClassExpression d1 : conceptD1) { + for (OWLClassExpression d2 : conceptD2) { + totalConceptSim += simPrim(d1, d2); + } //for each flattenD2 + } //for each flattenD1 + + //concept similarity = avg. of the total similarity between concepts between two descriptions + double conceptScore = totalConceptSim / (conceptD1.size() * conceptD2.size()); + + + //calculate the similarity for roles + Set commonObjProperties = new HashSet<>(); + commonObjProperties.addAll(objPropertiesD1); + commonObjProperties.retainAll(objPropertiesD2); + + double roleScore = 0; + if (commonObjProperties.size() > 0) { + + double totalRoleSim = 0; + //for each common property of the descriptions, calculate the similarity between their range + for (OWLPropertyExpression pro : commonObjProperties) { + OWLClassExpression rangeD1 = ConceptSimilarity.val(pro, des1); //get the range of the property + OWLClassExpression rangeD2 = ConceptSimilarity.val(pro, des2); + + + //get the concepts in the range of the properties + Set conceptValD1 = ConceptSimilarity.primSet(rangeD1); + Set conceptValD2 = ConceptSimilarity.primSet(rangeD2); + + //calculate the similarity for concepts + double roleValSim = 0; + if ((conceptValD1.size() > 0) && (conceptValD2.size() > 0)) { //when is this false??? + for (OWLClassExpression d1 : conceptValD1) { + for (OWLClassExpression d2 : conceptValD2) { + roleValSim += simPrim(d1, d2); + } //for each flattenD2 + } //for each flattenD1 + + roleValSim /= conceptValD1.size() * conceptValD2.size(); + } + + + //double roleValSim = this.getJaccardSimilarityComplex(rangeD1, rangeD2); + + totalRoleSim += roleValSim; + + } //for each common object property + + roleScore = totalRoleSim / commonObjProperties.size(); + + } //if there exists common property + + //return (simCon + simRole)/alpha; + + if (commonObjProperties.size() > 0) + return (conceptScore + roleScore)/2d; + else + return conceptScore; + } + + + + /** + * Compute jaccard similarity between two disjunctive normal concepts + * 1. normalise + * 2. compute max of the overlap + * + * @param d1 + * @param d2 + * @return + * @throws Exception + */ + public double getJaccardDisjunctiveSimilarity(OWLClassExpression d1, OWLClassExpression d2) throws Exception { + OWLClassExpression normalisedC = FortificationUtils.normalise(d1); + OWLClassExpression normalisedD = FortificationUtils.normalise(d2); + + List flattenedC = FortificationUtils.flattenDisjunctiveNormalDescription(normalisedC); + List flattenedD = FortificationUtils.flattenDisjunctiveNormalDescription(normalisedD); + + + double maxJSim = 0; + for (OWLClassExpression c : flattenedC) { + for (OWLClassExpression d : flattenedD) { + double sim = this.getJaccardSimilarityComplex(c, d); + if (maxJSim < sim) + maxJSim = sim; + } + } + + return maxJSim; + } + + /** + * Calculate the Jaccard similarity between two primitive concepts + * + * @param d1 + * @param d2 + * + * @return Jaccard similarity between d1 and d2 + * @throws Exception + */ + public double simPrim(OWLClassExpression d1, OWLClassExpression d2) throws Exception { + //if (!(d1 instanceof NamedClass) || !(d2 instanceof NamedClass)) + // throw new Exception("simPrim() requires two NamedClass (OWLClass) objects (d1: " + d1.getClass() + ", d2: " + d2.getClass()); + + if (d1 instanceof OWLObjectComplementOf) + return 1 - simPrim(((OWLObjectComplementOf) d1).getOperand(), d2); + + if (d2 instanceof OWLObjectComplementOf) + return 1 - simPrim(d1, ((OWLObjectComplementOf) d2).getOperand()); + + Set subClassesD1 = getsubClasses(d1); + Set subClassesD2 = getsubClasses(d2); + + if (subClassesD1.size() == 0) + subClassesD1.add(d1); + + if (subClassesD2.size() == 0) + subClassesD2.add(d2); + + int d1Size = subClassesD1.size(); + int d2Size = subClassesD2.size(); + + Set commonElements = new HashSet<>(subClassesD1); + commonElements.retainAll(subClassesD2); + + //common element without equivalent + int noOfCommonElements = commonElements.size(); + + //System.out.println("Set 1 (" + subClassesD1.size() + "): " + subClassesD1); + //System.out.println("Set 2 (" + subClassesD2.size() + "): " + subClassesD2); + + + //process the equivalent classes + //if a set of equivalent classes + for (OWLClassExpression c : subClassesD1) { + Set equivClassessTmp = reasoner.getEquivalentClasses(c).getEntities(); + + if (equivClassessTmp.size() > 1) { + + Set tmp = new HashSet<>(equivClassessTmp); + tmp.removeAll(subClassesD2); + + if (tmp.size() < equivClassessTmp.size()) { + commonElements.addAll(equivClassessTmp); + } + + } + } //for (process equivalent classes + + double score = (commonElements.size())/(double)(d1Size + d2Size - noOfCommonElements); + + //System.out.println("Common elements (" + commonElements.size() + "): " + commonElements); + //System.out.println("simPrim (" + d1 + ", " + d2 + ") = " + score); + + return score; + } + + + /** + * + * @param pro1 + * @param pro2 + * @return + */ + /* + public double simRoles(PropertyExpression pro1, PropertyExpression pro2) { + + return 0; + } + */ + /** + * Get Jaccard distance of two descriptions (= 1 - jaccard overlap(d1, d2)) + * + * @param des1 + * @param des2 + * @return + * @throws Exception + */ + /* + public double getJaccardDistance(Description des1, Description des2) throws Exception { + return 1 - getJaccardSimilaritySimple(des1, des2); + } + */ + +} + diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInfor.java b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInfor.java new file mode 100644 index 0000000000..2e0f8f83c5 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInfor.java @@ -0,0 +1,114 @@ +package org.dllearner.cli.parcel.modeling; + +import java.util.HashSet; +import java.util.Set; + +import org.dllearner.algorithms.parcel.reducer.ParCELReducer; + +/** + * Represents the information of a partial definition in one fold of validation, including: + *
    + *
  • training information, see {@link PhaseInfor}
  • + *
  • testing information, see {@link PhaseInfor}
  • + *
  • prediction model score
  • + *
  • actual model score
  • + *
+ * + * @author An C. Tran + * + */ +public class FoldInfor { + private int fold; + private PhaseInfor training; + private PhaseInfor testing; + + //score of the prediction model + private double predScore = Double.MIN_VALUE; + private double actualScore = Double.MIN_VALUE; + + //chosen by the reducer(s) + private Set selectedByReducers = new HashSet(); + + + /** + * Constructor + * @param fold + * @param training + * @param testing + */ + public FoldInfor(int fold, PhaseInfor training, PhaseInfor testing) { + this.fold = fold; + this.training = training; + this.testing = testing; + } + + public String toString() { + return "fold " + fold + + ": training=" + training.toString() + + ", testing=" + testing.toString(); + } + + public String getSelectedBy() { + String result = "{"; + + for (ParCELReducer reducer : selectedByReducers) + result += reducer.getClass().getSimpleName() + ","; + + if (selectedByReducers.size() > 0) + result = result.substring(0, result.length()-1); + + return result + "}"; + } + + public int getFold() { + return fold; + } + + public void setFold(int fold) { + this.fold = fold; + } + + public PhaseInfor getTraining() { + return training; + } + + public void setTraining(PhaseInfor training) { + this.training = training; + } + + public PhaseInfor getTesting() { + return testing; + } + + public void setTesting(PhaseInfor testing) { + this.testing = testing; + } + + public double getPredScore() { + return predScore; + } + + public void setPredScore(double predScore) { + this.predScore = predScore; + } + + public double getActualScore() { + return actualScore; + } + + public void setActualScore(double actualScore) { + this.actualScore = actualScore; + } + + public Set getSelectedByReducers() { + return selectedByReducers; + } + + public void setSelectedByReducers(Set selectedByReducers) { + this.selectedByReducers = selectedByReducers; + } + + + + +} \ No newline at end of file diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInforComparator.java b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInforComparator.java new file mode 100644 index 0000000000..5414ae4e78 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/FoldInforComparator.java @@ -0,0 +1,25 @@ +package org.dllearner.cli.parcel.modeling; + +import java.util.Comparator; + + +/** + * Comparator for EValInfor objects. This will be used to sort + * the EValInfor of a description based on the order of fold + * + * @author An C. Tran + * + */ +public class FoldInforComparator implements Comparator { + + @Override + public int compare(FoldInfor o1, FoldInfor o2) { + if (o1.getFold() < o2.getFold()) + return -1; + else if (o1.getFold() > o2.getFold()) + return 1; + else + return 0; + } + +} \ No newline at end of file diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELActualModelScoring.java b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELActualModelScoring.java new file mode 100644 index 0000000000..5cd0f8b673 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELActualModelScoring.java @@ -0,0 +1,90 @@ +package org.dllearner.cli.parcel.modeling; + +import java.util.Set; + +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.semanticweb.owlapi.model.OWLClassExpression; + +/** + * Scoring the partial definitions produced through the k-folds validation
+ * The scoring bases on the following dimensions: + *
    + *
  1. number of folds the partial definition involved (/total number of folds)
  2. + *
  3. coverage of the positive/negative examples in the training phase
  4. + *
  5. coverage of the positive/negative examples in the testing phase
  6. + *
  7. length of the definition (/the maximal length of all partial definitions
  8. + *
  9. etc.
  10. + *
+ * + * @author An C. Tran + * + */ +public class ParCELActualModelScoring { + + /** + * Scoring the partial definition. The scoring formula:
+ * score(d) = f(d.length, d.training_coverage, g(d.testing_accuracy), d.no_of_folds_involved) + *
    + *
  • length(+) = (1 - partial_definition_length/max_partial_definition_length)
  • + *
  • training(+) = avg(coverage)
  • + *
  • testing_completeness(+) = avg(testing_completeness)
  • + *
  • testing_correctness(-) = avg(incorrectness)
  • + *
  • number_of_folds(*) = normalise(no_of_folds_involved)
  • + *
+ * + * @param description The partial definition + * @param evalInfors Evaluation information (cp, cn, pos, neg, etc.) + * @param totalNoOfFolds Total of folds used in the evaluation + * @param maxLength Length of the longest partial definition + * + * @return Score of the input description + * + * TODO: Should we use the avg. length instead of max length? + */ + public static double scoring(OWLClassExpression description, + Set evalInfors, int totalNoOfFolds, int maxLength) + { + double foldingFactor = 1.5; //bonus (strong) + double lengthFactor = 0.6; //penalise the long partial definitions + double trainingCompletenessFactor = 0.8; //bonus + double testingCompletenessFactor = 1.0; //bonus + double testingIncorrectnessFactor = 1.8; //penalise on false positive (strong) + + double foldingScore = 0; // score from the number of folds the + double lengthScore = 0; + double trainingScore = 0; + double testingCompletenessScore = 0; + double testingIncorrectnessScore = 0; + + // folding and length scores + foldingScore = evalInfors.size() / (double) totalNoOfFolds; //bonus + lengthScore = (1 - OWLClassExpressionUtils.getLength(description) / (double) maxLength); //bonus + + // training and testing score + for (FoldInfor evalInfor : evalInfors) { + // training: only number of covered positive examples make sense + trainingScore += evalInfor.getTraining().getCp() + / (double) evalInfor.getTraining().getNoOfPositiveExamples(); + + // testing: both + testingCompletenessScore += evalInfor.getTesting().getCp() + / (double) evalInfor.getTesting().getNoOfPositiveExamples(); + testingIncorrectnessScore += evalInfor.getTesting().getCn() + / (double) evalInfor.getTesting().getNoOfNegativeExamples(); + } + + // divide training score, testing scos by the number of folds the description is involved + trainingScore /= evalInfors.size(); + testingCompletenessScore /= evalInfors.size(); + testingIncorrectnessScore /= evalInfors.size(); + + // aggregate the score + double score = foldingScore * foldingFactor + + trainingScore * trainingCompletenessFactor + + testingCompletenessScore * testingCompletenessFactor + - testingIncorrectnessScore * testingIncorrectnessFactor + + lengthScore * lengthFactor; + + return score; + } +} diff --git a/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELPredictionModelScoring.java b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELPredictionModelScoring.java new file mode 100644 index 0000000000..f83b8db522 --- /dev/null +++ b/interfaces/src/main/java/org/dllearner/cli/parcel/modeling/ParCELPredictionModelScoring.java @@ -0,0 +1,212 @@ +package org.dllearner.cli.parcel.modeling; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.dllearner.algorithms.parcel.ParCELExtraNode; +import org.dllearner.utilities.owl.OWLClassExpressionUtils; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; + + +/** + * This class implements the scoring function for the intended model. + * This will be used to score the partial definitions given the information + * output from the learner: + *
    + *
  • Total number of definitions
  • + *
  • Total number of reduced partial definition
  • + *
  • Definition length
  • + *
  • Covered positive examples
  • + *
  • Covered negative examples
  • + *
  • Other partial definitions' information
  • + *
+ * + * @author An C. Tran + * + */ +public class ParCELPredictionModelScoring { + + /** + * NOTE: This should take all partial definitions since the score of a description + * is relatively effected by the other partial definitions.
+ * + * Algorithm: score(d) = f(d.length, d.coverage) + * + * @param description An ParCELExtraNode which contains the description (partial definition) + * and some related information such as cp, cn, etc. + * @param noOfPositiveExamples Total number of positive examples used in the learning + * + * @return Score of the partial definition + */ + public static double scoringSimple(ParCELExtraNode description, int noOfPositiveExamples, int maxLength) { + + double lengthFactor = 0.7; + double coverageFactor = 1.0; + + //1st strategy: cp, length + double lengthScore = OWLClassExpressionUtils.getLength(description.getDescription()) / (double)maxLength; + double coverageScore = description.getCompleteness(); + + return coverageScore*coverageFactor - lengthScore*lengthFactor; + } + + + /** + * Algorithm: score(d) = f(d.length, g(d.coverage), d.coverage), in which function g() calculates the + * relative coverage score. + * + * @param partialDefinitions Set of partial definition + * @return + */ + public static Map scoringComplex(Set partialDefinitions, + Set positiveExamples) + { + //factors, that are used to adjust the scores of dimensions + double lengthFactor = 0.3; + double relativeCoverageFactor = 1.0; + + Map scoringResult = new HashMap(); + + int maxLength = 0; + int maxCoverage = 0; + + //get the global information such as max length, etc. + for (ParCELExtraNode pdef : partialDefinitions) { + //max length + int curLength = OWLClassExpressionUtils.getLength(pdef.getDescription()); + if (curLength > maxLength) + maxLength = curLength; + + //max coverage + int curCoverage = pdef.getCoveredPositiveExamples().size(); + if (maxCoverage < curCoverage) + maxCoverage = curCoverage; + } + + + /*---------------------------------------------------------------------- + * scoring relative coverage of a set of pdefs + * + * for each pdef, maintain 2 lists of cp (coverage positive examples): + * -new cp: covered pos. examples in the uncovered examples + * -old cp: covered pos. examples removed by the better pdefs + * + * 0) if pdefs = empty, return + * 1) pick the "best" pdef (highest cp) + * -score the coverage based on the new cp ad old cp + * 2) update the rest pdefs + * 3) goto step 0 + ------------------------------------------------------------------------*/ + + Set coveredPositiveExamples = new HashSet<>(); + Set uncoveredPositiveExamples = new HashSet<>(); + + uncoveredPositiveExamples.addAll(positiveExamples); + + //duplicate the set of partial definitions + //Set pdefs = new HashSet(); + //pdefs.addAll(partialDefinitions); + + Object[] pDefs = partialDefinitions.toArray(); + + for (int i=0; i> trainingSetsPos = new LinkedList<>(); + List> trainingSetsNeg = new LinkedList<>(); + List> testingSetsPos = new LinkedList<>(); + List> testingSetsNeg = new LinkedList<>(); + + // get examples and shuffle them too + Set posExamples = lp.getPositiveExamples(); + List posExamplesList = new LinkedList<>(posExamples); + Collections.shuffle(posExamplesList, new Random(1)); + Set negExamples = lp.getNegativeExamples(); + List negExamplesList = new LinkedList<>(negExamples); + Collections.shuffle(negExamplesList, new Random(2)); + + //---------------------- + //end of setting up + //---------------------- + + // sanity check whether nr. of folds makes sense for this benchmark + if(!leaveOneOut && (posExamples.size() testPos = getTestingSet(posExamplesList, splitsPos, i); + Set testNeg = getTestingSet(negExamplesList, splitsNeg, i); + testingSetsPos.add(i, testPos); + testingSetsNeg.add(i, testNeg); + trainingSetsPos.add(i, getTrainingSet(posExamples, testPos)); + trainingSetsNeg.add(i, getTrainingSet(negExamples, testNeg)); + } + + + //runtime + runtime = new Stat(); + noOfPartialDef = new Stat(); + partialDefinitionLength = new Stat(); + length = new Stat(); + accuracyTraining = new Stat(); + trainingCorrectnessStat= new Stat(); + trainingCompletenessStat = new Stat(); + accuracy = new Stat(); + testingCorrectnessStat = new Stat(); + testingCompletenessStat = new Stat(); + + + //hold all partial definitions for further analysis + Map> allPartialDefinitions = new TreeMap>(); + SortedSet allReducedPartialDefinitions = new TreeSet(); + + for(int currFold=0; (currFold pos = Datastructures.individualSetToStringSet(trainingSetsPos.get(currFold)); + //Set neg = Datastructures.individualSetToStringSet(trainingSetsNeg.get(currFold)); + lp.setPositiveExamples(trainingSetsPos.get(currFold)); + lp.setNegativeExamples(trainingSetsNeg.get(currFold)); + + try { + lp.init(); + la.init(); + } catch (ComponentInitException e) { + e.printStackTrace(); + } + + long algorithmStartTime = System.nanoTime(); + try { + la.start(); + } + catch (OutOfMemoryError e) { + System.out.println("out of memory at " + (System.currentTimeMillis() - algorithmStartTime)/1000 + "s"); + } + + long algorithmDuration = System.nanoTime() - algorithmStartTime; + runtime.addNumber(algorithmDuration/(double)1000000000); + + OWLClassExpression concept = parcel.getUnionCurrentlyBestDescription(); + + Set tmp = rs.hasType(concept, trainingSetsPos.get(currFold)); + Set tmp2 = Sets.difference(trainingSetsPos.get(currFold), tmp); + Set tmp3 = rs.hasType(concept, trainingSetsNeg.get(currFold)); + + outputWriter("training set errors pos (" + tmp2.size() + "): " + tmp2); + outputWriter("training set errors neg (" + tmp3.size() + "): " + tmp3); + + + tmp = rs.hasType(concept, testingSetsPos.get(currFold)); + tmp2 = Sets.difference(testingSetsPos.get(currFold), tmp); + tmp3 = rs.hasType(concept, testingSetsNeg.get(currFold)); + + outputWriter("test set errors pos: " + tmp2); + outputWriter("test set errors neg: " + tmp3); + + tmp = rs.hasType(concept, testingSetsPos.get(currFold)); + tmp2 = Sets.difference(testingSetsPos.get(currFold), tmp); + tmp3 = rs.hasType(concept, testingSetsNeg.get(currFold)); + + outputWriter("test set errors pos: " + tmp2); + outputWriter("test set errors neg: " + tmp3); + + // calculate training accuracies + int trainingCorrectPosClassified = getCorrectPosClassified(rs, concept, trainingSetsPos.get(currFold)); + int trainingCorrectNegClassified = getCorrectNegClassified(rs, concept, trainingSetsNeg.get(currFold)); + int trainingCorrectExamples = trainingCorrectPosClassified + trainingCorrectNegClassified; + double trainingAccuracy = 100*((double)trainingCorrectExamples/(trainingSetsPos.get(currFold).size()+ + trainingSetsNeg.get(currFold).size())); + + double trainingCompleteness = 100*(double)trainingCorrectPosClassified/trainingSetsPos.get(currFold).size(); + double trainingCorrectness = 100*(double)trainingCorrectNegClassified/trainingSetsNeg.get(currFold).size(); + + accuracyTraining.addNumber(trainingAccuracy); + trainingCompletenessStat.addNumber(trainingCompleteness); + trainingCorrectnessStat.addNumber(trainingCorrectness); + + // calculate test accuracies + int correctPosClassified = getCorrectPosClassified(rs, concept, testingSetsPos.get(currFold)); + int correctNegClassified = getCorrectNegClassified(rs, concept, testingSetsNeg.get(currFold)); + int correctExamples = correctPosClassified + correctNegClassified; + double currAccuracy = 100*((double)correctExamples/(testingSetsPos.get(currFold).size()+ + testingSetsNeg.get(currFold).size())); + + double testingCompleteness = 100*(double)correctPosClassified/testingSetsPos.get(currFold).size(); + double testingCorrectness = 100*(double)correctNegClassified/testingSetsNeg.get(currFold).size(); + + accuracy.addNumber(currAccuracy); + testingCompletenessStat.addNumber(testingCompleteness); + testingCorrectnessStat.addNumber(testingCorrectness); + + + // calculate training F-Score + int negAsPosTraining = rs.hasType(concept, trainingSetsNeg.get(currFold)).size(); + double precisionTraining = trainingCorrectPosClassified + negAsPosTraining == 0 ? 0 : trainingCorrectPosClassified / (double) (trainingCorrectPosClassified + negAsPosTraining); + double recallTraining = trainingCorrectPosClassified / (double) trainingSetsPos.get(currFold).size(); + fMeasureTraining.addNumber(100*Heuristics.getFScore(recallTraining, precisionTraining)); + // calculate test F-Score + int negAsPos = rs.hasType(concept, testingSetsNeg.get(currFold)).size(); + double precision = correctPosClassified + negAsPos == 0 ? 0 : correctPosClassified / (double) (correctPosClassified + negAsPos); + double recall = correctPosClassified / (double) testingSetsPos.get(currFold).size(); + // System.out.println(precision);System.out.println(recall); + fMeasure.addNumber(100*Heuristics.getFScore(recall, precision)); + + length.addNumber(OWLClassExpressionUtils.getLength(concept)); + + outputWriter("fold " + currFold + ":"); + outputWriter(" training: " + trainingCorrectPosClassified + "/" + trainingSetsPos.get(currFold).size() + + " positive and " + trainingCorrectNegClassified + "/" + trainingSetsNeg.get(currFold).size() + " negative examples"); + outputWriter(" testing: " + correctPosClassified + "/" + testingSetsPos.get(currFold).size() + " correct positives, " + + correctNegClassified + "/" + testingSetsNeg.get(currFold).size() + " correct negatives"); + outputWriter(" concept: " + concept); + outputWriter(" accuracy: " + df.format(currAccuracy) + "(corr/comp:"+ df.format(testingCorrectness) + "/" + df.format(testingCompleteness) + ")% --- " + + df.format(trainingAccuracy) + " (corr/comp:"+ df.format(trainingCorrectness) + "/" + df.format(trainingCompleteness) + ")% on training set)"); + outputWriter(" length: " + df.format(OWLClassExpressionUtils.getLength(concept))); + outputWriter(" runtime: " + df.format(algorithmDuration/(double)1000000000) + "s"); + + //this should be checked at the beginning of the cross validation since this is only for ParCEL algorithm + + int pn = ((ParCELAbstract)la).getNoOfReducedPartialDefinition(); + this.noOfPartialDef.addNumber(pn); + outputWriter(" number of partial definitions: " + pn + "/" + ((ParCELAbstract)la).getNumberOfPartialDefinitions()); + + double pl = OWLClassExpressionUtils.getLength(concept)/(double)pn; + this.partialDefinitionLength.addNumber(pl); + outputWriter(" avarage partial definition length: " + pl); + + + /* + * Analyse the partial definitions + */ + + //reduced partial definitions of the current fold + SortedSet foldReducedPartialDefinitions = parcel.getReducedPartialDefinition(); + + + for (ParCELExtraNode node : foldReducedPartialDefinitions) + allReducedPartialDefinitions.add(node.getDescription()); + + //infer and display the partial definition information + outputWriter("---------- Fold " + currFold + " -----------"); + Set foldPartialDefinitions = parcel.getPartialDefinitions(); + + //int count=1; + Set trainingPos = trainingSetsPos.get(currFold); + Set trainingNeg = trainingSetsNeg.get(currFold); + Set testingPos = testingSetsPos.get(currFold); + Set testingNeg = testingSetsNeg.get(currFold); + + //------------------ + // PREDICTION model + //------------------ + + //calculate prediction-model-score for all partial definition generated of the current fold + Map predictionScores = ParCELPredictionModelScoring.scoringComplex( + foldPartialDefinitions, trainingPos); + + //----------------------- + // calculate fold infor + //----------------------- + for (ParCELExtraNode def : foldPartialDefinitions) { + + Set trainingCoveredPos = rs.hasType(def.getDescription(), trainingPos); + Set trainingCoveredNeg = rs.hasType(def.getDescription(), trainingNeg); + Set testingCoveredPos = rs.hasType(def.getDescription(), testingPos); + Set testingCoveredNeg = rs.hasType(def.getDescription(), testingNeg); + + //add partial definition into the partial definition set + Set valInfor = new TreeSet(new FoldInforComparator()); + PhaseInfor trainingInfor = new PhaseInfor(trainingPos.size(), + trainingNeg.size(), trainingCoveredPos.size(), + trainingCoveredNeg.size()); + PhaseInfor testingInfor = new PhaseInfor(testingPos.size(), + testingNeg.size(), testingCoveredPos.size() , testingCoveredNeg.size()); + if (!allPartialDefinitions.containsKey(def.getDescription())) { + //if the description is in the list before, just add the evaluation info for that description + valInfor.add(new FoldInfor(currFold, trainingInfor, testingInfor)); + allPartialDefinitions.put(def.getDescription(), valInfor); + } + else { + //if the description is in the set of partial definition before, just add new evaluation info + allPartialDefinitions.get(def.getDescription()).add(new FoldInfor(currFold, trainingInfor, testingInfor)); + } + } + + //store intended score of the current fold into all partial definitions set + for (OWLClassExpression des : predictionScores.keySet()) { + //if the description is in the list of all partial definition + if (allPartialDefinitions.containsKey(des)) { + + //check for the corresponding fold and assign the score + boolean found = false; + for (FoldInfor fold : allPartialDefinitions.get(des)) { + if (fold.getFold() == currFold) { + fold.setPredScore(predictionScores.get(des)); + found = true; + break; + } + } + + if (!found) + logger.error("Cannot find the corresponding fold for the partial definition"); + } + else { + logger.error("Cannot find the partial definition in all partial definitions set"); + } + + } + + } //for k folds + + + //--------------------------------- + //end of k-fold cross validation + //output result of the k-fold + //--------------------------------- + + outputWriter(""); + outputWriter("Finished " + folds + "-folds cross-validation."); + outputWriter("runtime: " + statOutput(df, runtime, "s")); + outputWriter("#partial definitions: " + statOutput(df, noOfPartialDef, "")); + outputWriter("avg. partial definition length: " + statOutput(df, partialDefinitionLength, "")); + outputWriter("length: " + statOutput(df, length, "")); + outputWriter("F-Measure on training set: " + statOutput(df, fMeasureTraining, "%")); + outputWriter("F-Measure: " + statOutput(df, fMeasure, "%")); + outputWriter("predictive accuracy on training set: " + statOutput(df, accuracyTraining, "%") + " - corr/comp: " + + statOutput(df, trainingCorrectnessStat, "%") + "/" + statOutput(df, trainingCompletenessStat, "%")); + outputWriter("predictive accuracy: " + statOutput(df, accuracy, "%") + " - corr/comp: " + + statOutput(df, testingCorrectnessStat, "%") + "/" + statOutput(df, testingCompletenessStat, "%")); + + //display all partial definitions information produced in the validation group by partial definition + outputWriter("======================================="); + outputWriter("Partial definitions"); + outputWriter("======================================="); + int count=1; + for (OWLClassExpression def : allPartialDefinitions.keySet()) { + + double aScore = ParCELActualModelScoring.scoring(def, allPartialDefinitions.get(def), + folds, (int)partialDefinitionLength.getMax()); + + outputWriter(count++ + (allReducedPartialDefinitions.contains(def)?"* ":". ") + + def + + ", length=" + OWLClassExpressionUtils.getLength(def) + + ", folds=" + allPartialDefinitions.get(def).size() + + ", aScore=" + df.format(aScore)); + + for (FoldInfor info : allPartialDefinitions.get(def)) { + + //currently, actual score bases on the overall information of k-folds + //therefore, actual model score of a partial definition is equal for all folds + info.setActualScore(aScore); + + outputWriter("\t-" + info.toString() + ", pScore=" + df.format(info.getPredScore())); + } + } + + //display all partial definitions information produced in the validation group by partial definition + + for (int curFold=0; curFold + * The basic information includes: + *
    + *
  • number of positive/negative examples used in the training/testing
  • + *
  • number of positive/negative examples covered by the partial definition
  • + *
+ * + * @author An C. Tran + * + */ +public class PhaseInfor { + private int noOfPositiveExamples; + private int noOfNegativeExamples; + private int cp; //covered positive examples + private int cn; //uncovered negative examples + + public PhaseInfor(int noPos, int noNeg, int cp, int cn) { + this.noOfPositiveExamples = noPos; + this.noOfNegativeExamples = noNeg; + this.cp = cp; + this.cn = cn; + } + + public String toString() { + return "(" + cp + "/" + noOfPositiveExamples + "," + cn + "/" + noOfNegativeExamples + ")"; + } + + public int getNoOfPositiveExamples() { + return noOfPositiveExamples; + } + + public void setNoOfPositiveExamples(int noOfPositiveExamples) { + this.noOfPositiveExamples = noOfPositiveExamples; + } + + public int getNoOfNegativeExamples() { + return noOfNegativeExamples; + } + + public void setNoOfNegativeExamples(int noOfNegativeExamples) { + this.noOfNegativeExamples = noOfNegativeExamples; + } + + public int getCp() { + return cp; + } + + public void setCp(int cp) { + this.cp = cp; + } + + public int getCn() { + return cn; + } + + public void setCn(int cn) { + this.cn = cn; + } + + + + +} \ No newline at end of file From fc7f4a89246de469a63ae883b5434c4049669e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Wed, 1 Mar 2023 17:13:57 +0100 Subject: [PATCH 03/67] parcel operator integration, useNegation support enhanced, test evaluation --- .../org/dllearner/algorithms/celoe/CELOE.java | 4 + .../org/dllearner/algorithms/ocel/OCEL.java | 10 ++ .../algorithms/parcel/ParCELPosNegLP.java | 51 ++++++- .../algorithms/parcel/ParCELearner.java | 12 ++ .../parcelex/ParCELearnerExV12.java | 8 + .../dllearner/learningproblems/PosNegLP.java | 37 +++++ .../refinementoperators/RhoDRDown.java | 144 +++++++++++------- .../dllearner/cli/ExpressionValidation.java | 45 ++++-- 8 files changed, 249 insertions(+), 62 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index 88162a85a4..bb9f959fe5 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -415,6 +415,10 @@ public void start() { // print solution(s) logger.info("solutions:\n" + getSolutionString()); + if (learningProblem instanceof PosNegLP) { + ((PosNegLP) learningProblem).printTestEvaluation(bestEvaluatedDescriptions.getBest().getDescription()); + } + printBestConceptsTimesAndAccuracies(); isRunning = false; diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index 3f003c4d40..920567fa80 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -608,6 +608,9 @@ public void start() { logger.info("no appropriate solutions found (try increasing the noisePercentage parameter to what was reported as most accurate expression found above)"); } + if (learningProblem instanceof PosNegLP) { + ((PosNegLP) learningProblem).printTestEvaluation(bestNodeStable.getConcept()); + } printBestConceptsTimesAndAccuracies(); @@ -839,6 +842,13 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, } } +// Set newlyCoveredPositives = reasoner.hasType(refinement, positiveExamples); +// Set newlyCoveredNegatives = reasoner.hasType(refinement, negativeExamples); +// int misclassifiedPositives = nrOfPositiveExamples - newlyCoveredPositives.size(); +// +// if (misclassifiedPositives > allowedMisclassifications) +// quality = -1; + propernessCalcReasoningTimeNs += System.nanoTime() - propCalcReasoningStart2; newNode.setQualityEvaluationMethod(ExampleBasedNode.QualityEvaluationMethod.REASONER); // TODO: MY use noise or remove noise variable entirely diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java index 429feea0f2..b664679047 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -14,6 +14,7 @@ import java.util.HashSet; import java.util.TreeSet; +import org.apache.log4j.Logger; import org.dllearner.core.*; import org.dllearner.core.config.ConfigOption; import org.semanticweb.owlapi.model.OWLClassExpression; @@ -33,7 +34,7 @@ public class ParCELPosNegLP extends AbstractClassExpressionLearningProblem uncoveredPositiveExamples; - // private Logger logger = Logger.getLogger(this.getClass()); + private final Logger logger = Logger.getLogger(ParCELPosNegLP.class); // reasoner component is declared in AbstractLearningProblem class @@ -636,5 +637,53 @@ public Set getPositiveTestExamples() { public Set getNegativeTestExamples() { return this.negativeTestExamples; } + + public void printTestEvaluation(Set partialDefinitions) { + Set tp = new TreeSet<>(); + + for (OWLClassExpression def : partialDefinitions) { + tp.addAll(reasoner.hasType(def, positiveTestExamples)); + } + + Set fn = new TreeSet<>(positiveTestExamples); + fn.removeAll(tp); + + Set fp = new TreeSet<>(); + + for (OWLClassExpression def : partialDefinitions) { + Set defFP = reasoner.hasType(def, negativeTestExamples); + + for (OWLIndividual ex : defFP) { + logger.info("Partial definition: " + def); + logger.info("False positive: " + ex.toStringID()); + } + + fp.addAll(defFP); + } + + Set tn = new TreeSet<>(negativeTestExamples); + tn.removeAll(fp); + + double acc = (tp.size() + tn.size()) / (double) (positiveTestExamples.size() + negativeTestExamples.size()); + double precision = tp.size() / (double) (tp.size() + fp.size()); + double rec = tp.size() / (double) (tp.size() + fn.size()); + double spec = tn.size() / (double) (fp.size() + tn.size()); + double fpr = fp.size() / (double) (fp.size() + tn.size()); + double fm = 2 / ((1 / precision) + (1 / rec)); + + logger.info("======================================================"); + logger.info("Test evaluation."); + logger.info("True positives: " + tp.size()); + logger.info("True negatives: " + tn.size()); + logger.info("False positives: " + fp.size()); + logger.info("False negatives: " + fn.size()); + + logger.info("Accuracy: " + acc); + logger.info("Precission: " + precision); + logger.info("Recall: " + rec); + logger.info("Specificity: " + spec); + logger.info("FP rate: " + fpr); + logger.info("F-measure: " + fm); + } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index 13f326713b..0f06a40ba0 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -13,21 +13,26 @@ * @author An C. Tran */ +import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.reducer.ParCELReducer; import org.dllearner.core.AbstractReasonerComponent; import org.dllearner.core.ComponentAnn; import org.dllearner.core.ComponentInitException; +import org.dllearner.learningproblems.PosNegLP; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; +import org.semanticweb.owlapi.model.OWLClassExpression; import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.management.ManagementFactory; import java.util.HashSet; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.RejectedExecutionException; +import java.util.stream.Collectors; @ComponentAnn(name = "ParCEL", shortName = "parcel", version = 0.1, description = "PARallel Class Expression Learning") public class ParCELearner extends ParCELAbstract implements ParCELearnerMBean { @@ -294,6 +299,13 @@ else if (this.isTimeout()) { } + if (learningProblem instanceof ParCELPosNegLP) { + Set partialDefs = getReducedPartialDefinition() + .stream().map(OENode::getDescription).collect(Collectors.toSet()); + + ((ParCELPosNegLP) learningProblem).printTestEvaluation(partialDefs); + } + printBestConceptsTimesAndAccuracies(); } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index b45fb4c0d2..98fa9ea73a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -23,6 +23,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.text.*; +import java.util.stream.Collectors; import org.apache.log4j.Logger; import org.dllearner.algorithms.parcel.ParCELCompletenessComparator; @@ -440,6 +441,13 @@ else if (this.isTimeout()) { } + if (learningProblem instanceof ParCELPosNegLP) { + Set partialDefs = getReducedPartialDefinition() + .stream().map(OENode::getDescription).collect(Collectors.toSet()); + + ((ParCELPosNegLP) learningProblem).printTestEvaluation(partialDefs); + } + printBestConceptsTimesAndAccuracies(); } } diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java index 36608e62bd..2cde54744e 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java @@ -35,6 +35,7 @@ import org.semanticweb.owlapi.model.OWLNamedIndividual; import org.springframework.beans.factory.annotation.Autowired; +import java.util.HashSet; import java.util.Set; import java.util.TreeSet; @@ -145,6 +146,42 @@ public double getTestAccuracyOrTooWeak(OWLClassExpression description, double no return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); } + public void printTestEvaluation(OWLClassExpression description) { + Set tp = reasoner.hasType(description, positiveTestExamples); + Set fn = new TreeSet<>(positiveTestExamples); + fn.removeAll(tp); + + Set fp = reasoner.hasType(description, negativeTestExamples); + Set tn = new TreeSet<>(negativeTestExamples); + + for (OWLIndividual ex : fp) { + logger.info("False positive: " + ex.toStringID()); + tn.remove(ex); + } + + double acc = (tp.size() + tn.size()) / (double) (positiveTestExamples.size() + negativeTestExamples.size()); + double precision = tp.size() / (double) (tp.size() + fp.size()); + double rec = tp.size() / (double) (tp.size() + fn.size()); + double spec = tn.size() / (double) (fp.size() + tn.size()); + double fpr = fp.size() / (double) (fp.size() + tn.size()); + double fm = 2 / ((1 / precision) + (1 / rec)); + + logger.info("======================================================"); + logger.info("Test evaluation."); + logger.info("Concept: " + description); + logger.info("True positives: " + tp.size()); + logger.info("True negatives: " + tn.size()); + logger.info("False positives: " + fp.size()); + logger.info("False negatives: " + fn.size()); + + logger.info("Accuracy: " + acc); + logger.info("Precission: " + precision); + logger.info("Recall: " + rec); + logger.info("Specificity: " + spec); + logger.info("FP rate: " + fpr); + logger.info("F-measure: " + fm); + } + public Set getNegativeExamples() { return negativeExamples; } diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 88b6974910..adaa5e84ed 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -27,6 +27,7 @@ import org.dllearner.reasoning.SPARQLReasoner; import org.dllearner.utilities.OWLAPIUtils; import org.dllearner.utilities.owl.ConceptTransformation; +import org.dllearner.utilities.owl.ExpressionDecomposer; import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; import org.dllearner.utilities.owl.OWLClassExpressionUtils; import org.dllearner.utilities.split.DefaultDateTimeValuesSplitter; @@ -231,6 +232,11 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C defaultValue="true") private boolean useSomeOnly = true; + @ConfigOption( + description="if set to true, concepts of the form \u2265 n r.C are refined to \u2265 n r.D, where D is a downward refinement of C, otherwise D must be a refinement of C in the upward direction", + defaultValue="false") + private boolean refineMaxCardinalityRestrictionsUpwards = false; + // caches for reasoner queries private Map> cachedDisjoints = new TreeMap<>(); @@ -243,7 +249,9 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C @ConfigOption(description = "class expression length metric (should match learning algorithm usage)", defaultValue = "default cel_metric") private OWLClassExpressionLengthMetric lengthMetric = OWLClassExpressionLengthMetric.getDefaultMetric(); - private OWLDataFactory df = new OWLDataFactoryImpl(); + + private final OWLDataFactory df = new OWLDataFactoryImpl(); + private final ExpressionDecomposer decomposer = new ExpressionDecomposer(); public RhoDRDown() {} @@ -283,6 +291,7 @@ public RhoDRDown(RhoDRDown op) { setNumericValuesSplitter(op.numericValuesSplitter); setDisjointChecks(op.disjointChecks); setLengthMetric(op.lengthMetric); + setRefineMaxCardinalityRestrictionsUpwards(op.refineMaxCardinalityRestrictionsUpwards); initialized = false; } @@ -510,6 +519,11 @@ public Set refine(OWLClassExpression description, int maxLen } refinements = (TreeSet) topARefinementsCumulative.get(currDomain).get(maxLength).clone(); } + + if (!useNegation) { + refinements.removeIf(this::containsNegation); + } + // refinements.addAll(classHierarchy.getMoreSpecialConcepts(description)); } else if(description.isOWLNothing()) { // cannot be further refined @@ -671,7 +685,11 @@ public Set refine(OWLClassExpression description, int maxLen if(description instanceof OWLObjectMaxCardinality) { // rule 1: <= x r.C => <= x r.D if(useNegation || cardinality > 0){ - tmp = refineUpwards(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); + if (refineMaxCardinalityRestrictionsUpwards) { + tmp = refine(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); + } else { + tmp = refineUpwards(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); + } for(OWLClassExpression d : tmp) { refinements.add(df.getOWLObjectMaxCardinality(cardinality,role,d)); @@ -696,19 +714,20 @@ public Set refine(OWLClassExpression description, int maxLen if(cardinality < maxNrOfFillers.get(role)){ refinements.add(df.getOWLObjectMinCardinality(cardinality+1,role,filler)); } - } else if(description instanceof OWLObjectExactCardinality) { - tmp = refine(filler, maxLength-lengthMetric.objectCardinalityLength-lengthMetric.objectProperyLength, null, range); - - for(OWLClassExpression d : tmp) { - refinements.add(df.getOWLObjectExactCardinality(cardinality,role,d)); - } - - // = x r.C => = (x+1) r.C (not a downward refinement => commented out) -// int number = min.getNumber(); + } +// else if(description instanceof OWLObjectExactCardinality) { // (not downward refinements => commented out) +// tmp = refine(filler, maxLength-lengthMetric.objectCardinalityLength-lengthMetric.objectProperyLength, null, range); +// +// for(OWLClassExpression d : tmp) { +// refinements.add(df.getOWLObjectExactCardinality(cardinality,role,d)); +// } +// +// // = x r.C => = (x+1) r.C +// // int number = min.getNumber(); // if(cardinality < maxNrOfFillers.get(role)){ // refinements.add(df.getOWLObjectExactCardinality(cardinality+1,role,filler)); // } - } +// } } else if (description instanceof OWLDataSomeValuesFrom) { OWLDataProperty dp = ((OWLDataSomeValuesFrom) description).getProperty().asOWLDataProperty(); OWLDataRange dr = ((OWLDataSomeValuesFrom) description).getFiller(); @@ -784,6 +803,10 @@ public Set refine(OWLClassExpression description, int maxLen else topRefs = topARefinementsCumulative.get(currDomain).get(topRefLength); + if (!useNegation) { + topRefs = topRefs.stream().filter(c -> !containsNegation(c)).collect(Collectors.toSet()); + } + for(OWLClassExpression c : topRefs) { // true if refinement should be skipped due to filters, // false otherwise @@ -869,38 +892,43 @@ private Set refineUpwards( OWLClassExpression description, int maxLength, List knownRefinements, OWLClassExpression currDomain ) { - OWLClassExpression negatedDescription = constructNegationInNNF(description); - boolean useNegationBackup = useNegation; useNegation = true; - // concept length can change because of the conversion process; as a heuristic - // we increase maxLength by the length difference of negated and original concept - int lengthDiff = Math.max(0, OWLClassExpressionUtils.getLength(negatedDescription, lengthMetric) - OWLClassExpressionUtils.getLength(description, lengthMetric)); - Set refinements = refine(negatedDescription, maxLength+lengthDiff+1, knownRefinements, currDomain); TreeSet results = new TreeSet<>(); - useNegation = useNegationBackup; + try { + OWLClassExpression negatedDescription = constructNegationInNNF(description); - description = description.getNNF(); + // concept length can change because of the conversion process; as a heuristic + // we increase maxLength by the length difference of negated and original concept + int lengthDiff = Math.max(0, OWLClassExpressionUtils.getLength(negatedDescription, lengthMetric) - OWLClassExpressionUtils.getLength(description, lengthMetric)); + Set refinements = refine(negatedDescription, maxLength+lengthDiff+1, knownRefinements, currDomain); - for (OWLClassExpression d : refinements) { - OWLClassExpression dNeg = constructNegationInNNF(d); - dNeg = ConceptTransformation.cleanConcept(dNeg); + useNegation = useNegationBackup; - // to satisfy the guarantee that the method does not return longer - // concepts, we perform an additional check - if(description.compareTo(dNeg) != 0 - && (useNegation || !containsNegation(dNeg)) - && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength - ) { - results.add(dNeg); + description = description.getNNF(); + + for (OWLClassExpression d : refinements) { + OWLClassExpression dNeg = constructNegationInNNF(d); + dNeg = ConceptTransformation.cleanConcept(dNeg); + + // to satisfy the guarantee that the method does not return longer + // concepts, we perform an additional check + if(description.compareTo(dNeg) != 0 + && (useNegation || !containsNegation(dNeg)) + && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength + ) { + results.add(dNeg); + } } - } - if (description.isOWLNothing()) { - results.add(df.getOWLThing()); - } + if (description.isOWLNothing()) { + results.add(df.getOWLThing()); + } + } catch (Throwable t) {} + + useNegation = useNegationBackup; return results; } @@ -913,7 +941,7 @@ private OWLClassExpression constructNegationInNNF(OWLClassExpression description } private boolean containsNegation(OWLClassExpression description) { - return description.getNestedClassExpressions() + return decomposer.decompose(description) .stream().anyMatch(e -> e instanceof OWLObjectComplementOf || e instanceof OWLDataComplementOf ); @@ -1040,7 +1068,7 @@ && isPropertyAllowedInCardinalityRestrictions(prop) } if (description instanceof OWLDataSomeValuesFrom) { - return true; // TODO: not implemented + return true; // TODO: MY not implemented } if (description instanceof OWLDataHasValue) { @@ -1353,13 +1381,11 @@ private void computeM() { SortedSet m1 = classHierarchy.getSubClasses(df.getOWLThing(), true); m.get(lengthMetric.classLength).addAll(m1); - if(useNegation) { - int lc = lengthMetric.objectComplementLength + lengthMetric.classLength; - Set m2tmp = classHierarchy.getSuperClasses(df.getOWLNothing(), true); - for(OWLClassExpression c : m2tmp) { - if(!c.isOWLThing()) { - m.get(lc).add(df.getOWLObjectComplementOf(c)); - } + int lcn = lengthMetric.objectComplementLength + lengthMetric.classLength; + Set m2tmp = classHierarchy.getSuperClasses(df.getOWLNothing(), true); + for(OWLClassExpression c : m2tmp) { + if(!c.isOWLThing()) { + m.get(lcn).add(df.getOWLObjectComplementOf(c)); } } @@ -1460,9 +1486,15 @@ private void computeM() { // zero fillers: <= -1 r.C does not make sense // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, // but we still keep it, because ALL r.NOT C may be difficult to reach - if((useNegation && maxFillers > 0) || (!useNegation && maxFillers > 1)) - m.get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLNothing())); + if((useNegation && maxFillers > 0) || (!useNegation && maxFillers > 1)) { + if (refineMaxCardinalityRestrictionsUpwards) { + m.get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLThing())); + } else { + m.get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLNothing())); + } + } + // = 1 r.C // m.get(lc).add(df.getOWLObjectExactCardinality(1, r, df.getOWLThing())); } } @@ -1521,11 +1553,9 @@ private void computeM(OWLClassExpression nc) { mA.get(nc).get(lengthMetric.classLength).addAll(m1); // most specific negated classes, which are not disjoint with nc - if(useNegation) { - SortedSet m2; - m2 = getNegClassCandidates(nc); - mA.get(nc).get(lengthMetric.classLength + lengthMetric.objectComplementLength).addAll(m2); - } + SortedSet m2; + m2 = getNegClassCandidates(nc); + mA.get(nc).get(lengthMetric.classLength + lengthMetric.objectComplementLength).addAll(m2); // compute applicable properties computeMg(nc); @@ -1626,7 +1656,11 @@ private void computeM(OWLClassExpression nc) { // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, // but we still keep it, because ALL r.NOT C may be difficult to reach if ((useNegation && maxFillers > 0) || (!useNegation && maxFillers > 1)) { - mA.get(nc).get(lc).add(df.getOWLObjectMaxCardinality(maxFillers - 1, r, df.getOWLNothing())); + if (refineMaxCardinalityRestrictionsUpwards) { + mA.get(nc).get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLThing())); + } else { + mA.get(nc).get(lc).add(df.getOWLObjectMaxCardinality(maxFillers-1, r, df.getOWLNothing())); + } } // = 1 r.C @@ -2282,6 +2316,14 @@ public void setAllowedRolesInCardinalityRestrictions(Set allo } } + public boolean isRefineMaxCardinalityRestrictionsUpwards() { + return refineMaxCardinalityRestrictionsUpwards; + } + + public void setRefineMaxCardinalityRestrictionsUpwards(boolean refineMaxCardinalityRestrictionsUpwards) { + this.refineMaxCardinalityRestrictionsUpwards = refineMaxCardinalityRestrictionsUpwards; + } + @Override public RhoDRDown clone() { return new RhoDRDown(this); diff --git a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java index 573b244cae..a6243b070d 100644 --- a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java +++ b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java @@ -92,22 +92,47 @@ public void run() { // throw new RuntimeException("Expression is empty."); // } - expression = dataFactory.getOWLObjectSomeValuesFrom( - dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), - dataFactory.getOWLObjectIntersectionOf( - dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), - dataFactory.getOWLObjectMinCardinality( - 2, - dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), - dataFactory.getOWLThing() +// expression = dataFactory.getOWLObjectSomeValuesFrom( +// dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), +// dataFactory.getOWLObjectIntersectionOf( +// dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), +// dataFactory.getOWLObjectMinCardinality( +// 2, +// dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), +// dataFactory.getOWLThing() +// ) +// ) +// ); + +// expression = dataFactory.getOWLObjectSomeValuesFrom( +// dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), +// dataFactory.getOWLObjectMinCardinality( +// 2, +// dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), +// dataFactory.getOWLObjectComplementOf(dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#HighEntropy"))) +// ) +// ); + + expression = dataFactory.getOWLObjectIntersectionOf( + dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#ExecutableFile")), + dataFactory.getOWLObjectMinCardinality( + 2, + dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), + dataFactory.getOWLObjectIntersectionOf( + dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), + dataFactory.getOWLObjectMinCardinality( + 2, + dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), + dataFactory.getOWLThing() + ) ) ) ); logger.info("#EVAL# expression: " + expression); - Set pos = ((ParCELPosNegLP) lp).getPositiveExamples(); - Set neg = ((ParCELPosNegLP) lp).getNegativeExamples(); + Set pos = ((ParCELPosNegLP) lp).getPositiveTestExamples(); + Set neg = ((ParCELPosNegLP) lp).getNegativeTestExamples(); int tp = rs.hasType(expression, pos).size(); int fp = rs.hasType(expression, neg).size(); From b99b4c40d241c0bb3a70d24652e9a9d29db55365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Wed, 1 Mar 2023 20:23:27 +0100 Subject: [PATCH 04/67] reasoner cloning --- .../ParCELRefinementOperatorFactory.java | 5 +--- .../algorithms/parcel/ParCELWorker.java | 2 +- .../parcelex/ParCELWorkerExV12.java | 2 +- .../core/AbstractReasonerComponent.java | 18 +++++++++++- .../reasoning/ClosedWorldReasoner.java | 29 +++++++++++++++++++ .../refinementoperators/RhoDRDown.java | 6 +++- 6 files changed, 54 insertions(+), 8 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java index 85be1db8c5..ddb2366358 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java @@ -112,16 +112,13 @@ public ParCELRefinementOperatorFactory(RhoDRDown operatorPrototype, Map Date: Thu, 2 Mar 2023 09:11:37 +0100 Subject: [PATCH 05/67] parcel heuristic accuracy reward back to default, reasoner cloning config option --- .../parcel/ParCELDefaultHeuristic.java | 2 +- .../reasoning/ClosedWorldReasoner.java | 21 +++++++++++----- .../refinementoperators/RhoDRDown.java | 20 ++++++++++++++- .../dllearner/cli/ExpressionValidation.java | 25 +++++++++++++------ 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java index ba81048be8..b5740678c3 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java @@ -27,7 +27,7 @@ public class ParCELDefaultHeuristic implements ParCELHeuristic { protected double nodeRefinementPenalty = 0.0001; // award for node with high accuracy - protected double accuracyAwardFactor = 0.5; //0.01 + protected double accuracyAwardFactor = 0.01; //0.01 /** diff --git a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java index fa2bf9b48e..3f3806726b 100644 --- a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java +++ b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java @@ -46,8 +46,6 @@ import java.util.*; import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -135,11 +133,14 @@ public enum ForallSemantics { */ public enum DisjointnessSemantics { - EXPLICIT, - INSTANCE_BASED + Explicit, + InstanceBased } - private DisjointnessSemantics disjointnessSemantics = DisjointnessSemantics.EXPLICIT; + @ConfigOption(description = "whether to determine concept disjointness based on logical inference (Explicit) or " + + "based on the interpretation this reasoner works with (InstanceBased)", + defaultValue = "Explicit") + private DisjointnessSemantics disjointnessSemantics = DisjointnessSemantics.Explicit; @ConfigOption(defaultValue = "false") private boolean materializeExistentialRestrictions = false; @@ -1487,7 +1488,7 @@ public boolean isSuperClassOfImpl(OWLClassExpression superConcept, OWLClassExpre */ @Override public boolean isDisjointImpl(OWLClass clsA, OWLClass clsB) { - if (disjointnessSemantics == DisjointnessSemantics.INSTANCE_BASED) { + if (disjointnessSemantics == DisjointnessSemantics.InstanceBased) { TreeSet instancesA = classInstancesPos.get(clsA); TreeSet instancesB = classInstancesPos.get(clsB); @@ -1705,6 +1706,14 @@ public void setMaterializeExistentialRestrictions(boolean materializeExistential this.materializeExistentialRestrictions = materializeExistentialRestrictions; } + public DisjointnessSemantics getDisjointnessSemantics() { + return disjointnessSemantics; + } + + public void setDisjointnessSemantics(DisjointnessSemantics disjointnessSemantics) { + this.disjointnessSemantics = disjointnessSemantics; + } + /* (non-Javadoc) * @see org.dllearner.core.AbstractReasonerComponent#getDatatype(org.semanticweb.owlapi.model.OWLDataProperty) */ diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 10f0f8336d..3d1b994185 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -250,6 +250,9 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C @ConfigOption(description = "class expression length metric (should match learning algorithm usage)", defaultValue = "default cel_metric") private OWLClassExpressionLengthMetric lengthMetric = OWLClassExpressionLengthMetric.getDefaultMetric(); + @ConfigOption(description = "whether to clone the associated reasoner when cloning an operator instance", defaultValue = "false") + private boolean cloneReasoner = false; + private final OWLDataFactory df = new OWLDataFactoryImpl(); private final ExpressionDecomposer decomposer = new ExpressionDecomposer(); @@ -267,7 +270,14 @@ public RhoDRDown(RhoDRDown op) { setDataPropertyHierarchy(op.dataPropertyHierarchy.clone()); setDropDisjuncts(op.dropDisjuncts); setInstanceBasedDisjoints(op.instanceBasedDisjoints); - setReasoner(op.reasoner); // use clone if you would like to avoid reasoner exceptions + setCloneReasoner(op.cloneReasoner); + + if (cloneReasoner) { + setReasoner(op.reasoner.clone()); + } else { + setReasoner(op.reasoner); + } + setStartClass(op.startClass); setUseAllConstructor(op.useAllConstructor); setUseCardinalityRestrictions(op.useCardinalityRestrictions); @@ -2328,6 +2338,14 @@ public void setRefineMaxCardinalityRestrictionsUpwards(boolean refineMaxCardinal this.refineMaxCardinalityRestrictionsUpwards = refineMaxCardinalityRestrictionsUpwards; } + public boolean isCloneReasoner() { + return cloneReasoner; + } + + public void setCloneReasoner(boolean cloneReasoner) { + this.cloneReasoner = cloneReasoner; + } + @Override public RhoDRDown clone() { return new RhoDRDown(this); diff --git a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java index a6243b070d..4f73ec03f8 100644 --- a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java +++ b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java @@ -111,20 +111,31 @@ public void run() { // dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), // dataFactory.getOWLObjectComplementOf(dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#HighEntropy"))) // ) +// ); + +// expression = dataFactory.getOWLObjectIntersectionOf( +// dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#ExecutableFile")), +// dataFactory.getOWLObjectMinCardinality( +// 2, +// dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), +// dataFactory.getOWLObjectIntersectionOf( +// dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), +// dataFactory.getOWLObjectMinCardinality( +// 2, +// dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), +// dataFactory.getOWLThing() +// ) +// ) +// ) // ); expression = dataFactory.getOWLObjectIntersectionOf( dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#ExecutableFile")), - dataFactory.getOWLObjectMinCardinality( - 2, + dataFactory.getOWLObjectSomeValuesFrom( dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), dataFactory.getOWLObjectIntersectionOf( dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), - dataFactory.getOWLObjectMinCardinality( - 2, - dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section_feature")), - dataFactory.getOWLThing() - ) + dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#UninitializedDataSection")) ) ) ); From 4afb94f684d8faaf9af82f2e18b1cbc018d0616e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Thu, 2 Mar 2023 18:55:11 +0100 Subject: [PATCH 06/67] rho upward refinement takes into account (almost all) config options --- .../algorithms/parcel/ParCELAbstract.java | 4 +- .../algorithms/parcel/ParCELWorker.java | 7 + .../parcelex/ParCELWorkerExV12.java | 6 + .../refinementoperators/RhoDRDown.java | 275 +++++++++++------- 4 files changed, 190 insertions(+), 102 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index d739f7e773..0daf586b0a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -331,7 +331,9 @@ public void newPartialDefinitionsFound(Set definitions) { + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); } else if (logger.isInfoEnabled()) { - logger.info("PARTIAL definition found, uncovered positive examples left: " + logger.info("PARTIAL definition found: " + + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + + ", uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index e21c576017..1aa037fa30 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -3,6 +3,7 @@ import java.util.HashSet; import java.util.Map; import java.util.TreeSet; +import java.util.stream.Collectors; import org.apache.log4j.Logger; import org.dllearner.refinementoperators.LengthLimitedRefinementOperator; @@ -10,6 +11,7 @@ import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.mindswap.pellet.exceptions.InternalReasonerException; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLObjectUnionOf; /** * ParCEL worker which find and evaluate the refinements for a given node. @@ -92,6 +94,11 @@ public void run() { // expression into the search tree while (refinements != null && refinements.size() > 0) { OWLClassExpression refinement = refinements.pollFirst(); + +// if (refinement instanceof OWLObjectUnionOf) { +// continue; +// } + int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); // we ignore all refinements with lower length (may it happen?) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java index de05abae48..766d51a205 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java @@ -5,6 +5,7 @@ import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.mindswap.pellet.exceptions.InternalReasonerException; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLObjectUnionOf; import java.util.HashSet; import java.util.TreeSet; @@ -86,6 +87,11 @@ public void run() { //2. process the refinement result: calculate the accuracy and completeness and add the new expression into the search tree while (refinements.size() > 0) { OWLClassExpression refinement = refinements.pollFirst(); + +// if (refinement instanceof OWLObjectUnionOf) { +// continue; +// } + int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 3d1b994185..51fcaf616b 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -75,8 +75,7 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C private static Logger logger = LoggerFactory.getLogger(RhoDRDown.class); private final static Marker sparql_debug = new BasicMarkerFactory().getMarker("SD"); - private static final OWLClass OWL_THING = new OWLClassImpl( - OWLRDFVocabulary.OWL_THING.getIRI()); + private static final OWLClass OWL_THING = new OWLClassImpl(OWLRDFVocabulary.OWL_THING.getIRI()); @ConfigOption(description = "the reasoner to use") private AbstractReasonerComponent reasoner; @@ -108,8 +107,8 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C // Compound (and not with Thing), because otherwise concepts like // NOT Carbon-87 will be returned which itself is not a subclass of Compound @ConfigOption( - defaultValue = "owl:Thing", - description = "You can specify a start class for the algorithm") + defaultValue = "owl:Thing", + description = "You can specify a start class for the algorithm") private OWLClassExpression startClass = OWL_THING; // the length of concepts of top refinements, the first values is @@ -159,7 +158,7 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C // data structure for a simple frequent pattern matching preprocessing phase @ConfigOption(defaultValue = "3", description = "minimum number an individual or literal has to be seen in the " + - "knowledge base before considering it for inclusion in concepts") + "knowledge base before considering it for inclusion in concepts") private int frequencyThreshold = CommonConfigOptions.valueFrequencyThresholdDefault; // data structure with identified frequent values private Map> frequentValues = new HashMap<>(); @@ -174,7 +173,7 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C private boolean applyAllFilter = true; @ConfigOption(defaultValue="true", description = "throwing out all refinements with " + - "duplicate \u2203 r for any r") + "duplicate \u2203 r for any r") private boolean applyExistsFilter = true; @ConfigOption(description="support of universal restrictions (owl:allValuesFrom), e.g. \u2200 r.C ", defaultValue="true") @@ -229,7 +228,7 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, C private boolean dropDisjuncts = false; @ConfigOption(description="universal restrictions on a property r are only used when there is already a cardinality and/or existential restriction on r", - defaultValue="true") + defaultValue="true") private boolean useSomeOnly = true; @ConfigOption( @@ -309,16 +308,16 @@ public RhoDRDown(RhoDRDown op) { private Set frequentObjects(Collection> c, int frequencyThreshold) { final int t = frequencyThreshold; return c.stream() - .flatMap(Collection::stream) - .collect(Collectors.collectingAndThen(Collectors.groupingBy(Function.identity(), Collectors.counting()), - map -> { - map.values().removeIf(v -> v < t); - return map.keySet(); - })); + .flatMap(Collection::stream) + .collect(Collectors.collectingAndThen(Collectors.groupingBy(Function.identity(), Collectors.counting()), + map -> { + map.values().removeIf(v -> v < t); + return map.keySet(); + })); } @Override - public void init() throws ComponentInitException { + public void init() throws ComponentInitException { /* if(initialized) { throw new ComponentInitException("Refinement operator cannot be initialised twice."); @@ -358,10 +357,10 @@ public void init() throws ComponentInitException { // all related individuals, thus, the freuqncy of each individual as subject is just the number // of objects frequentInds = propertyMembers.entrySet().stream().collect(Collectors.collectingAndThen( - Collectors.toMap(Entry::getKey, e -> e.getValue().size()), map -> { - map.values().removeIf(v -> v < frequencyThreshold); - return map.keySet(); - })); + Collectors.toMap(Entry::getKey, e -> e.getValue().size()), map -> { + map.values().removeIf(v -> v < frequencyThreshold); + return map.keySet(); + })); frequentValues.put(op.getInverseProperty(), frequentInds); } } @@ -398,7 +397,7 @@ public void init() throws ComponentInitException { // compute splits for time data properties if (useTimeDatatypes) { if(reasoner instanceof SPARQLReasoner - && !((SPARQLReasoner)reasoner).isUseGenericSplitsCode()) { + && !((SPARQLReasoner)reasoner).isUseGenericSplitsCode()) { // TODO SPARQL support for splits logger.warn("Time based Facet restrictions are not (yet) implemented for " + AnnComponentManager.getName(reasoner) + ", option ignored"); } else { @@ -419,9 +418,9 @@ public void init() throws ComponentInitException { maxNrOfFillers.put(op, 10); } else { int maxFillers = Math.min(cardinalityLimit, - reasoner.getPropertyMembers(op).values().stream() - .mapToInt(Set::size) - .max().orElse(0)); + reasoner.getPropertyMembers(op).values().stream() + .mapToInt(Set::size) + .max().orElse(0)); maxNrOfFillers.put(op, maxFillers); // int percentile95 = (int) new Percentile().evaluate( @@ -435,18 +434,18 @@ public void init() throws ComponentInitException { // handle inverse properties if(useInverse) { maxFillers = 0; - + Multimap map = HashMultimap.create(); - + for (Entry> entry : reasoner.getPropertyMembers(op).entrySet()) { OWLIndividual subject = entry.getKey(); SortedSet objects = entry.getValue(); - + for (OWLIndividual obj : objects) { map.put(obj, subject); } } - + for (Entry> entry : map.asMap().entrySet()) { Collection inds = entry.getValue(); if (inds.size() > maxFillers) @@ -497,13 +496,13 @@ public Set refine(OWLClassExpression description, int maxLen @Override public Set refine(OWLClassExpression description, int maxLength, - List knownRefinements) { + List knownRefinements) { return refine(description, maxLength, knownRefinements, startClass); } @SuppressWarnings({"unchecked"}) public Set refine(OWLClassExpression description, int maxLength, - List knownRefinements, OWLClassExpression currDomain) { + List knownRefinements, OWLClassExpression currDomain) { // System.out.println("|- " + description + " " + currDomain + " " + maxLength); @@ -538,6 +537,10 @@ public Set refine(OWLClassExpression description, int maxLen refinements.removeIf(this::containsNegation); } + if (useSomeOnly) { + refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r)); + } + // refinements.addAll(classHierarchy.getMoreSpecialConcepts(description)); } else if(description.isOWLNothing()) { // cannot be further refined @@ -615,7 +618,7 @@ public Set refine(OWLClassExpression description, int maxLen // never be nested in another disjunction in this operator // if (checkRefinability((OWLNaryBooleanClassExpression) md)) { - refinements.add(md); + refinements.add(md); // } } } @@ -643,8 +646,8 @@ public Set refine(OWLClassExpression description, int maxLen // we need the context of the filler which is either the domain (in case of an inverse property) or the range of p OWLClassExpression domain = role.isAnonymous() - ? opDomains.get(role.getNamedProperty()) // inv(p) -> D = domain(p) - : opRanges.get(role.asOWLObjectProperty()); // p -> D = range(p) + ? opDomains.get(role.getNamedProperty()) // inv(p) -> D = domain(p) + : opRanges.get(role.asOWLObjectProperty()); // p -> D = range(p) // rule 1: EXISTS r.D => EXISTS r.E tmp = refine(filler, maxLength-lengthMetric.objectSomeValuesLength-lengthMetric.objectProperyLength, null, domain); @@ -665,8 +668,8 @@ public Set refine(OWLClassExpression description, int maxLen OWLObjectProperty prop = role.isAnonymous() ? role.getNamedProperty() : role.asOWLObjectProperty(); if (useCardinalityRestrictions && isPropertyAllowedInCardinalityRestrictions(prop) && - maxLength > OWLClassExpressionUtils.getLength(description, lengthMetric) && - maxNrOfFillers.get(role) > 1) { + maxLength > OWLClassExpressionUtils.getLength(description, lengthMetric) && + maxNrOfFillers.get(role) > 1) { refinements.add(df.getOWLObjectMinCardinality(2, role, filler)); } @@ -907,7 +910,14 @@ private Set refineUpwards( List knownRefinements, OWLClassExpression currDomain ) { boolean useNegationBackup = useNegation; + boolean useDisjunctionBackup = useDisjunction; + boolean useAllConstructorBackup = useAllConstructor; + boolean useExistsConstructorBackup = useExistsConstructor; + useNegation = true; + useDisjunction = true; + useAllConstructor = useExistsConstructorBackup; + useExistsConstructor = useAllConstructorBackup; TreeSet results = new TreeSet<>(); @@ -919,18 +929,21 @@ private Set refineUpwards( int lengthDiff = Math.max(0, OWLClassExpressionUtils.getLength(negatedDescription, lengthMetric) - OWLClassExpressionUtils.getLength(description, lengthMetric)); Set refinements = refine(negatedDescription, maxLength+lengthDiff+1, knownRefinements, currDomain); - useNegation = useNegationBackup; - description = description.getNNF(); for (OWLClassExpression d : refinements) { OWLClassExpression dNeg = constructNegationInNNF(d); dNeg = ConceptTransformation.cleanConcept(dNeg); + // TODO: dropDisjuncts not supported + // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check if(description.compareTo(dNeg) != 0 - && (useNegation || !containsNegation(dNeg)) + && (useDisjunctionBackup || !containsDisjunction(dNeg)) + && (useNegationBackup || !containsNegation(dNeg)) + && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) + && (!useSomeOnly || (!(dNeg instanceof OWLObjectAllValuesFrom) && isSomeOnlySatisfied(dNeg))) && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength ) { results.add(dNeg); @@ -943,6 +956,9 @@ private Set refineUpwards( } catch (Throwable t) {} useNegation = useNegationBackup; + useDisjunction = useDisjunctionBackup; + useAllConstructor = useAllConstructorBackup; + useExistsConstructor = useExistsConstructorBackup; return results; } @@ -954,6 +970,11 @@ private OWLClassExpression constructNegationInNNF(OWLClassExpression description return negatedDescription; } + private boolean containsDisjunction(OWLClassExpression description) { + return decomposer.decompose(description) + .stream().anyMatch(e -> e instanceof OWLObjectUnionOf); + } + private boolean containsNegation(OWLClassExpression description) { return decomposer.decompose(description) .stream().anyMatch(e -> @@ -961,6 +982,58 @@ private boolean containsNegation(OWLClassExpression description) { ); } + private boolean containsObjectValueNegation(OWLClassExpression description) { + return decomposer.decompose(description) + .stream().anyMatch(e -> + e instanceof OWLObjectComplementOf && ((OWLObjectComplementOf) e).getOperand() instanceof OWLObjectOneOf + ); + } + + private boolean isSomeOnlySatisfied(OWLClassExpression description) { + if (description instanceof OWLObjectIntersectionOf) { + Set allValuesProperties = + ((OWLObjectIntersectionOf) description).getOperands() + .stream().filter(op -> op instanceof OWLObjectAllValuesFrom) + .map(op -> ((OWLObjectAllValuesFrom) op).getProperty()) + .collect(Collectors.toSet()); + + Set someValuesProperties = + ((OWLObjectIntersectionOf) description).getOperands() + .stream().filter(op -> op instanceof OWLObjectSomeValuesFrom) + .map(op -> ((OWLObjectSomeValuesFrom) op).getProperty()) + .collect(Collectors.toSet()); + + allValuesProperties.removeAll(someValuesProperties); + + return allValuesProperties.isEmpty() + && ((OWLObjectIntersectionOf) description).getOperands().stream().allMatch(this::isSomeOnlySatisfied); + } + + if (description instanceof OWLObjectUnionOf) { + return ((OWLObjectUnionOf) description).getOperands().stream().allMatch(this::isSomeOnlySatisfied); + } + + if (description instanceof OWLObjectSomeValuesFrom) { + OWLClassExpression filler = ((OWLObjectSomeValuesFrom) description).getFiller(); + + return isSomeOnlySatisfied(filler); + } + + if (description instanceof OWLObjectAllValuesFrom) { + OWLClassExpression filler = ((OWLObjectAllValuesFrom) description).getFiller(); + + return isSomeOnlySatisfied(filler); + } + + if (description instanceof OWLObjectCardinalityRestriction) { + OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); + + return isSomeOnlySatisfied(filler); + } + + return true; + } + private boolean checkRefinability(OWLNaryBooleanClassExpression description) { Set unrefinableOperands = new TreeSet<>(); @@ -1108,7 +1181,7 @@ private boolean isCombinable(OWLClassExpression ce, OWLClassExpression child) { OWLObjectPropertyExpression r1 = ((OWLObjectAllValuesFrom) child).getProperty(); if(ce instanceof OWLObjectIntersectionOf){ for(OWLClassExpression operand : ((OWLObjectIntersectionOf) ce).getOperands()) { - if(child instanceof OWLObjectSomeValuesFrom) { + if(operand instanceof OWLObjectSomeValuesFrom) { OWLObjectPropertyExpression r2 = ((OWLObjectSomeValuesFrom) operand).getProperty(); if(r1.equals(r2)){ tmp = true; @@ -1182,9 +1255,9 @@ public static boolean checkIntersection(OWLObjectIntersectionOf intersection) { // rule 4: no double occurences of hasValue restrictions TreeSet occuredVR = new TreeSet<>(); // rule 5: max. restrictions at most once - boolean maxIntOccurence = false; - // rule 6: min restrictions at most once - boolean minIntOccurence = false; + boolean maxIntOccurence = false; + // rule 6: min restrictions at most once + boolean minIntOccurence = false; for(OWLClassExpression child : intersection.getOperands()) { if(child instanceof OWLDataSomeValuesFrom) { @@ -1299,7 +1372,7 @@ private void computeTopRefinements(int maxLength, OWLClassExpression domain) { topRefinements.get(i).addAll(m.get(i)); else topARefinements.get(domain).get(i).addAll(mA.get(domain).get(i)); - // combinations has several numbers => generate disjunct + // combinations has several numbers => generate disjunct } else if (useDisjunction) { // check whether the combination makes sense, i.e. whether @@ -1309,7 +1382,7 @@ private void computeTopRefinements(int maxLength, OWLClassExpression domain) { boolean validCombo = true; for(Integer j : combo) { if((domain == null && m.get(j).size()==0) || - (domain != null && mA.get(domain).get(j).size()==0)) + (domain != null && mA.get(domain).get(j).size()==0)) validCombo = false; } @@ -1452,11 +1525,11 @@ private void computeM() { if(useTimeDatatypes) { Set dataProperties = dataPropertyHierarchy.getEntities().stream() - .filter(dp -> - { - OWLDatatype datatype = reasoner.getDatatype(dp); - return (datatype != null && OWLAPIUtils.dtDatatypes.contains(datatype)); - }).collect(Collectors.toSet()); + .filter(dp -> + { + OWLDatatype datatype = reasoner.getDatatype(dp); + return (datatype != null && OWLAPIUtils.dtDatatypes.contains(datatype)); + }).collect(Collectors.toSet()); int lc = lengthMetric.dataSomeValuesLength + lengthMetric.dataProperyLength + 1; for(OWLDataProperty dp : dataProperties) { addNumericFacetRestrictions(lc, dp); @@ -1531,11 +1604,11 @@ private void addNumericFacetRestrictions(int lc, OWLDataProperty dp) { OWLLiteral min = splits.get(dp).get(0); OWLLiteral max = splits.get(dp).get(splits.get(dp).size()-1); - OWLDatatypeRestriction restriction = asDatatypeRestriction(dp, min, OWLFacet.MIN_INCLUSIVE); - m.get(lc).add(df.getOWLDataSomeValuesFrom(dp, restriction)); + OWLDatatypeRestriction restriction = asDatatypeRestriction(dp, min, OWLFacet.MIN_INCLUSIVE); + m.get(lc).add(df.getOWLDataSomeValuesFrom(dp, restriction)); - restriction = asDatatypeRestriction(dp, max, OWLFacet.MAX_INCLUSIVE); - m.get(lc).add(df.getOWLDataSomeValuesFrom(dp, restriction)); + restriction = asDatatypeRestriction(dp, max, OWLFacet.MAX_INCLUSIVE); + m.get(lc).add(df.getOWLDataSomeValuesFrom(dp, restriction)); } } @@ -1543,10 +1616,10 @@ private OWLDatatypeRestriction asDatatypeRestriction(OWLDataProperty dp, OWLLite OWLDatatype datatype = reasoner.getDatatype(dp); OWLDatatypeRestriction restriction = df.getOWLDatatypeRestriction( - datatype, - Collections.singleton(df.getOWLFacetRestriction( - facet, - value))); + datatype, + Collections.singleton(df.getOWLFacetRestriction( + facet, + value))); return restriction; } @@ -1718,40 +1791,40 @@ private SortedSet getClassCandidatesRecursive(OWLClassExpres // the most general concepts satisfying the criteria for(OWLClassExpression candidate : subClasses) { // System.out.println("testing " + candidate + " ... "); - // NamedClass candidate = (OWLClass) d; - // check disjointness with index (if not no further traversal downwards is necessary) - if(!isDisjoint(candidate,index)) { + // NamedClass candidate = (OWLClass) d; + // check disjointness with index (if not no further traversal downwards is necessary) + if(!isDisjoint(candidate,index)) { // System.out.println( " passed disjointness test ... "); - // check whether the class is meaningful, i.e. adds something to the index - // to do this, we need to make sure that the class is not a superclass of the - // index (otherwise we get nothing new) - for instance based disjoints, we - // make sure that there is at least one individual, which is not already in the - // upper class - boolean meaningful; - if(instanceBasedDisjoints) { - // bug: tests should be performed against the index, not the upper class - // SortedSet tmp = rs.getIndividuals(upperClass); - SortedSet tmp = reasoner.getIndividuals(index); - tmp.removeAll(reasoner.getIndividuals(candidate)); - // System.out.println(" instances of " + index + " and not " + candidate + ": " + tmp.size()); - meaningful = tmp.size() != 0; - } else { - meaningful = !isDisjoint(df.getOWLObjectComplementOf(candidate),index); - } + // check whether the class is meaningful, i.e. adds something to the index + // to do this, we need to make sure that the class is not a superclass of the + // index (otherwise we get nothing new) - for instance based disjoints, we + // make sure that there is at least one individual, which is not already in the + // upper class + boolean meaningful; + if(instanceBasedDisjoints) { + // bug: tests should be performed against the index, not the upper class + // SortedSet tmp = rs.getIndividuals(upperClass); + SortedSet tmp = reasoner.getIndividuals(index); + tmp.removeAll(reasoner.getIndividuals(candidate)); + // System.out.println(" instances of " + index + " and not " + candidate + ": " + tmp.size()); + meaningful = tmp.size() != 0; + } else { + meaningful = !isDisjoint(df.getOWLObjectComplementOf(candidate),index); + } - if(meaningful) { - // candidate went successfully through all checks - candidates.add(candidate); - // System.out.println(" real refinement"); - } else { - // descend subsumption hierarchy to find candidates - // System.out.println(" enter recursion"); - candidates.addAll(getClassCandidatesRecursive(index, candidate)); - } + if(meaningful) { + // candidate went successfully through all checks + candidates.add(candidate); + // System.out.println(" real refinement"); + } else { + // descend subsumption hierarchy to find candidates + // System.out.println(" enter recursion"); + candidates.addAll(getClassCandidatesRecursive(index, candidate)); } - // else { - // System.out.println(" ruled out, because it is disjoint"); - // } + } + // else { + // System.out.println(" ruled out, because it is disjoint"); + // } } } // System.out.println("cc method exit"); @@ -2026,9 +2099,9 @@ private boolean isNotADisjoint(OWLClass a, OWLClass b) { // if(tmp2==null) { OWLClassExpression notA = df.getOWLObjectComplementOf(a); OWLClassExpression d = df.getOWLObjectIntersectionOf(notA, b); - Boolean result = reasoner.isSuperClassOf(df.getOWLNothing(), d); - // ... add to cache ... - return result; + Boolean result = reasoner.isSuperClassOf(df.getOWLNothing(), d); + // ... add to cache ... + return result; // } else // return tmp2; } @@ -2167,7 +2240,7 @@ public AbstractReasonerComponent getReasoner() { return reasoner; } - @Autowired + @Autowired public void setReasoner(AbstractReasonerComponent reasoner) { this.reasoner = reasoner; } @@ -2202,7 +2275,7 @@ public ObjectPropertyHierarchy getObjectPropertyHierarchy() { } @Override - public void setObjectPropertyHierarchy(ObjectPropertyHierarchy objectPropertyHierarchy) { + public void setObjectPropertyHierarchy(ObjectPropertyHierarchy objectPropertyHierarchy) { this.objectPropertyHierarchy = objectPropertyHierarchy; } @@ -2211,7 +2284,7 @@ public DatatypePropertyHierarchy getDataPropertyHierarchy() { } @Override - public void setDataPropertyHierarchy(DatatypePropertyHierarchy dataPropertyHierarchy) { + public void setDataPropertyHierarchy(DatatypePropertyHierarchy dataPropertyHierarchy) { this.dataPropertyHierarchy = dataPropertyHierarchy; } @@ -2295,15 +2368,15 @@ public void setLengthMetric(OWLClassExpressionLengthMetric lengthMetric) { this.lengthMetric = lengthMetric; mMaxLength = max ( - lengthMetric.classLength, - lengthMetric.objectComplementLength + lengthMetric.classLength, - lengthMetric.objectSomeValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength, - lengthMetric.objectSomeValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength + lengthMetric.objectInverseLength, - lengthMetric.objectAllValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength, - lengthMetric.objectAllValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength + lengthMetric.objectInverseLength, - lengthMetric.dataHasValueLength + lengthMetric.dataProperyLength, - lengthMetric.dataSomeValuesLength + lengthMetric.dataProperyLength + 1, - lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength); + lengthMetric.classLength, + lengthMetric.objectComplementLength + lengthMetric.classLength, + lengthMetric.objectSomeValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength, + lengthMetric.objectSomeValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength + lengthMetric.objectInverseLength, + lengthMetric.objectAllValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength, + lengthMetric.objectAllValuesLength + lengthMetric.objectProperyLength + lengthMetric.classLength + lengthMetric.objectInverseLength, + lengthMetric.dataHasValueLength + lengthMetric.dataProperyLength, + lengthMetric.dataSomeValuesLength + lengthMetric.dataProperyLength + 1, + lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength); logger.debug("mMaxLength = " + mMaxLength); } From b24a4871d961df690c8eef96861e6948ae47b68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 09:10:46 +0100 Subject: [PATCH 07/67] rho useDisjunction when refining upwards and accuracy speedup --- .../org/dllearner/algorithms/celoe/CELOE.java | 75 ++++-- .../dllearner/algorithms/celoe/OENode.java | 30 +++ .../algorithms/parcel/ParCELAbstract.java | 61 ++++- .../algorithms/parcel/ParCELExtraNode.java | 2 +- .../algorithms/parcel/ParCELNode.java | 29 +-- .../algorithms/parcel/ParCELPosNegLP.java | 11 +- .../ParCELRefinementOperatorFactory.java | 4 + .../algorithms/parcel/ParCELWorker.java | 21 +- .../parcelex/ParCELExWorkerAbstract.java | 17 +- .../dllearner/learningproblems/PosNegLP.java | 9 + .../DownwardRefinementOperator.java | 4 + .../refinementoperators/RhoDRDown.java | 226 ++++-------------- .../dllearner/cli/ExpressionValidation.java | 2 +- 13 files changed, 237 insertions(+), 254 deletions(-) create mode 100644 components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index bb9f959fe5..e706c59bf4 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -574,34 +574,28 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { return false; } - // quality of class expression (return if too weak) - Monitor mon = MonitorFactory.start("lp"); - logger.trace(sparql_debug, sparql_debug_out); - double accuracy = learningProblem.getAccuracyOrTooWeak(description, noise); - logger.trace(sparql_debug, "`acc:"+accuracy); - mon.stop(); + OENode node = createNode(parentNode, description); // issue a warning if accuracy is not between 0 and 1 or -1 (too weak) - if(accuracy > 1.0 || (accuracy < 0.0 && accuracy != -1)) { - throw new RuntimeException("Invalid accuracy value " + accuracy + " for class expression " + description + + if(node.getAccuracy() > 1.0 || (node.getAccuracy() < 0.0 && node.getAccuracy() != -1)) { + throw new RuntimeException("Invalid accuracy value " + node.getAccuracy() + " for class expression " + description + ". This could be caused by a bug in the heuristic measure and should be reported to the DL-Learner bug tracker."); } expressionTests++; // return FALSE if 'too weak' - if(accuracy == -1) { + if(node.getAccuracy() == -1) { return false; } - - OENode node = new OENode(description, accuracy); + searchTree.addNode(parentNode, node); // in some cases (e.g. mutation) fully evaluating even a single class expression is too expensive // due to the high number of examples -- so we just stick to the approximate accuracy if(singleSuggestionMode) { - if(accuracy > bestAccuracy) { - bestAccuracy = accuracy; + if(node.getAccuracy() > bestAccuracy) { + bestAccuracy = node.getAccuracy(); bestDescription = description; logger.info("more accurate (" + dfPercent.format(bestAccuracy) + ") class expression found: " + descriptionToString(bestDescription)); // + getTemporaryString(bestDescription)); } @@ -616,8 +610,8 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { EvaluatedDescription worst = bestEvaluatedDescriptions.getWorst(); double accThreshold = worst.getAccuracy(); isCandidate = - (accuracy > accThreshold || - (accuracy >= accThreshold && OWLClassExpressionUtils.getLength(description) < worst.getDescriptionLength())); + (node.getAccuracy() > accThreshold || + (node.getAccuracy() >= accThreshold && OWLClassExpressionUtils.getLength(description) < worst.getDescriptionLength())); } if(isCandidate) { @@ -638,7 +632,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { boolean shorterDescriptionExists = false; if(forceMutualDifference) { for(EvaluatedDescription ed : bestEvaluatedDescriptions.getSet()) { - if(Math.abs(ed.getAccuracy()-accuracy) <= 0.00001 && ConceptTransformation.isSubdescription(niceDescription, ed.getDescription())) { + if(Math.abs(ed.getAccuracy()-node.getAccuracy()) <= 0.00001 && ConceptTransformation.isSubdescription(niceDescription, ed.getDescription())) { // System.out.println("shorter: " + ed.getDescription()); shorterDescriptionExists = true; break; @@ -651,7 +645,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { if(!shorterDescriptionExists) { if(!filterFollowsFromKB || !((ClassLearningProblem)learningProblem).followsFromKB(niceDescription)) { // System.out.println(node + "->" + niceDescription); - bestEvaluatedDescriptions.add(niceDescription, accuracy, learningProblem); + bestEvaluatedDescriptions.add(niceDescription, node.getAccuracy(), learningProblem); // System.out.println("acc: " + accuracy); // System.out.println(bestEvaluatedDescriptions); } @@ -662,7 +656,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { // System.out.println(bestEvaluatedDescriptions.getSet().size()); } - if (accuracy >= 1 - noiseWithMargin) { + if (node.getAccuracy() >= 1 - noiseWithMargin) { if (solutionCandidates.isEmpty() || (node.getAccuracy() > solutionCandidates.firstKey().getAccuracy() && solutionCandidates.keySet().stream().allMatch( @@ -680,6 +674,51 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { return true; } + + private OENode createNode(OENode parent, OWLClassExpression refinement) { + if (!(learningProblem instanceof PosNegLP)) { + Monitor mon = MonitorFactory.start("lp"); + double accuracy = learningProblem.getAccuracyOrTooWeak(refinement, noise); + mon.stop(); + + return new OENode(refinement, accuracy); + } + + PosNegLP posNegLP = (PosNegLP) learningProblem; + + Set coveredPositives; + Set coveredNegatives; + + Monitor mon = MonitorFactory.start("lp"); + + if (parent == null) { + coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); + } else if (operator instanceof DownwardRefinementOperator) { + coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); + } else { + Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); + uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); + Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); + uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); + + coveredPositives = reasoner.hasType(refinement, uncoveredPositives); + coveredPositives.addAll(parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); + coveredNegatives.addAll(parent.getCoveredNegativeExamples()); + } + + double accuracy = posNegLP.getAccuracyOrTooWeak(coveredPositives, coveredNegatives, noise); + + mon.stop(); + + OENode node = new OENode(refinement, accuracy); + node.setCoveredPositiveExamples(coveredPositives); + node.setCoveredNegativeExamples(coveredNegatives); + + return node; + } // checks whether the class expression is allowed private boolean isDescriptionAllowed(OWLClassExpression description, OENode parentNode) { diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java index 8c1423c7e2..bab752f857 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java @@ -23,9 +23,12 @@ import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionUtils; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; import java.text.DecimalFormat; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; /** * A node in the search tree of the ontology engineering algorithm. @@ -54,6 +57,9 @@ public class OENode extends AbstractSearchTreeNode implements SearchTree // OWLClassExpression in this node - it is a better heuristic indicator than child count // (and avoids the problem that adding children changes the heuristic value) private int refinementCount = 0; + + private Set coveredPositiveExamples = new TreeSet<>(); + private Set coveredNegativeExamples = new TreeSet<>(); private static DecimalFormat dfPercent = new DecimalFormat("0.00%"); @@ -135,4 +141,28 @@ public int getRefinementCount() { public void setRefinementCount(int refinementCount) { this.refinementCount = refinementCount; } + + public Set getCoveredPositiveExamples() { + return coveredPositiveExamples; + } + + public Set getCoveredNegativeExamples() { + return coveredNegativeExamples; + } + + public void setCoveredPositiveExamples(Set coveredPositiveExamples) { + this.coveredPositiveExamples.clear(); + + if (coveredPositiveExamples != null) { + this.coveredPositiveExamples.addAll(coveredPositiveExamples); + } + } + + public void setCoveredNegativeExamples(Set coveredNegativeExamples) { + this.coveredNegativeExamples.clear(); + + if (coveredNegativeExamples != null) { + this.coveredNegativeExamples.addAll(coveredNegativeExamples); + } + } } \ No newline at end of file diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 0daf586b0a..4fa0b47fa9 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -1,5 +1,7 @@ package org.dllearner.algorithms.parcel; +import com.jamonapi.Monitor; +import com.jamonapi.MonitorFactory; import org.apache.log4j.Logger; import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer; @@ -11,10 +13,8 @@ import org.dllearner.core.owl.DatatypePropertyHierarchy; import org.dllearner.core.owl.OWLObjectUnionOfImplExt; import org.dllearner.core.owl.ObjectPropertyHierarchy; -import org.dllearner.refinementoperators.CustomHierarchyRefinementOperator; -import org.dllearner.refinementoperators.CustomStartRefinementOperator; -import org.dllearner.refinementoperators.RefinementOperator; -import org.dllearner.refinementoperators.RhoDRDown; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.refinementoperators.*; import org.dllearner.utilities.owl.EvaluatedDescriptionComparator; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionUtils; @@ -24,6 +24,7 @@ import org.semanticweb.owlapi.model.OWLIndividual; import org.springframework.beans.factory.annotation.Autowired; +import javax.naming.OperationNotSupportedException; import java.lang.invoke.MethodHandles; import java.text.DecimalFormat; import java.util.*; @@ -267,8 +268,27 @@ protected void initSearchTree() { // currently, start class is always Thing (initialised in the init() method) allDescriptions.add(startClass); - double accuracy = this.positiveExamples.size() / (double) (this.positiveExamples.size() + this.negativeExamples.size()); - ParCELNode startNode = new ParCELNode(null, startClass, accuracy, 0, 1.0); + ParCELNode startNode; + + if (learningProblem instanceof ParCELPosNegLP) { + Set coveredPositives = reasoner.hasType(startClass, positiveExamples); + Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); + + ParCELEvaluationResult accAndCorr = ((ParCELPosNegLP) learningProblem) + .getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + + startNode = new ParCELNode( + null, startClass, + accAndCorr.accuracy, accAndCorr.correctness, accAndCorr.completeness + ); + + startNode.setCoveredPositiveExamples(coveredPositives); + startNode.setCoveredNegativeExamples(coveredNegatives); + } else { + double accuracy = this.positiveExamples.size() / (double) (this.positiveExamples.size() + this.negativeExamples.size()); + startNode = new ParCELNode(null, startClass, accuracy, 0, 1.0); + } + searchTree.add(startNode); } @@ -447,6 +467,35 @@ protected void createWorkerPool() { ", max pool size: " + workerPool.getMaximumPoolSize()); } + public ParCELEvaluationResult getAccuracyAndCorrectness(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set coveredPositives; + Set coveredNegatives; + + if (parent == null) { + coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); + } else if (refinementOperatorPool.getFactory().getOperatorPrototype() instanceof DownwardRefinementOperator) { + coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); + } else { + Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); + uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); + Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); + uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); + + coveredPositives = reasoner.hasType(refinement, uncoveredPositives); + coveredPositives.addAll(parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); + coveredNegatives.addAll(parent.getCoveredNegativeExamples()); + } + + return posNegLP.getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + } + /** * Get the union of all the best (reduced) partial definitions * diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java index 76758ccdb5..4e12babaf0 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java @@ -74,7 +74,7 @@ public ParCELExtraNode(ParCELNode node) { */ public ParCELExtraNode(ParCELNode node, Set cp) { super(node.getParent(), node.getDescription(), node.getAccuracy(), node.getCorrectness(), node.getCompleteness()); - super.coveredPositiveExamples = cp; + setCoveredPositiveExamples(cp); } /** diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java index e2a27fde0b..7542c2a482 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java @@ -22,9 +22,6 @@ public class ParCELNode extends OENode { private double correctness = -1.0; private double completeness = -1.0; - protected Set coveredPositiveExamples = new HashSet<>(); - protected final Set coveredNegativeExamples = new HashSet<>(); - private final DecimalFormat dfPercent = new DecimalFormat("0.00%"); @@ -41,8 +38,8 @@ public ParCELNode(OENode parentNode, OWLClassExpression description, Set coveredPositiveExamples, Set coveredNegativeExamples) { super(description, 0); setParent(parentNode); - this.coveredPositiveExamples.addAll(coveredPositiveExamples); - this.coveredNegativeExamples.addAll(coveredNegativeExamples); + setCoveredPositiveExamples(coveredPositiveExamples); + setCoveredNegativeExamples(coveredNegativeExamples); } public void setCorrectness(double cor) { @@ -65,28 +62,6 @@ public void setAccuracy(double acc) { this.accuracy = acc; } - public Set getCoveredPositiveExamples() { - return this.coveredPositiveExamples; - } - - public Set getCoveredNegativeExamples() { - return this.coveredNegativeExamples; - } - - public void setCoveredPositiveExamples(Set coveredPositiveExamples) { - if (coveredPositiveExamples != null) - this.coveredPositiveExamples.addAll(coveredPositiveExamples); - else - this.coveredPositiveExamples.clear(); - } - - public void setCoveredNegativeExamples(Set coveredNegativeExamples) { - if (coveredNegativeExamples != null) - this.coveredNegativeExamples.addAll(coveredNegativeExamples); - else - this.coveredNegativeExamples.clear(); - } - @Override public String toString() { String ret = OWLAPIRenderers.toManchesterOWLSyntax(this.getDescription()); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java index b664679047..b105501376 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -468,10 +468,14 @@ public ParCELEvaluationResult getAccuracyAndCorrectness3(OWLClassExpression desc } - public ParCELEvaluationResult getAccuracyAndCorrectness4(OWLClassExpression description, double noise) { + public ParCELEvaluationResult getAccuracyAndCorrectness4(OWLClassExpression description) { Set coveredPositiveExamples = reasoner.hasType(description, positiveExamples); Set coveredNegativeExamples = reasoner.hasType(description, negativeExamples); + return getAccuracyAndCorrectness4(coveredPositiveExamples, coveredNegativeExamples); + } + + public ParCELEvaluationResult getAccuracyAndCorrectness4(Set coveredPositiveExamples, Set coveredNegativeExamples) { if (coveredPositiveExamples.isEmpty()) { return new ParCELEvaluationResult(-1, 0, 0); } @@ -485,9 +489,8 @@ public ParCELEvaluationResult getAccuracyAndCorrectness4(OWLClassExpression desc result.correctness = un / (double) negativeExamples.size(); result.completeness = cp / (double) positiveExamples.size(); - if (result.correctness >= 1.0d - noise) { - result.coveredPositiveExamples = coveredPositiveExamples; - } + result.coveredPositiveExamples = coveredPositiveExamples; + result.coveredNegativeExamples = coveredNegativeExamples; return result; } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java index ddb2366358..4de20adfd6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java @@ -202,4 +202,8 @@ public void setUseCardinalityRestrictions(boolean useCardinalityRestrictions) { public boolean getUseCardinalityRestrictions() { return this.useCardinalityRestrictions; } + + public RefinementOperator getOperatorPrototype() { + return operatorPrototype; + } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index 1aa037fa30..7a6491c079 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -2,15 +2,19 @@ import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; import org.apache.log4j.Logger; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.refinementoperators.DownwardRefinementOperator; import org.dllearner.refinementoperators.LengthLimitedRefinementOperator; import org.dllearner.refinementoperators.RefinementOperator; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.mindswap.pellet.exceptions.InternalReasonerException; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; import org.semanticweb.owlapi.model.OWLObjectUnionOf; /** @@ -160,18 +164,19 @@ private ParCELExtraNode checkAndCreateNewNode(OWLClassExpression description, Pa return null; // false, node cannot be added // currently, noise is not processed. it should be processed later - ParCELEvaluationResult accurateAndCorrectness = learningProblem - .getAccuracyAndCorrectness4(description, learner.getNoiseAllowed()); -// System.out.println(description + ":" + accurateAndCorrectness); + ParCELEvaluationResult accuracyAndCorrectness = learner.getAccuracyAndCorrectness(parentNode, description); // description is too weak, i.e. covered no positive example - if (accurateAndCorrectness.accuracy == -1.0d) + if (accuracyAndCorrectness.accuracy == -1.0d) return null; - ParCELExtraNode newNode = new ParCELExtraNode(parentNode, description, - accurateAndCorrectness.accuracy, accurateAndCorrectness.correctness, - accurateAndCorrectness.completeness, - accurateAndCorrectness.coveredPositiveExamples); + ParCELExtraNode newNode = new ParCELExtraNode( + parentNode, description, + accuracyAndCorrectness.accuracy, accuracyAndCorrectness.correctness, + accuracyAndCorrectness.completeness, + accuracyAndCorrectness.coveredPositiveExamples, + accuracyAndCorrectness.coveredNegativeExamples + ); if (parentNode != null) parentNode.addChild(newNode); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java index 485f5c899c..44652cfa9a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java @@ -79,21 +79,17 @@ protected ParCELExtraNode checkAndCreateNewNodeV2(OWLClassExpression description * * */ - ParCELEvaluationResult evaluationResult = learningProblem - .getAccuracyAndCorrectnessEx(description); + ParCELEvaluationResult evaluationResult = learner.getAccuracyAndCorrectness(parentNode, description); // cover no positive example && no negative example ==> weak description if ((evaluationResult.getCompleteness() == 0) && (evaluationResult.getCorrectness() == 1)) return null; - ParCELExtraNode newNode = new ParCELExtraNode(parentNode, description, - evaluationResult.getAccuracy(), evaluationResult.getCorrectness(), - evaluationResult.getCompleteness(), evaluationResult.getCoveredPositiveExamples()); - - // newNode.setCorrectness(evaluationResult.getCorrectness()); - // newNode.setCompleteness(evaluationResult.getCompleteness()); - // newNode.setCoveredPositiveExamples(evaluationResult.getCoveredPossitiveExamples()); - newNode.setCoveredNegativeExamples(evaluationResult.getCoveredNegativeExamples()); + ParCELExtraNode newNode = new ParCELExtraNode( + parentNode, description, + evaluationResult.getAccuracy(), evaluationResult.getCorrectness(), evaluationResult.getCompleteness(), + evaluationResult.getCoveredPositiveExamples(), evaluationResult.getCoveredNegativeExamples() + ); if (parentNode != null) parentNode.addChild(newNode); @@ -102,4 +98,5 @@ protected ParCELExtraNode checkAndCreateNewNodeV2(OWLClassExpression description } // addNode() + } diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java index 2cde54744e..ac91cd3442 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java @@ -146,6 +146,15 @@ public double getTestAccuracyOrTooWeak(OWLClassExpression description, double no return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); } + public double getAccuracyOrTooWeak(Set coveredPositives, Set coveredNegatives, double noise) { + int tp = coveredPositives.size(); + int fp = coveredNegatives.size(); + int tn = negativeExamples.size() - fp; + int fn = positiveExamples.size() - tp; + + return accuracyMethod.getAccOrTooWeak2(tp, fn, fp, tn, noise); + } + public void printTestEvaluation(OWLClassExpression description) { Set tp = reasoner.hasType(description, positiveTestExamples); Set fn = new TreeSet<>(positiveTestExamples); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java b/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java new file mode 100644 index 0000000000..8ab3943b76 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java @@ -0,0 +1,4 @@ +package org.dllearner.refinementoperators; + +public interface DownwardRefinementOperator { +} diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 51fcaf616b..e6ab03e367 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -70,7 +70,11 @@ * */ @ComponentAnn(name = "rho refinement operator", shortName = "rho", version = 0.8) -public class RhoDRDown extends RefinementOperatorAdapter implements Component, CustomHierarchyRefinementOperator, CustomStartRefinementOperator, ReasoningBasedRefinementOperator, Cloneable { +public class RhoDRDown + extends RefinementOperatorAdapter + implements Component, CustomHierarchyRefinementOperator, CustomStartRefinementOperator, + ReasoningBasedRefinementOperator, Cloneable, DownwardRefinementOperator +{ private static Logger logger = LoggerFactory.getLogger(RhoDRDown.class); private final static Marker sparql_debug = new BasicMarkerFactory().getMarker("SD"); @@ -537,6 +541,10 @@ public Set refine(OWLClassExpression description, int maxLen refinements.removeIf(this::containsNegation); } + if (!useDisjunction) { + refinements.removeIf(r -> r instanceof OWLObjectUnionOf); + } + if (useSomeOnly) { refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r)); } @@ -1034,145 +1042,6 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description) { return true; } - private boolean checkRefinability(OWLNaryBooleanClassExpression description) { - Set unrefinableOperands = new TreeSet<>(); - - for (OWLClassExpression op : description.getOperandsAsList()) { - if (unrefinableOperands.contains(op)) { - return false; - } - - if (!mayBeRefinable(op)) { - unrefinableOperands.add(op); - } - } - - return true; - } - - private boolean mayBeRefinable(OWLClassExpression description) { - if (description.isOWLThing()) { - return true; - } - - if (description.isOWLNothing()) { - return false; - } - - if(!description.isAnonymous()) { - Set refinements = classHierarchy.getSubClasses(description, true); - refinements.remove(df.getOWLNothing()); - - return !refinements.isEmpty(); - } - - if (description instanceof OWLObjectComplementOf) { - OWLClassExpression operand = ((OWLObjectComplementOf) description).getOperand(); - - if (operand.isAnonymous()){ - return false; - } - - Set refinements = classHierarchy.getSuperClasses(operand, true); - refinements.remove(df.getOWLThing()); - - return !refinements.isEmpty(); - } - - if (description instanceof OWLObjectIntersectionOf || description instanceof OWLObjectUnionOf) { - return true; - } - - if (description instanceof OWLObjectSomeValuesFrom) { - OWLObjectPropertyExpression role = ((OWLObjectSomeValuesFrom) description).getProperty(); - OWLClassExpression filler = ((OWLObjectSomeValuesFrom) description).getFiller(); - - if (mayBeRefinable(filler)) { - return true; - } - - Set moreSpecialRoles = objectPropertyHierarchy.getMoreSpecialRoles(role.getNamedProperty()); - - if (!moreSpecialRoles.isEmpty()) { - return true; - } - - OWLObjectProperty prop = role.isAnonymous() ? role.getNamedProperty() : role.asOWLObjectProperty(); - - if (useCardinalityRestrictions - && isPropertyAllowedInCardinalityRestrictions(prop) - && maxNrOfFillers.get(role) > 1 - ) { - return true; - } - - if (useHasValueConstructor && filler.isOWLThing()){ - Set frequentIndividuals = frequentValues.get(role); - - return frequentIndividuals != null; - } - - return false; - } - - if (description instanceof OWLObjectAllValuesFrom) { - OWLObjectPropertyExpression role = ((OWLObjectAllValuesFrom) description).getProperty(); - OWLClassExpression filler = ((OWLObjectAllValuesFrom) description).getFiller(); - - if (mayBeRefinable(filler)) { - return true; - } - - if (!filler.isOWLNothing() && !filler.isAnonymous()) { - return true; - } - - Set subProperties = objectPropertyHierarchy.getMoreSpecialRoles(role.getNamedProperty()); - - return !subProperties.isEmpty(); - } - - if (description instanceof OWLObjectCardinalityRestriction) { - OWLObjectPropertyExpression role = ((OWLObjectCardinalityRestriction) description).getProperty(); - OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); - int cardinality = ((OWLObjectCardinalityRestriction) description).getCardinality(); - - if (description instanceof OWLObjectMaxCardinality) { - if (cardinality > 1) { - return true; - } - - return (useNegation || cardinality > 0) && mayBeRefinable(constructNegationInNNF(description)); - } - - if (description instanceof OWLObjectMinCardinality) { - return cardinality < maxNrOfFillers.get(role) || mayBeRefinable(filler); - } - - if (description instanceof OWLObjectExactCardinality) { - return mayBeRefinable(filler); - } - } - - if (description instanceof OWLDataSomeValuesFrom) { - return true; // TODO: MY not implemented - } - - if (description instanceof OWLDataHasValue) { - OWLDataPropertyExpression dp = ((OWLDataHasValue) description).getProperty(); - - if (dp.isAnonymous()) { - return false; - } - - Set subDPs = dataPropertyHierarchy.getMoreSpecialRoles(dp.asOWLDataProperty()); - - return !subDPs.isEmpty(); - } - - return false; - } - private boolean isCombinable(OWLClassExpression ce, OWLClassExpression child) { boolean combinable = true; @@ -1373,50 +1242,49 @@ private void computeTopRefinements(int maxLength, OWLClassExpression domain) { else topARefinements.get(domain).get(i).addAll(mA.get(domain).get(i)); // combinations has several numbers => generate disjunct - } else if (useDisjunction) { + } - // check whether the combination makes sense, i.e. whether - // all lengths mentioned in it have corresponding elements - // e.g. when negation is deactivated there won't be elements of - // length 2 in M - boolean validCombo = true; - for(Integer j : combo) { - if((domain == null && m.get(j).size()==0) || - (domain != null && mA.get(domain).get(j).size()==0)) - validCombo = false; - } + // check whether the combination makes sense, i.e. whether + // all lengths mentioned in it have corresponding elements + // e.g. when negation is deactivated there won't be elements of + // length 2 in M + boolean validCombo = true; + for(Integer j : combo) { + if((domain == null && m.get(j).size()==0) || + (domain != null && mA.get(domain).get(j).size()==0)) + validCombo = false; + } - if(validCombo) { + if(validCombo) { - SortedSet baseSet = new TreeSet<>(); - for(Integer j : combo) { - if(domain == null) - baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); - else - baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); - } + SortedSet baseSet = new TreeSet<>(); + for(Integer j : combo) { + if(domain == null) + baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); + else + baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); + } - // convert all concepts in ordered negation normal form - Set tmp = new HashSet<>(); - for(OWLClassExpression concept : baseSet) { - tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); - } - baseSet = new TreeSet<>(tmp); - - // apply the exists filter (throwing out all refinements with - // double \exists r for any r) - // TODO: similar filtering can be done for boolean datatype - // properties - if(applyExistsFilter) { - baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); - } + // convert all concepts in ordered negation normal form + Set tmp = new HashSet<>(); + for(OWLClassExpression concept : baseSet) { + tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); + } + baseSet = new TreeSet<>(tmp); + + // apply the exists filter (throwing out all refinements with + // double \exists r for any r) + // TODO: similar filtering can be done for boolean datatype + // properties + if(applyExistsFilter) { + baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); + } - // add computed refinements - if(domain == null) { - topRefinements.get(i).addAll(baseSet); - } else { - topARefinements.get(domain).get(i).addAll(baseSet); - } + // add computed refinements + if(domain == null) { + topRefinements.get(i).addAll(baseSet); + } else { + topARefinements.get(domain).get(i).addAll(baseSet); } } } diff --git a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java index 4f73ec03f8..2c891c9007 100644 --- a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java +++ b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java @@ -157,7 +157,7 @@ public void run() { logger.info("#EVAL# fn: " + fn); logger.info("#EVAL# acc: " + acc); - ParCELEvaluationResult ev =((ParCELPosNegLP) lp).getAccuracyAndCorrectness4(expression, 1); + ParCELEvaluationResult ev =((ParCELPosNegLP) lp).getAccuracyAndCorrectness4(expression); System.out.println(ev); Set coveredIndividuals = rs.getIndividuals(expression); From 6c9e996117dcf37a5de3913cf48bc1c81b951be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 09:54:37 +0100 Subject: [PATCH 08/67] accuracy speedup reverted --- .../org/dllearner/algorithms/celoe/CELOE.java | 69 ++++--------------- .../algorithms/parcel/ParCELAbstract.java | 60 +++------------- .../algorithms/parcel/ParCELExtraNode.java | 6 +- .../algorithms/parcel/ParCELWorker.java | 14 +--- .../parcelex/ParCELExWorkerAbstract.java | 2 +- .../parcelex/ParCELearnerExV12.java | 4 -- .../DownwardRefinementOperator.java | 4 -- .../refinementoperators/RhoDRDown.java | 2 +- 8 files changed, 33 insertions(+), 128 deletions(-) delete mode 100644 components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index e706c59bf4..12a2e161f6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -573,22 +573,28 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { logger.trace(sparql_debug, sparql_debug_out + "NOT ALLOWED"); return false; } - - OENode node = createNode(parentNode, description); - + + // quality of class expression (return if too weak) + Monitor mon = MonitorFactory.start("lp"); + logger.trace(sparql_debug, sparql_debug_out); + double accuracy = learningProblem.getAccuracyOrTooWeak(description, noise); + logger.trace(sparql_debug, "`acc:"+accuracy); + mon.stop(); + // issue a warning if accuracy is not between 0 and 1 or -1 (too weak) - if(node.getAccuracy() > 1.0 || (node.getAccuracy() < 0.0 && node.getAccuracy() != -1)) { - throw new RuntimeException("Invalid accuracy value " + node.getAccuracy() + " for class expression " + description + - ". This could be caused by a bug in the heuristic measure and should be reported to the DL-Learner bug tracker."); + if(accuracy > 1.0 || (accuracy < 0.0 && accuracy != -1)) { + throw new RuntimeException("Invalid accuracy value " + accuracy + " for class expression " + description + + ". This could be caused by a bug in the heuristic measure and should be reported to the DL-Learner bug tracker."); } - + expressionTests++; - + // return FALSE if 'too weak' - if(node.getAccuracy() == -1) { + if(accuracy == -1) { return false; } + OENode node = new OENode(description, accuracy); searchTree.addNode(parentNode, node); // in some cases (e.g. mutation) fully evaluating even a single class expression is too expensive @@ -674,51 +680,6 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { return true; } - - private OENode createNode(OENode parent, OWLClassExpression refinement) { - if (!(learningProblem instanceof PosNegLP)) { - Monitor mon = MonitorFactory.start("lp"); - double accuracy = learningProblem.getAccuracyOrTooWeak(refinement, noise); - mon.stop(); - - return new OENode(refinement, accuracy); - } - - PosNegLP posNegLP = (PosNegLP) learningProblem; - - Set coveredPositives; - Set coveredNegatives; - - Monitor mon = MonitorFactory.start("lp"); - - if (parent == null) { - coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); - } else if (operator instanceof DownwardRefinementOperator) { - coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); - } else { - Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); - uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); - Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); - uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); - - coveredPositives = reasoner.hasType(refinement, uncoveredPositives); - coveredPositives.addAll(parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); - coveredNegatives.addAll(parent.getCoveredNegativeExamples()); - } - - double accuracy = posNegLP.getAccuracyOrTooWeak(coveredPositives, coveredNegatives, noise); - - mon.stop(); - - OENode node = new OENode(refinement, accuracy); - node.setCoveredPositiveExamples(coveredPositives); - node.setCoveredNegativeExamples(coveredNegatives); - - return node; - } // checks whether the class expression is allowed private boolean isDescriptionAllowed(OWLClassExpression description, OENode parentNode) { diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 4fa0b47fa9..4b03447181 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -264,30 +264,21 @@ protected void initOperatorIfAny() { } protected void initSearchTree() { + // TODO: only ParCELPosNegLP supported + // create a start node in the search tree - // currently, start class is always Thing (initialised in the init() method) allDescriptions.add(startClass); - ParCELNode startNode; - - if (learningProblem instanceof ParCELPosNegLP) { - Set coveredPositives = reasoner.hasType(startClass, positiveExamples); - Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); - - ParCELEvaluationResult accAndCorr = ((ParCELPosNegLP) learningProblem) - .getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + Set coveredPositives = reasoner.hasType(startClass, positiveExamples); + Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); - startNode = new ParCELNode( - null, startClass, - accAndCorr.accuracy, accAndCorr.correctness, accAndCorr.completeness - ); - - startNode.setCoveredPositiveExamples(coveredPositives); - startNode.setCoveredNegativeExamples(coveredNegatives); - } else { - double accuracy = this.positiveExamples.size() / (double) (this.positiveExamples.size() + this.negativeExamples.size()); - startNode = new ParCELNode(null, startClass, accuracy, 0, 1.0); - } + ParCELEvaluationResult accAndCorr = ((ParCELPosNegLP) learningProblem).getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + ParCELNode startNode = new ParCELNode( + null, startClass, + accAndCorr.accuracy, accAndCorr.correctness, accAndCorr.completeness + ); + startNode.setCoveredPositiveExamples(coveredPositives); + startNode.setCoveredNegativeExamples(coveredNegatives); searchTree.add(startNode); } @@ -467,35 +458,6 @@ protected void createWorkerPool() { ", max pool size: " + workerPool.getMaximumPoolSize()); } - public ParCELEvaluationResult getAccuracyAndCorrectness(OENode parent, OWLClassExpression refinement) { - // TODO: only ParCELPosNegLP supported - - ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; - - Set coveredPositives; - Set coveredNegatives; - - if (parent == null) { - coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); - } else if (refinementOperatorPool.getFactory().getOperatorPrototype() instanceof DownwardRefinementOperator) { - coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); - } else { - Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); - uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); - Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); - uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); - - coveredPositives = reasoner.hasType(refinement, uncoveredPositives); - coveredPositives.addAll(parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); - coveredNegatives.addAll(parent.getCoveredNegativeExamples()); - } - - return posNegLP.getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); - } - /** * Get the union of all the best (reduced) partial definitions * diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java index 4e12babaf0..88f04ce9a6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java @@ -106,7 +106,7 @@ public ParCELExtraNode(ParCELNode parentNode, OWLClassExpression description, do double correctness, double completeness, Set cp) { super(parentNode, description, accuracy, correctness, completeness); - super.setCoveredPositiveExamples(cp); + setCoveredPositiveExamples(cp); } @@ -123,8 +123,8 @@ public ParCELExtraNode(ParCELNode parentNode, OWLClassExpression description, do double correctness, double completeness, Set cp, Set cn) { super(parentNode, description, accuracy, correctness, completeness); - super.setCoveredPositiveExamples(cp); - super.setCoveredNegativeExamples(cn); + setCoveredPositiveExamples(cp); + setCoveredNegativeExamples(cn); } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index 7a6491c079..a7f1c8beb6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -1,21 +1,12 @@ package org.dllearner.algorithms.parcel; import java.util.HashSet; -import java.util.Map; -import java.util.Set; import java.util.TreeSet; -import java.util.stream.Collectors; -import org.apache.log4j.Logger; -import org.dllearner.core.AbstractReasonerComponent; -import org.dllearner.refinementoperators.DownwardRefinementOperator; -import org.dllearner.refinementoperators.LengthLimitedRefinementOperator; import org.dllearner.refinementoperators.RefinementOperator; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.mindswap.pellet.exceptions.InternalReasonerException; import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLIndividual; -import org.semanticweb.owlapi.model.OWLObjectUnionOf; /** * ParCEL worker which find and evaluate the refinements for a given node. @@ -164,7 +155,7 @@ private ParCELExtraNode checkAndCreateNewNode(OWLClassExpression description, Pa return null; // false, node cannot be added // currently, noise is not processed. it should be processed later - ParCELEvaluationResult accuracyAndCorrectness = learner.getAccuracyAndCorrectness(parentNode, description); + ParCELEvaluationResult accuracyAndCorrectness = learningProblem.getAccuracyAndCorrectness4(description); // description is too weak, i.e. covered no positive example if (accuracyAndCorrectness.accuracy == -1.0d) @@ -174,8 +165,7 @@ private ParCELExtraNode checkAndCreateNewNode(OWLClassExpression description, Pa parentNode, description, accuracyAndCorrectness.accuracy, accuracyAndCorrectness.correctness, accuracyAndCorrectness.completeness, - accuracyAndCorrectness.coveredPositiveExamples, - accuracyAndCorrectness.coveredNegativeExamples + accuracyAndCorrectness.coveredPositiveExamples ); if (parentNode != null) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java index 44652cfa9a..06b2e0ef8e 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java @@ -79,7 +79,7 @@ protected ParCELExtraNode checkAndCreateNewNodeV2(OWLClassExpression description * * */ - ParCELEvaluationResult evaluationResult = learner.getAccuracyAndCorrectness(parentNode, description); + ParCELEvaluationResult evaluationResult = learningProblem.getAccuracyAndCorrectnessEx(description); // cover no positive example && no negative example ==> weak description if ((evaluationResult.getCompleteness() == 0) && (evaluationResult.getCorrectness() == 1)) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index 98fa9ea73a..b748d44846 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -212,10 +212,6 @@ public void start() { reset(); initSearchTree(); - - ParCELNode startNode = searchTree.first(); - startNode.setCoveredPositiveExamples(positiveExamples); - startNode.setCoveredNegativeExamples(negativeExamples); createWorkerPool(); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java b/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java deleted file mode 100644 index 8ab3943b76..0000000000 --- a/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.dllearner.refinementoperators; - -public interface DownwardRefinementOperator { -} diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index e6ab03e367..4125280177 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -73,7 +73,7 @@ public class RhoDRDown extends RefinementOperatorAdapter implements Component, CustomHierarchyRefinementOperator, CustomStartRefinementOperator, - ReasoningBasedRefinementOperator, Cloneable, DownwardRefinementOperator + ReasoningBasedRefinementOperator, Cloneable { private static Logger logger = LoggerFactory.getLogger(RhoDRDown.class); From bd4fd60bda9acdd1ae008ff56ca18ee45fdd95c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 09:10:46 +0100 Subject: [PATCH 09/67] rho useDisjunction when refining upwards and accuracy speedup --- .../org/dllearner/algorithms/celoe/CELOE.java | 75 ++++-- .../dllearner/algorithms/celoe/OENode.java | 30 +++ .../algorithms/parcel/ParCELAbstract.java | 61 ++++- .../algorithms/parcel/ParCELExtraNode.java | 2 +- .../algorithms/parcel/ParCELNode.java | 29 +-- .../algorithms/parcel/ParCELPosNegLP.java | 11 +- .../ParCELRefinementOperatorFactory.java | 4 + .../algorithms/parcel/ParCELWorker.java | 21 +- .../parcelex/ParCELExWorkerAbstract.java | 17 +- .../dllearner/learningproblems/PosNegLP.java | 9 + .../DownwardRefinementOperator.java | 4 + .../refinementoperators/RhoDRDown.java | 226 ++++-------------- .../dllearner/cli/ExpressionValidation.java | 2 +- 13 files changed, 237 insertions(+), 254 deletions(-) create mode 100644 components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index bb9f959fe5..e706c59bf4 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -574,34 +574,28 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { return false; } - // quality of class expression (return if too weak) - Monitor mon = MonitorFactory.start("lp"); - logger.trace(sparql_debug, sparql_debug_out); - double accuracy = learningProblem.getAccuracyOrTooWeak(description, noise); - logger.trace(sparql_debug, "`acc:"+accuracy); - mon.stop(); + OENode node = createNode(parentNode, description); // issue a warning if accuracy is not between 0 and 1 or -1 (too weak) - if(accuracy > 1.0 || (accuracy < 0.0 && accuracy != -1)) { - throw new RuntimeException("Invalid accuracy value " + accuracy + " for class expression " + description + + if(node.getAccuracy() > 1.0 || (node.getAccuracy() < 0.0 && node.getAccuracy() != -1)) { + throw new RuntimeException("Invalid accuracy value " + node.getAccuracy() + " for class expression " + description + ". This could be caused by a bug in the heuristic measure and should be reported to the DL-Learner bug tracker."); } expressionTests++; // return FALSE if 'too weak' - if(accuracy == -1) { + if(node.getAccuracy() == -1) { return false; } - - OENode node = new OENode(description, accuracy); + searchTree.addNode(parentNode, node); // in some cases (e.g. mutation) fully evaluating even a single class expression is too expensive // due to the high number of examples -- so we just stick to the approximate accuracy if(singleSuggestionMode) { - if(accuracy > bestAccuracy) { - bestAccuracy = accuracy; + if(node.getAccuracy() > bestAccuracy) { + bestAccuracy = node.getAccuracy(); bestDescription = description; logger.info("more accurate (" + dfPercent.format(bestAccuracy) + ") class expression found: " + descriptionToString(bestDescription)); // + getTemporaryString(bestDescription)); } @@ -616,8 +610,8 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { EvaluatedDescription worst = bestEvaluatedDescriptions.getWorst(); double accThreshold = worst.getAccuracy(); isCandidate = - (accuracy > accThreshold || - (accuracy >= accThreshold && OWLClassExpressionUtils.getLength(description) < worst.getDescriptionLength())); + (node.getAccuracy() > accThreshold || + (node.getAccuracy() >= accThreshold && OWLClassExpressionUtils.getLength(description) < worst.getDescriptionLength())); } if(isCandidate) { @@ -638,7 +632,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { boolean shorterDescriptionExists = false; if(forceMutualDifference) { for(EvaluatedDescription ed : bestEvaluatedDescriptions.getSet()) { - if(Math.abs(ed.getAccuracy()-accuracy) <= 0.00001 && ConceptTransformation.isSubdescription(niceDescription, ed.getDescription())) { + if(Math.abs(ed.getAccuracy()-node.getAccuracy()) <= 0.00001 && ConceptTransformation.isSubdescription(niceDescription, ed.getDescription())) { // System.out.println("shorter: " + ed.getDescription()); shorterDescriptionExists = true; break; @@ -651,7 +645,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { if(!shorterDescriptionExists) { if(!filterFollowsFromKB || !((ClassLearningProblem)learningProblem).followsFromKB(niceDescription)) { // System.out.println(node + "->" + niceDescription); - bestEvaluatedDescriptions.add(niceDescription, accuracy, learningProblem); + bestEvaluatedDescriptions.add(niceDescription, node.getAccuracy(), learningProblem); // System.out.println("acc: " + accuracy); // System.out.println(bestEvaluatedDescriptions); } @@ -662,7 +656,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { // System.out.println(bestEvaluatedDescriptions.getSet().size()); } - if (accuracy >= 1 - noiseWithMargin) { + if (node.getAccuracy() >= 1 - noiseWithMargin) { if (solutionCandidates.isEmpty() || (node.getAccuracy() > solutionCandidates.firstKey().getAccuracy() && solutionCandidates.keySet().stream().allMatch( @@ -680,6 +674,51 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { return true; } + + private OENode createNode(OENode parent, OWLClassExpression refinement) { + if (!(learningProblem instanceof PosNegLP)) { + Monitor mon = MonitorFactory.start("lp"); + double accuracy = learningProblem.getAccuracyOrTooWeak(refinement, noise); + mon.stop(); + + return new OENode(refinement, accuracy); + } + + PosNegLP posNegLP = (PosNegLP) learningProblem; + + Set coveredPositives; + Set coveredNegatives; + + Monitor mon = MonitorFactory.start("lp"); + + if (parent == null) { + coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); + } else if (operator instanceof DownwardRefinementOperator) { + coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); + } else { + Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); + uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); + Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); + uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); + + coveredPositives = reasoner.hasType(refinement, uncoveredPositives); + coveredPositives.addAll(parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); + coveredNegatives.addAll(parent.getCoveredNegativeExamples()); + } + + double accuracy = posNegLP.getAccuracyOrTooWeak(coveredPositives, coveredNegatives, noise); + + mon.stop(); + + OENode node = new OENode(refinement, accuracy); + node.setCoveredPositiveExamples(coveredPositives); + node.setCoveredNegativeExamples(coveredNegatives); + + return node; + } // checks whether the class expression is allowed private boolean isDescriptionAllowed(OWLClassExpression description, OENode parentNode) { diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java index 8c1423c7e2..bab752f857 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java @@ -23,9 +23,12 @@ import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionUtils; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; import java.text.DecimalFormat; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; /** * A node in the search tree of the ontology engineering algorithm. @@ -54,6 +57,9 @@ public class OENode extends AbstractSearchTreeNode implements SearchTree // OWLClassExpression in this node - it is a better heuristic indicator than child count // (and avoids the problem that adding children changes the heuristic value) private int refinementCount = 0; + + private Set coveredPositiveExamples = new TreeSet<>(); + private Set coveredNegativeExamples = new TreeSet<>(); private static DecimalFormat dfPercent = new DecimalFormat("0.00%"); @@ -135,4 +141,28 @@ public int getRefinementCount() { public void setRefinementCount(int refinementCount) { this.refinementCount = refinementCount; } + + public Set getCoveredPositiveExamples() { + return coveredPositiveExamples; + } + + public Set getCoveredNegativeExamples() { + return coveredNegativeExamples; + } + + public void setCoveredPositiveExamples(Set coveredPositiveExamples) { + this.coveredPositiveExamples.clear(); + + if (coveredPositiveExamples != null) { + this.coveredPositiveExamples.addAll(coveredPositiveExamples); + } + } + + public void setCoveredNegativeExamples(Set coveredNegativeExamples) { + this.coveredNegativeExamples.clear(); + + if (coveredNegativeExamples != null) { + this.coveredNegativeExamples.addAll(coveredNegativeExamples); + } + } } \ No newline at end of file diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 0daf586b0a..4fa0b47fa9 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -1,5 +1,7 @@ package org.dllearner.algorithms.parcel; +import com.jamonapi.Monitor; +import com.jamonapi.MonitorFactory; import org.apache.log4j.Logger; import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer; @@ -11,10 +13,8 @@ import org.dllearner.core.owl.DatatypePropertyHierarchy; import org.dllearner.core.owl.OWLObjectUnionOfImplExt; import org.dllearner.core.owl.ObjectPropertyHierarchy; -import org.dllearner.refinementoperators.CustomHierarchyRefinementOperator; -import org.dllearner.refinementoperators.CustomStartRefinementOperator; -import org.dllearner.refinementoperators.RefinementOperator; -import org.dllearner.refinementoperators.RhoDRDown; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.refinementoperators.*; import org.dllearner.utilities.owl.EvaluatedDescriptionComparator; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionUtils; @@ -24,6 +24,7 @@ import org.semanticweb.owlapi.model.OWLIndividual; import org.springframework.beans.factory.annotation.Autowired; +import javax.naming.OperationNotSupportedException; import java.lang.invoke.MethodHandles; import java.text.DecimalFormat; import java.util.*; @@ -267,8 +268,27 @@ protected void initSearchTree() { // currently, start class is always Thing (initialised in the init() method) allDescriptions.add(startClass); - double accuracy = this.positiveExamples.size() / (double) (this.positiveExamples.size() + this.negativeExamples.size()); - ParCELNode startNode = new ParCELNode(null, startClass, accuracy, 0, 1.0); + ParCELNode startNode; + + if (learningProblem instanceof ParCELPosNegLP) { + Set coveredPositives = reasoner.hasType(startClass, positiveExamples); + Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); + + ParCELEvaluationResult accAndCorr = ((ParCELPosNegLP) learningProblem) + .getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + + startNode = new ParCELNode( + null, startClass, + accAndCorr.accuracy, accAndCorr.correctness, accAndCorr.completeness + ); + + startNode.setCoveredPositiveExamples(coveredPositives); + startNode.setCoveredNegativeExamples(coveredNegatives); + } else { + double accuracy = this.positiveExamples.size() / (double) (this.positiveExamples.size() + this.negativeExamples.size()); + startNode = new ParCELNode(null, startClass, accuracy, 0, 1.0); + } + searchTree.add(startNode); } @@ -447,6 +467,35 @@ protected void createWorkerPool() { ", max pool size: " + workerPool.getMaximumPoolSize()); } + public ParCELEvaluationResult getAccuracyAndCorrectness(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set coveredPositives; + Set coveredNegatives; + + if (parent == null) { + coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); + } else if (refinementOperatorPool.getFactory().getOperatorPrototype() instanceof DownwardRefinementOperator) { + coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); + } else { + Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); + uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); + Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); + uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); + + coveredPositives = reasoner.hasType(refinement, uncoveredPositives); + coveredPositives.addAll(parent.getCoveredPositiveExamples()); + coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); + coveredNegatives.addAll(parent.getCoveredNegativeExamples()); + } + + return posNegLP.getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + } + /** * Get the union of all the best (reduced) partial definitions * diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java index 76758ccdb5..4e12babaf0 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java @@ -74,7 +74,7 @@ public ParCELExtraNode(ParCELNode node) { */ public ParCELExtraNode(ParCELNode node, Set cp) { super(node.getParent(), node.getDescription(), node.getAccuracy(), node.getCorrectness(), node.getCompleteness()); - super.coveredPositiveExamples = cp; + setCoveredPositiveExamples(cp); } /** diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java index e2a27fde0b..7542c2a482 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java @@ -22,9 +22,6 @@ public class ParCELNode extends OENode { private double correctness = -1.0; private double completeness = -1.0; - protected Set coveredPositiveExamples = new HashSet<>(); - protected final Set coveredNegativeExamples = new HashSet<>(); - private final DecimalFormat dfPercent = new DecimalFormat("0.00%"); @@ -41,8 +38,8 @@ public ParCELNode(OENode parentNode, OWLClassExpression description, Set coveredPositiveExamples, Set coveredNegativeExamples) { super(description, 0); setParent(parentNode); - this.coveredPositiveExamples.addAll(coveredPositiveExamples); - this.coveredNegativeExamples.addAll(coveredNegativeExamples); + setCoveredPositiveExamples(coveredPositiveExamples); + setCoveredNegativeExamples(coveredNegativeExamples); } public void setCorrectness(double cor) { @@ -65,28 +62,6 @@ public void setAccuracy(double acc) { this.accuracy = acc; } - public Set getCoveredPositiveExamples() { - return this.coveredPositiveExamples; - } - - public Set getCoveredNegativeExamples() { - return this.coveredNegativeExamples; - } - - public void setCoveredPositiveExamples(Set coveredPositiveExamples) { - if (coveredPositiveExamples != null) - this.coveredPositiveExamples.addAll(coveredPositiveExamples); - else - this.coveredPositiveExamples.clear(); - } - - public void setCoveredNegativeExamples(Set coveredNegativeExamples) { - if (coveredNegativeExamples != null) - this.coveredNegativeExamples.addAll(coveredNegativeExamples); - else - this.coveredNegativeExamples.clear(); - } - @Override public String toString() { String ret = OWLAPIRenderers.toManchesterOWLSyntax(this.getDescription()); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java index b664679047..b105501376 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -468,10 +468,14 @@ public ParCELEvaluationResult getAccuracyAndCorrectness3(OWLClassExpression desc } - public ParCELEvaluationResult getAccuracyAndCorrectness4(OWLClassExpression description, double noise) { + public ParCELEvaluationResult getAccuracyAndCorrectness4(OWLClassExpression description) { Set coveredPositiveExamples = reasoner.hasType(description, positiveExamples); Set coveredNegativeExamples = reasoner.hasType(description, negativeExamples); + return getAccuracyAndCorrectness4(coveredPositiveExamples, coveredNegativeExamples); + } + + public ParCELEvaluationResult getAccuracyAndCorrectness4(Set coveredPositiveExamples, Set coveredNegativeExamples) { if (coveredPositiveExamples.isEmpty()) { return new ParCELEvaluationResult(-1, 0, 0); } @@ -485,9 +489,8 @@ public ParCELEvaluationResult getAccuracyAndCorrectness4(OWLClassExpression desc result.correctness = un / (double) negativeExamples.size(); result.completeness = cp / (double) positiveExamples.size(); - if (result.correctness >= 1.0d - noise) { - result.coveredPositiveExamples = coveredPositiveExamples; - } + result.coveredPositiveExamples = coveredPositiveExamples; + result.coveredNegativeExamples = coveredNegativeExamples; return result; } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java index ddb2366358..4de20adfd6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java @@ -202,4 +202,8 @@ public void setUseCardinalityRestrictions(boolean useCardinalityRestrictions) { public boolean getUseCardinalityRestrictions() { return this.useCardinalityRestrictions; } + + public RefinementOperator getOperatorPrototype() { + return operatorPrototype; + } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index 1aa037fa30..7a6491c079 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -2,15 +2,19 @@ import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; import org.apache.log4j.Logger; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.refinementoperators.DownwardRefinementOperator; import org.dllearner.refinementoperators.LengthLimitedRefinementOperator; import org.dllearner.refinementoperators.RefinementOperator; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.mindswap.pellet.exceptions.InternalReasonerException; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; import org.semanticweb.owlapi.model.OWLObjectUnionOf; /** @@ -160,18 +164,19 @@ private ParCELExtraNode checkAndCreateNewNode(OWLClassExpression description, Pa return null; // false, node cannot be added // currently, noise is not processed. it should be processed later - ParCELEvaluationResult accurateAndCorrectness = learningProblem - .getAccuracyAndCorrectness4(description, learner.getNoiseAllowed()); -// System.out.println(description + ":" + accurateAndCorrectness); + ParCELEvaluationResult accuracyAndCorrectness = learner.getAccuracyAndCorrectness(parentNode, description); // description is too weak, i.e. covered no positive example - if (accurateAndCorrectness.accuracy == -1.0d) + if (accuracyAndCorrectness.accuracy == -1.0d) return null; - ParCELExtraNode newNode = new ParCELExtraNode(parentNode, description, - accurateAndCorrectness.accuracy, accurateAndCorrectness.correctness, - accurateAndCorrectness.completeness, - accurateAndCorrectness.coveredPositiveExamples); + ParCELExtraNode newNode = new ParCELExtraNode( + parentNode, description, + accuracyAndCorrectness.accuracy, accuracyAndCorrectness.correctness, + accuracyAndCorrectness.completeness, + accuracyAndCorrectness.coveredPositiveExamples, + accuracyAndCorrectness.coveredNegativeExamples + ); if (parentNode != null) parentNode.addChild(newNode); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java index 485f5c899c..44652cfa9a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExWorkerAbstract.java @@ -79,21 +79,17 @@ protected ParCELExtraNode checkAndCreateNewNodeV2(OWLClassExpression description * * */ - ParCELEvaluationResult evaluationResult = learningProblem - .getAccuracyAndCorrectnessEx(description); + ParCELEvaluationResult evaluationResult = learner.getAccuracyAndCorrectness(parentNode, description); // cover no positive example && no negative example ==> weak description if ((evaluationResult.getCompleteness() == 0) && (evaluationResult.getCorrectness() == 1)) return null; - ParCELExtraNode newNode = new ParCELExtraNode(parentNode, description, - evaluationResult.getAccuracy(), evaluationResult.getCorrectness(), - evaluationResult.getCompleteness(), evaluationResult.getCoveredPositiveExamples()); - - // newNode.setCorrectness(evaluationResult.getCorrectness()); - // newNode.setCompleteness(evaluationResult.getCompleteness()); - // newNode.setCoveredPositiveExamples(evaluationResult.getCoveredPossitiveExamples()); - newNode.setCoveredNegativeExamples(evaluationResult.getCoveredNegativeExamples()); + ParCELExtraNode newNode = new ParCELExtraNode( + parentNode, description, + evaluationResult.getAccuracy(), evaluationResult.getCorrectness(), evaluationResult.getCompleteness(), + evaluationResult.getCoveredPositiveExamples(), evaluationResult.getCoveredNegativeExamples() + ); if (parentNode != null) parentNode.addChild(newNode); @@ -102,4 +98,5 @@ protected ParCELExtraNode checkAndCreateNewNodeV2(OWLClassExpression description } // addNode() + } diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java index 2cde54744e..ac91cd3442 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java @@ -146,6 +146,15 @@ public double getTestAccuracyOrTooWeak(OWLClassExpression description, double no return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); } + public double getAccuracyOrTooWeak(Set coveredPositives, Set coveredNegatives, double noise) { + int tp = coveredPositives.size(); + int fp = coveredNegatives.size(); + int tn = negativeExamples.size() - fp; + int fn = positiveExamples.size() - tp; + + return accuracyMethod.getAccOrTooWeak2(tp, fn, fp, tn, noise); + } + public void printTestEvaluation(OWLClassExpression description) { Set tp = reasoner.hasType(description, positiveTestExamples); Set fn = new TreeSet<>(positiveTestExamples); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java b/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java new file mode 100644 index 0000000000..8ab3943b76 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/refinementoperators/DownwardRefinementOperator.java @@ -0,0 +1,4 @@ +package org.dllearner.refinementoperators; + +public interface DownwardRefinementOperator { +} diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 51fcaf616b..e6ab03e367 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -70,7 +70,11 @@ * */ @ComponentAnn(name = "rho refinement operator", shortName = "rho", version = 0.8) -public class RhoDRDown extends RefinementOperatorAdapter implements Component, CustomHierarchyRefinementOperator, CustomStartRefinementOperator, ReasoningBasedRefinementOperator, Cloneable { +public class RhoDRDown + extends RefinementOperatorAdapter + implements Component, CustomHierarchyRefinementOperator, CustomStartRefinementOperator, + ReasoningBasedRefinementOperator, Cloneable, DownwardRefinementOperator +{ private static Logger logger = LoggerFactory.getLogger(RhoDRDown.class); private final static Marker sparql_debug = new BasicMarkerFactory().getMarker("SD"); @@ -537,6 +541,10 @@ public Set refine(OWLClassExpression description, int maxLen refinements.removeIf(this::containsNegation); } + if (!useDisjunction) { + refinements.removeIf(r -> r instanceof OWLObjectUnionOf); + } + if (useSomeOnly) { refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r)); } @@ -1034,145 +1042,6 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description) { return true; } - private boolean checkRefinability(OWLNaryBooleanClassExpression description) { - Set unrefinableOperands = new TreeSet<>(); - - for (OWLClassExpression op : description.getOperandsAsList()) { - if (unrefinableOperands.contains(op)) { - return false; - } - - if (!mayBeRefinable(op)) { - unrefinableOperands.add(op); - } - } - - return true; - } - - private boolean mayBeRefinable(OWLClassExpression description) { - if (description.isOWLThing()) { - return true; - } - - if (description.isOWLNothing()) { - return false; - } - - if(!description.isAnonymous()) { - Set refinements = classHierarchy.getSubClasses(description, true); - refinements.remove(df.getOWLNothing()); - - return !refinements.isEmpty(); - } - - if (description instanceof OWLObjectComplementOf) { - OWLClassExpression operand = ((OWLObjectComplementOf) description).getOperand(); - - if (operand.isAnonymous()){ - return false; - } - - Set refinements = classHierarchy.getSuperClasses(operand, true); - refinements.remove(df.getOWLThing()); - - return !refinements.isEmpty(); - } - - if (description instanceof OWLObjectIntersectionOf || description instanceof OWLObjectUnionOf) { - return true; - } - - if (description instanceof OWLObjectSomeValuesFrom) { - OWLObjectPropertyExpression role = ((OWLObjectSomeValuesFrom) description).getProperty(); - OWLClassExpression filler = ((OWLObjectSomeValuesFrom) description).getFiller(); - - if (mayBeRefinable(filler)) { - return true; - } - - Set moreSpecialRoles = objectPropertyHierarchy.getMoreSpecialRoles(role.getNamedProperty()); - - if (!moreSpecialRoles.isEmpty()) { - return true; - } - - OWLObjectProperty prop = role.isAnonymous() ? role.getNamedProperty() : role.asOWLObjectProperty(); - - if (useCardinalityRestrictions - && isPropertyAllowedInCardinalityRestrictions(prop) - && maxNrOfFillers.get(role) > 1 - ) { - return true; - } - - if (useHasValueConstructor && filler.isOWLThing()){ - Set frequentIndividuals = frequentValues.get(role); - - return frequentIndividuals != null; - } - - return false; - } - - if (description instanceof OWLObjectAllValuesFrom) { - OWLObjectPropertyExpression role = ((OWLObjectAllValuesFrom) description).getProperty(); - OWLClassExpression filler = ((OWLObjectAllValuesFrom) description).getFiller(); - - if (mayBeRefinable(filler)) { - return true; - } - - if (!filler.isOWLNothing() && !filler.isAnonymous()) { - return true; - } - - Set subProperties = objectPropertyHierarchy.getMoreSpecialRoles(role.getNamedProperty()); - - return !subProperties.isEmpty(); - } - - if (description instanceof OWLObjectCardinalityRestriction) { - OWLObjectPropertyExpression role = ((OWLObjectCardinalityRestriction) description).getProperty(); - OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); - int cardinality = ((OWLObjectCardinalityRestriction) description).getCardinality(); - - if (description instanceof OWLObjectMaxCardinality) { - if (cardinality > 1) { - return true; - } - - return (useNegation || cardinality > 0) && mayBeRefinable(constructNegationInNNF(description)); - } - - if (description instanceof OWLObjectMinCardinality) { - return cardinality < maxNrOfFillers.get(role) || mayBeRefinable(filler); - } - - if (description instanceof OWLObjectExactCardinality) { - return mayBeRefinable(filler); - } - } - - if (description instanceof OWLDataSomeValuesFrom) { - return true; // TODO: MY not implemented - } - - if (description instanceof OWLDataHasValue) { - OWLDataPropertyExpression dp = ((OWLDataHasValue) description).getProperty(); - - if (dp.isAnonymous()) { - return false; - } - - Set subDPs = dataPropertyHierarchy.getMoreSpecialRoles(dp.asOWLDataProperty()); - - return !subDPs.isEmpty(); - } - - return false; - } - private boolean isCombinable(OWLClassExpression ce, OWLClassExpression child) { boolean combinable = true; @@ -1373,50 +1242,49 @@ private void computeTopRefinements(int maxLength, OWLClassExpression domain) { else topARefinements.get(domain).get(i).addAll(mA.get(domain).get(i)); // combinations has several numbers => generate disjunct - } else if (useDisjunction) { + } - // check whether the combination makes sense, i.e. whether - // all lengths mentioned in it have corresponding elements - // e.g. when negation is deactivated there won't be elements of - // length 2 in M - boolean validCombo = true; - for(Integer j : combo) { - if((domain == null && m.get(j).size()==0) || - (domain != null && mA.get(domain).get(j).size()==0)) - validCombo = false; - } + // check whether the combination makes sense, i.e. whether + // all lengths mentioned in it have corresponding elements + // e.g. when negation is deactivated there won't be elements of + // length 2 in M + boolean validCombo = true; + for(Integer j : combo) { + if((domain == null && m.get(j).size()==0) || + (domain != null && mA.get(domain).get(j).size()==0)) + validCombo = false; + } - if(validCombo) { + if(validCombo) { - SortedSet baseSet = new TreeSet<>(); - for(Integer j : combo) { - if(domain == null) - baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); - else - baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); - } + SortedSet baseSet = new TreeSet<>(); + for(Integer j : combo) { + if(domain == null) + baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); + else + baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); + } - // convert all concepts in ordered negation normal form - Set tmp = new HashSet<>(); - for(OWLClassExpression concept : baseSet) { - tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); - } - baseSet = new TreeSet<>(tmp); - - // apply the exists filter (throwing out all refinements with - // double \exists r for any r) - // TODO: similar filtering can be done for boolean datatype - // properties - if(applyExistsFilter) { - baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); - } + // convert all concepts in ordered negation normal form + Set tmp = new HashSet<>(); + for(OWLClassExpression concept : baseSet) { + tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); + } + baseSet = new TreeSet<>(tmp); + + // apply the exists filter (throwing out all refinements with + // double \exists r for any r) + // TODO: similar filtering can be done for boolean datatype + // properties + if(applyExistsFilter) { + baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); + } - // add computed refinements - if(domain == null) { - topRefinements.get(i).addAll(baseSet); - } else { - topARefinements.get(domain).get(i).addAll(baseSet); - } + // add computed refinements + if(domain == null) { + topRefinements.get(i).addAll(baseSet); + } else { + topARefinements.get(domain).get(i).addAll(baseSet); } } } diff --git a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java index 4f73ec03f8..2c891c9007 100644 --- a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java +++ b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java @@ -157,7 +157,7 @@ public void run() { logger.info("#EVAL# fn: " + fn); logger.info("#EVAL# acc: " + acc); - ParCELEvaluationResult ev =((ParCELPosNegLP) lp).getAccuracyAndCorrectness4(expression, 1); + ParCELEvaluationResult ev =((ParCELPosNegLP) lp).getAccuracyAndCorrectness4(expression); System.out.println(ev); Set coveredIndividuals = rs.getIndividuals(expression); From a23688dd510fb1bac91b98229051c84ccfeb8c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 10:17:01 +0100 Subject: [PATCH 10/67] minor refactoring, search tree initialization --- .../algorithms/parcel/ParCELAbstract.java | 30 ++++++++----------- .../algorithms/parcel/ParCELExtraNode.java | 6 ++-- .../parcelex/ParCELearnerExV12.java | 4 --- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 4fa0b47fa9..cea6e325be 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -264,30 +264,24 @@ protected void initOperatorIfAny() { } protected void initSearchTree() { + // TODO: only ParCELPosNegLP supported + // create a start node in the search tree - // currently, start class is always Thing (initialised in the init() method) allDescriptions.add(startClass); - ParCELNode startNode; - - if (learningProblem instanceof ParCELPosNegLP) { - Set coveredPositives = reasoner.hasType(startClass, positiveExamples); - Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); + Set coveredPositives = reasoner.hasType(startClass, positiveExamples); + Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); - ParCELEvaluationResult accAndCorr = ((ParCELPosNegLP) learningProblem) - .getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + ParCELEvaluationResult accAndCorr = ((ParCELPosNegLP) learningProblem) + .getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); - startNode = new ParCELNode( - null, startClass, - accAndCorr.accuracy, accAndCorr.correctness, accAndCorr.completeness - ); + ParCELNode startNode = new ParCELNode( + null, startClass, + accAndCorr.accuracy, accAndCorr.correctness, accAndCorr.completeness + ); - startNode.setCoveredPositiveExamples(coveredPositives); - startNode.setCoveredNegativeExamples(coveredNegatives); - } else { - double accuracy = this.positiveExamples.size() / (double) (this.positiveExamples.size() + this.negativeExamples.size()); - startNode = new ParCELNode(null, startClass, accuracy, 0, 1.0); - } + startNode.setCoveredPositiveExamples(coveredPositives); + startNode.setCoveredNegativeExamples(coveredNegatives); searchTree.add(startNode); } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java index 4e12babaf0..88f04ce9a6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java @@ -106,7 +106,7 @@ public ParCELExtraNode(ParCELNode parentNode, OWLClassExpression description, do double correctness, double completeness, Set cp) { super(parentNode, description, accuracy, correctness, completeness); - super.setCoveredPositiveExamples(cp); + setCoveredPositiveExamples(cp); } @@ -123,8 +123,8 @@ public ParCELExtraNode(ParCELNode parentNode, OWLClassExpression description, do double correctness, double completeness, Set cp, Set cn) { super(parentNode, description, accuracy, correctness, completeness); - super.setCoveredPositiveExamples(cp); - super.setCoveredNegativeExamples(cn); + setCoveredPositiveExamples(cp); + setCoveredNegativeExamples(cn); } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index 98fa9ea73a..b748d44846 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -212,10 +212,6 @@ public void start() { reset(); initSearchTree(); - - ParCELNode startNode = searchTree.first(); - startNode.setCoveredPositiveExamples(positiveExamples); - startNode.setCoveredNegativeExamples(negativeExamples); createWorkerPool(); From 24af23d7e8f072a2282e23e641184b27bcb1b8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 11:17:24 +0100 Subject: [PATCH 11/67] rho top refinements correction, CWR min cardinality hasType corrected for inverse properties --- .../algorithms/parcel/ParCELExtraNode.java | 3 +- .../reasoning/ClosedWorldReasoner.java | 4 +- .../refinementoperators/RhoDRDown.java | 78 +++++++++---------- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java index 88f04ce9a6..23a873b78e 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELExtraNode.java @@ -147,8 +147,7 @@ public double getExtraInfo() { public void setExtraInfo(double d) { this.extraInfo = d; } - - + public void setType(int t) { this.type = t; } diff --git a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java index 3f3806726b..300f57ce98 100644 --- a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java +++ b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java @@ -637,6 +637,8 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ int nrOfFillers = 0; int nrOfEntries = mapping.keySet().size(); for (Entry> entry : mapping.entrySet()) { + index++; + OWLIndividual subject = entry.getKey(); SortedSet objects = entry.getValue(); @@ -650,7 +652,7 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ return true; } } else { - if (nrOfEntries - index < cardinality) { + if (nrOfEntries - index + nrOfFillers < cardinality) { return false; } } diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index e6ab03e367..c4f4331d14 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -1242,49 +1242,49 @@ private void computeTopRefinements(int maxLength, OWLClassExpression domain) { else topARefinements.get(domain).get(i).addAll(mA.get(domain).get(i)); // combinations has several numbers => generate disjunct - } - - // check whether the combination makes sense, i.e. whether - // all lengths mentioned in it have corresponding elements - // e.g. when negation is deactivated there won't be elements of - // length 2 in M - boolean validCombo = true; - for(Integer j : combo) { - if((domain == null && m.get(j).size()==0) || - (domain != null && mA.get(domain).get(j).size()==0)) - validCombo = false; - } - - if(validCombo) { - - SortedSet baseSet = new TreeSet<>(); + } else { + // check whether the combination makes sense, i.e. whether + // all lengths mentioned in it have corresponding elements + // e.g. when negation is deactivated there won't be elements of + // length 2 in M + boolean validCombo = true; for(Integer j : combo) { - if(domain == null) - baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); - else - baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); + if((domain == null && m.get(j).size()==0) || + (domain != null && mA.get(domain).get(j).size()==0)) + validCombo = false; } - // convert all concepts in ordered negation normal form - Set tmp = new HashSet<>(); - for(OWLClassExpression concept : baseSet) { - tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); - } - baseSet = new TreeSet<>(tmp); - - // apply the exists filter (throwing out all refinements with - // double \exists r for any r) - // TODO: similar filtering can be done for boolean datatype - // properties - if(applyExistsFilter) { - baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); - } + if(validCombo) { - // add computed refinements - if(domain == null) { - topRefinements.get(i).addAll(baseSet); - } else { - topARefinements.get(domain).get(i).addAll(baseSet); + SortedSet baseSet = new TreeSet<>(); + for(Integer j : combo) { + if(domain == null) + baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); + else + baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); + } + + // convert all concepts in ordered negation normal form + Set tmp = new HashSet<>(); + for(OWLClassExpression concept : baseSet) { + tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); + } + baseSet = new TreeSet<>(tmp); + + // apply the exists filter (throwing out all refinements with + // double \exists r for any r) + // TODO: similar filtering can be done for boolean datatype + // properties + if(applyExistsFilter) { + baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); + } + + // add computed refinements + if(domain == null) { + topRefinements.get(i).addAll(baseSet); + } else { + topARefinements.get(domain).get(i).addAll(baseSet); + } } } } From f9646712a41b40a8ec5c2981ca9f3efcfb07b985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 11:19:10 +0100 Subject: [PATCH 12/67] rho top refinements correction, CWR min cardinality hasType corrected for inverse properties --- .../reasoning/ClosedWorldReasoner.java | 4 +- .../refinementoperators/RhoDRDown.java | 78 +++++++++---------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java index 3f3806726b..300f57ce98 100644 --- a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java +++ b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java @@ -637,6 +637,8 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ int nrOfFillers = 0; int nrOfEntries = mapping.keySet().size(); for (Entry> entry : mapping.entrySet()) { + index++; + OWLIndividual subject = entry.getKey(); SortedSet objects = entry.getValue(); @@ -650,7 +652,7 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ return true; } } else { - if (nrOfEntries - index < cardinality) { + if (nrOfEntries - index + nrOfFillers < cardinality) { return false; } } diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 4125280177..128a90804f 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -1242,49 +1242,49 @@ private void computeTopRefinements(int maxLength, OWLClassExpression domain) { else topARefinements.get(domain).get(i).addAll(mA.get(domain).get(i)); // combinations has several numbers => generate disjunct - } - - // check whether the combination makes sense, i.e. whether - // all lengths mentioned in it have corresponding elements - // e.g. when negation is deactivated there won't be elements of - // length 2 in M - boolean validCombo = true; - for(Integer j : combo) { - if((domain == null && m.get(j).size()==0) || - (domain != null && mA.get(domain).get(j).size()==0)) - validCombo = false; - } - - if(validCombo) { - - SortedSet baseSet = new TreeSet<>(); + } else { + // check whether the combination makes sense, i.e. whether + // all lengths mentioned in it have corresponding elements + // e.g. when negation is deactivated there won't be elements of + // length 2 in M + boolean validCombo = true; for(Integer j : combo) { - if(domain == null) - baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); - else - baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); + if((domain == null && m.get(j).size()==0) || + (domain != null && mA.get(domain).get(j).size()==0)) + validCombo = false; } - // convert all concepts in ordered negation normal form - Set tmp = new HashSet<>(); - for(OWLClassExpression concept : baseSet) { - tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); - } - baseSet = new TreeSet<>(tmp); - - // apply the exists filter (throwing out all refinements with - // double \exists r for any r) - // TODO: similar filtering can be done for boolean datatype - // properties - if(applyExistsFilter) { - baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); - } + if(validCombo) { - // add computed refinements - if(domain == null) { - topRefinements.get(i).addAll(baseSet); - } else { - topARefinements.get(domain).get(i).addAll(baseSet); + SortedSet baseSet = new TreeSet<>(); + for(Integer j : combo) { + if(domain == null) + baseSet = MathOperations.incCrossProduct(baseSet, m.get(j)); + else + baseSet = MathOperations.incCrossProduct(baseSet, mA.get(domain).get(j)); + } + + // convert all concepts in ordered negation normal form + Set tmp = new HashSet<>(); + for(OWLClassExpression concept : baseSet) { + tmp.add((OWLObjectUnionOf) ConceptTransformation.nnf(concept)); + } + baseSet = new TreeSet<>(tmp); + + // apply the exists filter (throwing out all refinements with + // double \exists r for any r) + // TODO: similar filtering can be done for boolean datatype + // properties + if(applyExistsFilter) { + baseSet.removeIf(MathOperations::containsDoubleObjectSomeRestriction); + } + + // add computed refinements + if(domain == null) { + topRefinements.get(i).addAll(baseSet); + } else { + topARefinements.get(domain).get(i).addAll(baseSet); + } } } } From c952cdd7ed38285ca5d9c5ba3122416f73e42db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 12:44:17 +0100 Subject: [PATCH 13/67] celoe evaluated descriptions not computed from scratch --- .../org/dllearner/algorithms/celoe/CELOE.java | 20 ++++++++---- .../dllearner/learningproblems/PosNegLP.java | 9 ------ .../learningproblems/PosNegLPStandard.java | 32 +++++++++++++++++++ 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index e706c59bf4..bb4e6c37d9 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -27,10 +27,7 @@ import org.dllearner.core.owl.DatatypePropertyHierarchy; import org.dllearner.core.owl.ObjectPropertyHierarchy; import org.dllearner.kb.OWLAPIOntology; -import org.dllearner.learningproblems.ClassAsInstanceLearningProblem; -import org.dllearner.learningproblems.ClassLearningProblem; -import org.dllearner.learningproblems.PosNegLP; -import org.dllearner.learningproblems.PosOnlyLP; +import org.dllearner.learningproblems.*; import org.dllearner.reasoning.ClosedWorldReasoner; import org.dllearner.reasoning.OWLAPIReasoner; import org.dllearner.reasoning.ReasonerImplementation; @@ -645,7 +642,16 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { if(!shorterDescriptionExists) { if(!filterFollowsFromKB || !((ClassLearningProblem)learningProblem).followsFromKB(niceDescription)) { // System.out.println(node + "->" + niceDescription); - bestEvaluatedDescriptions.add(niceDescription, node.getAccuracy(), learningProblem); + + if (learningProblem instanceof PosNegLPStandard) { + EvaluatedDescription ed = ((PosNegLPStandard) learningProblem).constructEvaluatedDescription( + niceDescription, node.getCoveredPositiveExamples(), node.getCoveredNegativeExamples(), node.getAccuracy() + ); + bestEvaluatedDescriptions.add(ed); + } else { + bestEvaluatedDescriptions.add(niceDescription, node.getAccuracy(), learningProblem); + } + // System.out.println("acc: " + accuracy); // System.out.println(bestEvaluatedDescriptions); } @@ -676,7 +682,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { } private OENode createNode(OENode parent, OWLClassExpression refinement) { - if (!(learningProblem instanceof PosNegLP)) { + if (!(learningProblem instanceof PosNegLPStandard)) { Monitor mon = MonitorFactory.start("lp"); double accuracy = learningProblem.getAccuracyOrTooWeak(refinement, noise); mon.stop(); @@ -684,7 +690,7 @@ private OENode createNode(OENode parent, OWLClassExpression refinement) { return new OENode(refinement, accuracy); } - PosNegLP posNegLP = (PosNegLP) learningProblem; + PosNegLPStandard posNegLP = (PosNegLPStandard) learningProblem; Set coveredPositives; Set coveredNegatives; diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java index ac91cd3442..2cde54744e 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java @@ -146,15 +146,6 @@ public double getTestAccuracyOrTooWeak(OWLClassExpression description, double no return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); } - public double getAccuracyOrTooWeak(Set coveredPositives, Set coveredNegatives, double noise) { - int tp = coveredPositives.size(); - int fp = coveredNegatives.size(); - int tn = negativeExamples.size() - fp; - int fn = positiveExamples.size() - tp; - - return accuracyMethod.getAccOrTooWeak2(tp, fn, fp, tn, noise); - } - public void printTestEvaluation(OWLClassExpression description) { Set tp = reasoner.hasType(description, positiveTestExamples); Set fn = new TreeSet<>(positiveTestExamples); diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java index d8e3bbe872..c301974a19 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java @@ -23,10 +23,13 @@ import org.dllearner.utilities.ReasoningUtils.Coverage; import org.dllearner.utilities.owl.OWLClassExpressionUtils; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLEntity; import org.semanticweb.owlapi.model.OWLIndividual; import org.semanticweb.owlapi.model.OWLNamedIndividual; +import java.util.Set; import java.util.SortedSet; +import java.util.TreeSet; /** * The aim of this learning problem is to learn a concept definition such that @@ -107,6 +110,15 @@ public double getAccuracyOrTooWeak(OWLClassExpression description, double noise) return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveExamples, negativeExamples, noise); } + public double getAccuracyOrTooWeak(Set coveredPositives, Set coveredNegatives, double noise) { + int tp = coveredPositives.size(); + int fp = coveredNegatives.size(); + int tn = negativeExamples.size() - fp; + int fn = positiveExamples.size() - tp; + + return accuracyMethod.getAccOrTooWeak2(tp, fn, fp, tn, noise); + } + /* (non-Javadoc) * @see org.dllearner.core.LearningProblem#evaluate(org.dllearner.core.owl.Description) */ @@ -116,6 +128,26 @@ public EvaluatedDescription evaluate(OWLClassExpression description, double nois return new EvaluatedDescriptionPosNeg(description, score); } + public EvaluatedDescription constructEvaluatedDescription( + OWLClassExpression description, + Set coveredPositiveExamples, Set coveredNegativeExamples, + double accuracy + ) { + Set uncoveredPositiveExamples = new TreeSet<>(positiveExamples); + uncoveredPositiveExamples.removeAll(coveredPositiveExamples); + Set uncoveredNegativeExamples = new TreeSet<>(negativeExamples); + uncoveredNegativeExamples.removeAll(coveredNegativeExamples); + + ScoreTwoValued score = new ScoreTwoValued( + OWLClassExpressionUtils.getLength(description), + getPercentPerLengthUnit(), + coveredPositiveExamples, uncoveredPositiveExamples, coveredNegativeExamples, uncoveredNegativeExamples, + accuracy + ); + + return new EvaluatedDescriptionPosNeg(description, score); + } + /* (non-Javadoc) * @see java.lang.Object#clone() */ From b9ddecdba97898bf91d78c1cd8db26230d4c6e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 13:57:15 +0100 Subject: [PATCH 14/67] rho memento, upward refining enhanced, isSomeOnlySatisfied improved --- .../refinementoperators/RhoDRDown.java | 85 ++++++++++++------- .../RhoDRDownConfigOptionsMemento.java | 47 ++++++++++ 2 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 128a90804f..f2cc743e92 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -196,7 +196,7 @@ public class RhoDRDown private boolean useCardinalityRestrictions = true; @ConfigOption(description="a set of roles which can be used in qualified cardinality restrictions") - protected Set allowedRolesInCardinalityRestrictions = null; + private Set allowedRolesInCardinalityRestrictions = null; @ConfigOption(description="support of local reflexivity of an object property expression (owl:hasSelf), e.g. \u2203 loves.Self for a narcissistic", defaultValue="false") private boolean useHasSelf = false; @@ -480,10 +480,6 @@ public void init() throws ComponentInitException { initialized = true; } - protected void isFinal() { - if (initialized) throw new IllegalStateException(this.getClass() + " already initialised in " + Thread.currentThread().getStackTrace()[2].getMethodName()); - } - @Override public Set refine(OWLClassExpression concept) { throw new RuntimeException(); @@ -546,7 +542,7 @@ public Set refine(OWLClassExpression description, int maxLen } if (useSomeOnly) { - refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r)); + refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r, Set.of())); } // refinements.addAll(classHierarchy.getMoreSpecialConcepts(description)); @@ -917,15 +913,20 @@ private Set refineUpwards( OWLClassExpression description, int maxLength, List knownRefinements, OWLClassExpression currDomain ) { - boolean useNegationBackup = useNegation; - boolean useDisjunctionBackup = useDisjunction; - boolean useAllConstructorBackup = useAllConstructor; - boolean useExistsConstructorBackup = useExistsConstructor; + RhoDRDownConfigOptionsMemento configOptions = new RhoDRDownConfigOptionsMemento(this); useNegation = true; useDisjunction = true; - useAllConstructor = useExistsConstructorBackup; - useExistsConstructor = useAllConstructorBackup; + useSomeOnly = false; + useObjectValueNegation = true; + + boolean optionTmp = useAllConstructor; + useAllConstructor = useExistsConstructor; + useExistsConstructor = optionTmp; + + optionTmp = applyAllFilter; + applyAllFilter = applyExistsFilter; + applyExistsFilter = optionTmp; TreeSet results = new TreeSet<>(); @@ -937,6 +938,8 @@ private Set refineUpwards( int lengthDiff = Math.max(0, OWLClassExpressionUtils.getLength(negatedDescription, lengthMetric) - OWLClassExpressionUtils.getLength(description, lengthMetric)); Set refinements = refine(negatedDescription, maxLength+lengthDiff+1, knownRefinements, currDomain); + configOptions.restore(this); + description = description.getNNF(); for (OWLClassExpression d : refinements) { @@ -948,10 +951,10 @@ private Set refineUpwards( // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check if(description.compareTo(dNeg) != 0 - && (useDisjunctionBackup || !containsDisjunction(dNeg)) - && (useNegationBackup || !containsNegation(dNeg)) + && (useDisjunction || !containsDisjunction(dNeg)) + && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) - && (!useSomeOnly || (!(dNeg instanceof OWLObjectAllValuesFrom) && isSomeOnlySatisfied(dNeg))) + && (!useSomeOnly || (!(dNeg instanceof OWLObjectAllValuesFrom) && isSomeOnlySatisfied(dNeg, Set.of()))) && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength ) { results.add(dNeg); @@ -961,12 +964,9 @@ private Set refineUpwards( if (description.isOWLNothing()) { results.add(df.getOWLThing()); } - } catch (Throwable t) {} - - useNegation = useNegationBackup; - useDisjunction = useDisjunctionBackup; - useAllConstructor = useAllConstructorBackup; - useExistsConstructor = useExistsConstructorBackup; + } catch (Throwable t) { + configOptions.restore(this); + } return results; } @@ -997,7 +997,7 @@ private boolean containsObjectValueNegation(OWLClassExpression description) { ); } - private boolean isSomeOnlySatisfied(OWLClassExpression description) { + private boolean isSomeOnlySatisfied(OWLClassExpression description, Set prevSomeValuesProperties) { if (description instanceof OWLObjectIntersectionOf) { Set allValuesProperties = ((OWLObjectIntersectionOf) description).getOperands() @@ -1014,29 +1014,34 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description) { allValuesProperties.removeAll(someValuesProperties); return allValuesProperties.isEmpty() - && ((OWLObjectIntersectionOf) description).getOperands().stream().allMatch(this::isSomeOnlySatisfied); + && ((OWLObjectIntersectionOf) description).getOperands() + .stream().allMatch(op -> isSomeOnlySatisfied(op, someValuesProperties)); } if (description instanceof OWLObjectUnionOf) { - return ((OWLObjectUnionOf) description).getOperands().stream().allMatch(this::isSomeOnlySatisfied); + return ((OWLObjectUnionOf) description).getOperands() + .stream().allMatch(op -> + (!(op instanceof OWLObjectSomeValuesFrom) || prevSomeValuesProperties.contains(op)) + && isSomeOnlySatisfied(op, Set.of()) + ); } if (description instanceof OWLObjectSomeValuesFrom) { OWLClassExpression filler = ((OWLObjectSomeValuesFrom) description).getFiller(); - return isSomeOnlySatisfied(filler); + return isSomeOnlySatisfied(filler, Set.of()); } if (description instanceof OWLObjectAllValuesFrom) { OWLClassExpression filler = ((OWLObjectAllValuesFrom) description).getFiller(); - return isSomeOnlySatisfied(filler); + return isSomeOnlySatisfied(filler, Set.of()); } if (description instanceof OWLObjectCardinalityRestriction) { OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); - return isSomeOnlySatisfied(filler); + return isSomeOnlySatisfied(filler, Set.of()); } return true; @@ -1193,6 +1198,10 @@ public void setDropDisjuncts(boolean dropDisjuncts) { this.dropDisjuncts = dropDisjuncts; } + public boolean isDropDisjuncts() { + return dropDisjuncts; + } + private void computeTopRefinements(int maxLength) { computeTopRefinements(maxLength, null); } @@ -2002,7 +2011,6 @@ public boolean isUseDataHasValueConstructor() { } public void setUseDataHasValueConstructor(boolean useDataHasValueConstructor) { - isFinal(); this.useDataHasValueConstructor = useDataHasValueConstructor; } @@ -2043,7 +2051,6 @@ public boolean isUseHasValueConstructor() { } public void setUseHasValueConstructor(boolean useHasValueConstructor) { - isFinal(); this.useHasValueConstructor = useHasValueConstructor; } @@ -2052,7 +2059,6 @@ public boolean isUseCardinalityRestrictions() { } public void setUseCardinalityRestrictions(boolean useCardinalityRestrictions) { - isFinal(); this.useCardinalityRestrictions = useCardinalityRestrictions; } @@ -2173,12 +2179,15 @@ public void setUseObjectValueNegation(boolean useObjectValueNegation) { this.useObjectValueNegation = useObjectValueNegation; } + public boolean isUseObjectValueNegation() { + return useObjectValueNegation; + } + public boolean isUseNumericDatatypes() { return useNumericDatatypes; } public void setUseNumericDatatypes(boolean useNumericDatatypes) { - isFinal(); this.useNumericDatatypes = useNumericDatatypes; } @@ -2186,10 +2195,13 @@ public void setUseNumericDatatypes(boolean useNumericDatatypes) { * @param useInverse whether to use inverse properties in property restrictions */ public void setUseInverse(boolean useInverse) { - isFinal(); this.useInverse = useInverse; } + public boolean isUseInverse() { + return useInverse; + } + /** * @param useSomeOnly whether to allow universal restrictions on a property r only if there exists already * a existential restriction on the same property in an intersection @@ -2198,14 +2210,21 @@ public void setUseSomeOnly(boolean useSomeOnly) { this.useSomeOnly = useSomeOnly; } + public boolean isUseSomeOnly() { + return useSomeOnly; + } + /** * @param useTimeDatatypes whether to use data/time literal restrictions */ public void setUseTimeDatatypes(boolean useTimeDatatypes) { - isFinal(); this.useTimeDatatypes = useTimeDatatypes; } + public boolean isUseTimeDatatypes() { + return useTimeDatatypes; + } + public int getMaxNrOfSplits() { return maxNrOfSplits; } diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java new file mode 100644 index 0000000000..16ab66eba1 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -0,0 +1,47 @@ +package org.dllearner.refinementoperators; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; +import org.semanticweb.owlapi.model.*; + +import java.util.*; + +// does not store the reasoner used by the originator +public class RhoDRDownConfigOptionsMemento { + + private final boolean applyAllFilter; + private final boolean applyExistsFilter; + + private final boolean useAllConstructor; + private final boolean useExistsConstructor; + + private final boolean useNegation; + private final boolean useDisjunction; + private final boolean useSomeOnly; + private final boolean useObjectValueNegation; + + public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { + applyAllFilter = originator.isApplyAllFilter(); + applyExistsFilter = originator.isApplyExistsFilter(); + + useAllConstructor = originator.isUseAllConstructor(); + useExistsConstructor = originator.isUseExistsConstructor(); + + useNegation = originator.isUseNegation(); + useDisjunction = originator.isUseDisjunction(); + useSomeOnly = originator.isUseSomeOnly(); + useObjectValueNegation = originator.isUseObjectValueNegation(); + } + + public void restore(RhoDRDown originator) { + originator.setApplyAllFilter(applyAllFilter); + originator.setApplyExistsFilter(applyExistsFilter); + + originator.setUseAllConstructor(useAllConstructor); + originator.setUseExistsConstructor(useExistsConstructor); + + originator.setUseNegation(useNegation); + originator.setUseDisjunction(useDisjunction); + originator.setUseSomeOnly(useSomeOnly); + originator.setUseObjectValueNegation(useObjectValueNegation); + } +} From 23832cf3ed0096cdb59e3e026a799b6a182ee78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 13:57:15 +0100 Subject: [PATCH 15/67] rho memento, upward refining enhanced, isSomeOnlySatisfied improved --- .../refinementoperators/RhoDRDown.java | 85 ++++++++++++------- .../RhoDRDownConfigOptionsMemento.java | 47 ++++++++++ 2 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index c4f4331d14..e57f7c79b0 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -196,7 +196,7 @@ public class RhoDRDown private boolean useCardinalityRestrictions = true; @ConfigOption(description="a set of roles which can be used in qualified cardinality restrictions") - protected Set allowedRolesInCardinalityRestrictions = null; + private Set allowedRolesInCardinalityRestrictions = null; @ConfigOption(description="support of local reflexivity of an object property expression (owl:hasSelf), e.g. \u2203 loves.Self for a narcissistic", defaultValue="false") private boolean useHasSelf = false; @@ -480,10 +480,6 @@ public void init() throws ComponentInitException { initialized = true; } - protected void isFinal() { - if (initialized) throw new IllegalStateException(this.getClass() + " already initialised in " + Thread.currentThread().getStackTrace()[2].getMethodName()); - } - @Override public Set refine(OWLClassExpression concept) { throw new RuntimeException(); @@ -546,7 +542,7 @@ public Set refine(OWLClassExpression description, int maxLen } if (useSomeOnly) { - refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r)); + refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r, Set.of())); } // refinements.addAll(classHierarchy.getMoreSpecialConcepts(description)); @@ -917,15 +913,20 @@ private Set refineUpwards( OWLClassExpression description, int maxLength, List knownRefinements, OWLClassExpression currDomain ) { - boolean useNegationBackup = useNegation; - boolean useDisjunctionBackup = useDisjunction; - boolean useAllConstructorBackup = useAllConstructor; - boolean useExistsConstructorBackup = useExistsConstructor; + RhoDRDownConfigOptionsMemento configOptions = new RhoDRDownConfigOptionsMemento(this); useNegation = true; useDisjunction = true; - useAllConstructor = useExistsConstructorBackup; - useExistsConstructor = useAllConstructorBackup; + useSomeOnly = false; + useObjectValueNegation = true; + + boolean optionTmp = useAllConstructor; + useAllConstructor = useExistsConstructor; + useExistsConstructor = optionTmp; + + optionTmp = applyAllFilter; + applyAllFilter = applyExistsFilter; + applyExistsFilter = optionTmp; TreeSet results = new TreeSet<>(); @@ -937,6 +938,8 @@ private Set refineUpwards( int lengthDiff = Math.max(0, OWLClassExpressionUtils.getLength(negatedDescription, lengthMetric) - OWLClassExpressionUtils.getLength(description, lengthMetric)); Set refinements = refine(negatedDescription, maxLength+lengthDiff+1, knownRefinements, currDomain); + configOptions.restore(this); + description = description.getNNF(); for (OWLClassExpression d : refinements) { @@ -948,10 +951,10 @@ private Set refineUpwards( // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check if(description.compareTo(dNeg) != 0 - && (useDisjunctionBackup || !containsDisjunction(dNeg)) - && (useNegationBackup || !containsNegation(dNeg)) + && (useDisjunction || !containsDisjunction(dNeg)) + && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) - && (!useSomeOnly || (!(dNeg instanceof OWLObjectAllValuesFrom) && isSomeOnlySatisfied(dNeg))) + && (!useSomeOnly || (!(dNeg instanceof OWLObjectAllValuesFrom) && isSomeOnlySatisfied(dNeg, Set.of()))) && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength ) { results.add(dNeg); @@ -961,12 +964,9 @@ private Set refineUpwards( if (description.isOWLNothing()) { results.add(df.getOWLThing()); } - } catch (Throwable t) {} - - useNegation = useNegationBackup; - useDisjunction = useDisjunctionBackup; - useAllConstructor = useAllConstructorBackup; - useExistsConstructor = useExistsConstructorBackup; + } catch (Throwable t) { + configOptions.restore(this); + } return results; } @@ -997,7 +997,7 @@ private boolean containsObjectValueNegation(OWLClassExpression description) { ); } - private boolean isSomeOnlySatisfied(OWLClassExpression description) { + private boolean isSomeOnlySatisfied(OWLClassExpression description, Set prevSomeValuesProperties) { if (description instanceof OWLObjectIntersectionOf) { Set allValuesProperties = ((OWLObjectIntersectionOf) description).getOperands() @@ -1014,29 +1014,34 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description) { allValuesProperties.removeAll(someValuesProperties); return allValuesProperties.isEmpty() - && ((OWLObjectIntersectionOf) description).getOperands().stream().allMatch(this::isSomeOnlySatisfied); + && ((OWLObjectIntersectionOf) description).getOperands() + .stream().allMatch(op -> isSomeOnlySatisfied(op, someValuesProperties)); } if (description instanceof OWLObjectUnionOf) { - return ((OWLObjectUnionOf) description).getOperands().stream().allMatch(this::isSomeOnlySatisfied); + return ((OWLObjectUnionOf) description).getOperands() + .stream().allMatch(op -> + (!(op instanceof OWLObjectSomeValuesFrom) || prevSomeValuesProperties.contains(op)) + && isSomeOnlySatisfied(op, Set.of()) + ); } if (description instanceof OWLObjectSomeValuesFrom) { OWLClassExpression filler = ((OWLObjectSomeValuesFrom) description).getFiller(); - return isSomeOnlySatisfied(filler); + return isSomeOnlySatisfied(filler, Set.of()); } if (description instanceof OWLObjectAllValuesFrom) { OWLClassExpression filler = ((OWLObjectAllValuesFrom) description).getFiller(); - return isSomeOnlySatisfied(filler); + return isSomeOnlySatisfied(filler, Set.of()); } if (description instanceof OWLObjectCardinalityRestriction) { OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); - return isSomeOnlySatisfied(filler); + return isSomeOnlySatisfied(filler, Set.of()); } return true; @@ -1193,6 +1198,10 @@ public void setDropDisjuncts(boolean dropDisjuncts) { this.dropDisjuncts = dropDisjuncts; } + public boolean isDropDisjuncts() { + return dropDisjuncts; + } + private void computeTopRefinements(int maxLength) { computeTopRefinements(maxLength, null); } @@ -2002,7 +2011,6 @@ public boolean isUseDataHasValueConstructor() { } public void setUseDataHasValueConstructor(boolean useDataHasValueConstructor) { - isFinal(); this.useDataHasValueConstructor = useDataHasValueConstructor; } @@ -2043,7 +2051,6 @@ public boolean isUseHasValueConstructor() { } public void setUseHasValueConstructor(boolean useHasValueConstructor) { - isFinal(); this.useHasValueConstructor = useHasValueConstructor; } @@ -2052,7 +2059,6 @@ public boolean isUseCardinalityRestrictions() { } public void setUseCardinalityRestrictions(boolean useCardinalityRestrictions) { - isFinal(); this.useCardinalityRestrictions = useCardinalityRestrictions; } @@ -2173,12 +2179,15 @@ public void setUseObjectValueNegation(boolean useObjectValueNegation) { this.useObjectValueNegation = useObjectValueNegation; } + public boolean isUseObjectValueNegation() { + return useObjectValueNegation; + } + public boolean isUseNumericDatatypes() { return useNumericDatatypes; } public void setUseNumericDatatypes(boolean useNumericDatatypes) { - isFinal(); this.useNumericDatatypes = useNumericDatatypes; } @@ -2186,10 +2195,13 @@ public void setUseNumericDatatypes(boolean useNumericDatatypes) { * @param useInverse whether to use inverse properties in property restrictions */ public void setUseInverse(boolean useInverse) { - isFinal(); this.useInverse = useInverse; } + public boolean isUseInverse() { + return useInverse; + } + /** * @param useSomeOnly whether to allow universal restrictions on a property r only if there exists already * a existential restriction on the same property in an intersection @@ -2198,14 +2210,21 @@ public void setUseSomeOnly(boolean useSomeOnly) { this.useSomeOnly = useSomeOnly; } + public boolean isUseSomeOnly() { + return useSomeOnly; + } + /** * @param useTimeDatatypes whether to use data/time literal restrictions */ public void setUseTimeDatatypes(boolean useTimeDatatypes) { - isFinal(); this.useTimeDatatypes = useTimeDatatypes; } + public boolean isUseTimeDatatypes() { + return useTimeDatatypes; + } + public int getMaxNrOfSplits() { return maxNrOfSplits; } diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java new file mode 100644 index 0000000000..16ab66eba1 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -0,0 +1,47 @@ +package org.dllearner.refinementoperators; + +import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; +import org.semanticweb.owlapi.model.*; + +import java.util.*; + +// does not store the reasoner used by the originator +public class RhoDRDownConfigOptionsMemento { + + private final boolean applyAllFilter; + private final boolean applyExistsFilter; + + private final boolean useAllConstructor; + private final boolean useExistsConstructor; + + private final boolean useNegation; + private final boolean useDisjunction; + private final boolean useSomeOnly; + private final boolean useObjectValueNegation; + + public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { + applyAllFilter = originator.isApplyAllFilter(); + applyExistsFilter = originator.isApplyExistsFilter(); + + useAllConstructor = originator.isUseAllConstructor(); + useExistsConstructor = originator.isUseExistsConstructor(); + + useNegation = originator.isUseNegation(); + useDisjunction = originator.isUseDisjunction(); + useSomeOnly = originator.isUseSomeOnly(); + useObjectValueNegation = originator.isUseObjectValueNegation(); + } + + public void restore(RhoDRDown originator) { + originator.setApplyAllFilter(applyAllFilter); + originator.setApplyExistsFilter(applyExistsFilter); + + originator.setUseAllConstructor(useAllConstructor); + originator.setUseExistsConstructor(useExistsConstructor); + + originator.setUseNegation(useNegation); + originator.setUseDisjunction(useDisjunction); + originator.setUseSomeOnly(useSomeOnly); + originator.setUseObjectValueNegation(useObjectValueNegation); + } +} From 91fb6b8d3469188bc2d6fa7a34ea605a11bf10f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 14:47:30 +0100 Subject: [PATCH 16/67] isSomeOnlySatisfied corrected, maxCardinalityLimit option added --- .../refinementoperators/RhoDRDown.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index f2cc743e92..3119d82df7 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -105,6 +105,9 @@ public class RhoDRDown @ConfigOption(defaultValue = "5", description = "limit for cardinality restrictions (this makes sense if we e.g. have compounds with too many atoms)") private int cardinalityLimit = 5; + @ConfigOption(defaultValue = "cardinalityLimit", description = "limit for max cardinality restrictions") + private int maxCardinalityLimit = -1; + // start concept (can be used to start from an arbitrary concept, needs // to be Thing or NamedClass), note that when you use e.g. Compound as // start class, then the algorithm should start the search with class @@ -477,6 +480,10 @@ public void init() throws ComponentInitException { dataPropertyHierarchy = reasoner.getDatatypePropertyHierarchy(); } + if (maxCardinalityLimit < 0) { + maxCardinalityLimit = cardinalityLimit; + } + initialized = true; } @@ -1021,7 +1028,7 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description, Set - (!(op instanceof OWLObjectSomeValuesFrom) || prevSomeValuesProperties.contains(op)) + (!(op instanceof OWLObjectSomeValuesFrom) || prevSomeValuesProperties.contains(((OWLObjectSomeValuesFrom) op).getProperty())) && isSomeOnlySatisfied(op, Set.of()) ); } @@ -1445,7 +1452,7 @@ private void computeM() { int lc = lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength; for(OWLObjectProperty r : objectPropertyHierarchy.getMostGeneralRoles()) { if (isPropertyAllowedInCardinalityRestrictions(r)) { - int maxFillers = maxNrOfFillers.get(r); + int maxFillers = Math.min(maxCardinalityLimit + 1, maxNrOfFillers.get(r)); logger.debug(sparql_debug, "`"+r+"="+maxFillers); // zero fillers: <= -1 r.C does not make sense // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, @@ -1615,7 +1622,7 @@ private void computeM(OWLClassExpression nc) { int lc = lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength; for(OWLObjectProperty r : mgr.get(nc)) { if (isPropertyAllowedInCardinalityRestrictions(r)) { - int maxFillers = maxNrOfFillers.get(r); + int maxFillers = Math.min(maxCardinalityLimit + 1, maxNrOfFillers.get(r)); // zero fillers: <= -1 r.C does not make sense // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, // but we still keep it, because ALL r.NOT C may be difficult to reach @@ -2144,6 +2151,14 @@ public void setCardinalityLimit(int cardinalityLimit) { this.cardinalityLimit = cardinalityLimit; } + public int getMaxCardinalityLimit() { + return maxCardinalityLimit; + } + + public void setMaxCardinalityLimit(int maxCardinalityLimit) { + this.maxCardinalityLimit = maxCardinalityLimit; + } + public ObjectPropertyHierarchy getObjectPropertyHierarchy() { return objectPropertyHierarchy; } From 9b68c2c2759922777980e7d4fa30e082a44e77f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 14:47:30 +0100 Subject: [PATCH 17/67] isSomeOnlySatisfied corrected, maxCardinalityLimit option added --- .../refinementoperators/RhoDRDown.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index e57f7c79b0..2bc19bfa62 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -105,6 +105,9 @@ public class RhoDRDown @ConfigOption(defaultValue = "5", description = "limit for cardinality restrictions (this makes sense if we e.g. have compounds with too many atoms)") private int cardinalityLimit = 5; + @ConfigOption(defaultValue = "cardinalityLimit", description = "limit for max cardinality restrictions") + private int maxCardinalityLimit = -1; + // start concept (can be used to start from an arbitrary concept, needs // to be Thing or NamedClass), note that when you use e.g. Compound as // start class, then the algorithm should start the search with class @@ -477,6 +480,10 @@ public void init() throws ComponentInitException { dataPropertyHierarchy = reasoner.getDatatypePropertyHierarchy(); } + if (maxCardinalityLimit < 0) { + maxCardinalityLimit = cardinalityLimit; + } + initialized = true; } @@ -1021,7 +1028,7 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description, Set - (!(op instanceof OWLObjectSomeValuesFrom) || prevSomeValuesProperties.contains(op)) + (!(op instanceof OWLObjectSomeValuesFrom) || prevSomeValuesProperties.contains(((OWLObjectSomeValuesFrom) op).getProperty())) && isSomeOnlySatisfied(op, Set.of()) ); } @@ -1445,7 +1452,7 @@ private void computeM() { int lc = lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength; for(OWLObjectProperty r : objectPropertyHierarchy.getMostGeneralRoles()) { if (isPropertyAllowedInCardinalityRestrictions(r)) { - int maxFillers = maxNrOfFillers.get(r); + int maxFillers = Math.min(maxCardinalityLimit + 1, maxNrOfFillers.get(r)); logger.debug(sparql_debug, "`"+r+"="+maxFillers); // zero fillers: <= -1 r.C does not make sense // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, @@ -1615,7 +1622,7 @@ private void computeM(OWLClassExpression nc) { int lc = lengthMetric.objectCardinalityLength + lengthMetric.objectProperyLength + lengthMetric.classLength; for(OWLObjectProperty r : mgr.get(nc)) { if (isPropertyAllowedInCardinalityRestrictions(r)) { - int maxFillers = maxNrOfFillers.get(r); + int maxFillers = Math.min(maxCardinalityLimit + 1, maxNrOfFillers.get(r)); // zero fillers: <= -1 r.C does not make sense // one filler: <= 0 r.C is equivalent to NOT EXISTS r.C, // but we still keep it, because ALL r.NOT C may be difficult to reach @@ -2144,6 +2151,14 @@ public void setCardinalityLimit(int cardinalityLimit) { this.cardinalityLimit = cardinalityLimit; } + public int getMaxCardinalityLimit() { + return maxCardinalityLimit; + } + + public void setMaxCardinalityLimit(int maxCardinalityLimit) { + this.maxCardinalityLimit = maxCardinalityLimit; + } + public ObjectPropertyHierarchy getObjectPropertyHierarchy() { return objectPropertyHierarchy; } From 9a80253a2c3c38173306bcf93f38248929a580a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Fri, 3 Mar 2023 16:41:05 +0100 Subject: [PATCH 18/67] concurrent cwr added --- .../reasoning/ClosedWorldReasoner.java | 2 +- .../ConcurrentClosedWorldReasoner.java | 227 ++++++++++++++++++ .../dllearner/reasoning/OWLAPIReasoner.java | 13 + .../dllearner/reasoning/ReasonerFactory.java | 32 +++ .../org/dllearner/reasoning/ReasonerPool.java | 12 + 5 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 components-core/src/main/java/org/dllearner/reasoning/ConcurrentClosedWorldReasoner.java create mode 100644 components-core/src/main/java/org/dllearner/reasoning/ReasonerFactory.java create mode 100644 components-core/src/main/java/org/dllearner/reasoning/ReasonerPool.java diff --git a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java index 300f57ce98..1909085e01 100644 --- a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java +++ b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java @@ -73,7 +73,7 @@ public class ClosedWorldReasoner extends AbstractReasonerComponent { private static Logger logger = LoggerFactory.getLogger(ClosedWorldReasoner.class); // the underlying base reasoner implementation - private OWLAPIReasoner baseReasoner; + protected OWLAPIReasoner baseReasoner; @ConfigOption(description = "the underlying reasoner implementation", defaultValue = "OWL API Reasoner") private final OWLAPIReasoner reasonerComponent = null; /** diff --git a/components-core/src/main/java/org/dllearner/reasoning/ConcurrentClosedWorldReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/ConcurrentClosedWorldReasoner.java new file mode 100644 index 0000000000..778d554c6f --- /dev/null +++ b/components-core/src/main/java/org/dllearner/reasoning/ConcurrentClosedWorldReasoner.java @@ -0,0 +1,227 @@ +package org.dllearner.reasoning; + +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentInitException; +import org.dllearner.core.config.ConfigOption; +import org.semanticweb.owlapi.model.*; + +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.function.Function; + +@ComponentAnn(name = "concurrent closed world reasoner", shortName = "ccwr", version = 0.1) +public class ConcurrentClosedWorldReasoner extends ClosedWorldReasoner { + + @ConfigOption(description = "maximum number of concurrently working base reasoners", defaultValue = "4") + private int maxNrOfBaseReasoners = 4; + + private ReasonerPool reasonerPool; + + @Override + public void init() throws ComponentInitException { + super.init(); + + createReasonerPool(); + } + + private void createReasonerPool() { + reasonerPool = new ReasonerPool(baseReasoner, maxNrOfBaseReasoners); + } + + private AbstractReasonerComponent borrowReasoner() { + try { + return reasonerPool.borrowObject(); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + private void returnReasoner(AbstractReasonerComponent reasoner) { + try { + reasonerPool.returnObject(reasoner); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private T queryReasoner(Function query) { + AbstractReasonerComponent reasoner = borrowReasoner(); + T result = query.apply(reasoner); + returnReasoner(reasoner); + + return result; + } + + public int getMaxNrOfBaseReasoners() { + return maxNrOfBaseReasoners; + } + + public void setMaxNrOfBaseReasoners(int maxNrOfBaseReasoners) { + this.maxNrOfBaseReasoners = maxNrOfBaseReasoners; + } + + @Override + public Set getClasses() { + return queryReasoner(r -> r.getClasses()); + } + + @Override + public Set getDatatypePropertiesImpl() { + return queryReasoner(r -> r.getDatatypeProperties()); + } + + @Override + public Set getBooleanDatatypePropertiesImpl() { + return queryReasoner(r -> r.getBooleanDatatypeProperties()); + } + + @Override + public Set getDoubleDatatypePropertiesImpl() { + return queryReasoner(r -> r.getDoubleDatatypeProperties()); + } + + @Override + public Set getIntDatatypePropertiesImpl() { + return queryReasoner(r -> r.getIntDatatypeProperties()); + } + + @Override + public Set getStringDatatypePropertiesImpl() { + return queryReasoner(r -> r.getStringDatatypeProperties()); + } + + @Override + protected SortedSet getSuperClassesImpl(OWLClassExpression concept) { + return queryReasoner(r -> r.getSuperClasses(concept)); + } + + @Override + protected SortedSet getSubClassesImpl(OWLClassExpression concept) { + return queryReasoner(r -> r.getSubClasses(concept)); + } + + @Override + protected SortedSet getSuperPropertiesImpl(OWLObjectProperty role) { + return queryReasoner(r -> r.getSuperProperties(role)); + } + + @Override + protected SortedSet getSubPropertiesImpl(OWLObjectProperty role) { + return queryReasoner(r -> r.getSubProperties(role)); + } + + @Override + protected SortedSet getSuperPropertiesImpl(OWLDataProperty role) { + return queryReasoner(r -> r.getSuperProperties(role)); + } + + @Override + protected SortedSet getSubPropertiesImpl(OWLDataProperty role) { + return queryReasoner(r -> r.getSubProperties(role)); + } + + @Override + public boolean isSuperClassOfImpl(OWLClassExpression superConcept, OWLClassExpression subConcept) { + return queryReasoner(r -> r.isSuperClassOf(superConcept, subConcept)); + } + + @Override + public boolean isDisjointImpl(OWLClass clsA, OWLClass clsB) { + if (getDisjointnessSemantics() == DisjointnessSemantics.Explicit) { + return queryReasoner(r -> r.isDisjoint(clsA, clsB)); + } + + return super.isDisjointImpl(clsA, clsB); + } + + @Override + public void setBaseURI(String baseURI) {} + + @Override + public void setPrefixes(Map prefixes) {} + + @Override + public OWLClassExpression getDomainImpl(OWLObjectProperty objectProperty) { + return queryReasoner(r -> r.getDomain(objectProperty)); + } + + @Override + public OWLClassExpression getDomainImpl(OWLDataProperty datatypeProperty) { + return queryReasoner(r -> r.getDomain(datatypeProperty)); + } + + @Override + public OWLClassExpression getRangeImpl(OWLObjectProperty objectProperty) { + return queryReasoner(r -> r.getRange(objectProperty)); + } + + @Override + public OWLDataRange getRangeImpl(OWLDataProperty datatypeProperty) { + return queryReasoner(r -> r.getRange(datatypeProperty)); + } + + @Override + protected Map> getDataPropertyRelationshipsImpl(OWLIndividual individual) { + return queryReasoner(r -> r.getDataPropertyRelationships(individual)); + } + + @Override + public Set getRelatedIndividualsImpl(OWLIndividual individual, OWLObjectProperty objectProperty) { + return queryReasoner(r -> r.getRelatedIndividuals(individual, objectProperty)); + } + + @Override + protected Map> getObjectPropertyRelationshipsImpl(OWLIndividual individual) { + return queryReasoner(r -> r.getObjectPropertyRelationships(individual)); + } + + @Override + public Set getRelatedValuesImpl(OWLIndividual individual, OWLDataProperty datatypeProperty) { + return queryReasoner(r -> r.getRelatedValues(individual, datatypeProperty)); + } + + @Override + public boolean isSatisfiableImpl() { + return queryReasoner(r -> r.isSatisfiable()); + } + + @Override + public Set getLabelImpl(OWLEntity entity) { + return queryReasoner(r -> r.getLabel(entity)); + } + + @Override + public void releaseKB() {} + + @Override + protected Set getTypesImpl(OWLIndividual individual) { + return queryReasoner(r -> r.getTypes(individual)); + } + + @Override + public boolean remainsSatisfiableImpl(OWLAxiom axiom) { + return queryReasoner(r -> r.remainsSatisfiable(axiom)); + } + + @Override + protected Set getAssertedDefinitionsImpl(OWLClass nc) { + return queryReasoner(r -> r.getAssertedDefinitions(nc)); + } + + @Override + protected Set getInconsistentClassesImpl() { + return queryReasoner(r -> r.getInconsistentClasses()); + } + + @Override + public OWLDatatype getDatatype(OWLDataProperty dp) { + return queryReasoner(r -> r.getDatatype(dp)); + } + + @Override + public void setSynchronized() {} +} diff --git a/components-core/src/main/java/org/dllearner/reasoning/OWLAPIReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/OWLAPIReasoner.java index edef21ca7a..da7c02b92f 100644 --- a/components-core/src/main/java/org/dllearner/reasoning/OWLAPIReasoner.java +++ b/components-core/src/main/java/org/dllearner/reasoning/OWLAPIReasoner.java @@ -124,6 +124,14 @@ public OWLAPIReasoner(OWLReasoner reasoner) { sources = Collections.singleton(ks); } + public OWLAPIReasoner(OWLAPIReasoner reasoner) { + super(reasoner); + + setReasonerImplementation(reasoner.reasonerImplementation); + setUseFallbackReasoner(reasoner.useFallbackReasoner); + setOwlLinkURL(reasoner.owlLinkURL); + } + @Override public void init() throws ComponentInitException { // reset variables (otherwise subsequent initialisation with @@ -1263,6 +1271,11 @@ public void setSynchronized() { } } + @Override + public AbstractReasonerComponent clone() { + return new OWLAPIReasoner(this); + } + public static void main(String[] args) throws Exception{ OWLOntology o = OWLManager.createOWLOntologyManager().loadOntologyFromOntologyDocument(new File(System.getProperty("java.io.tmpdir") + File.separator + "test2.rdf")); System.out.println(o.getClassesInSignature()); diff --git a/components-core/src/main/java/org/dllearner/reasoning/ReasonerFactory.java b/components-core/src/main/java/org/dllearner/reasoning/ReasonerFactory.java new file mode 100644 index 0000000000..a5836c9caa --- /dev/null +++ b/components-core/src/main/java/org/dllearner/reasoning/ReasonerFactory.java @@ -0,0 +1,32 @@ +package org.dllearner.reasoning; + +import org.apache.commons.pool2.BasePooledObjectFactory; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.impl.DefaultPooledObject; +import org.dllearner.core.AbstractReasonerComponent; + +public class ReasonerFactory extends BasePooledObjectFactory { + + private final AbstractReasonerComponent reasonerPrototype; + + public ReasonerFactory(AbstractReasonerComponent reasonerPrototype) { + this.reasonerPrototype = reasonerPrototype.clone(); + } + + @Override + public AbstractReasonerComponent create() throws Exception { + if (!reasonerPrototype.isInitialized()) { + reasonerPrototype.init(); + } + + AbstractReasonerComponent reasoner = reasonerPrototype.clone(); + reasoner.init(); + + return reasoner; + } + + @Override + public PooledObject wrap(AbstractReasonerComponent reasonerComponent) { + return new DefaultPooledObject<>(reasonerComponent); + } +} diff --git a/components-core/src/main/java/org/dllearner/reasoning/ReasonerPool.java b/components-core/src/main/java/org/dllearner/reasoning/ReasonerPool.java new file mode 100644 index 0000000000..23902de1b1 --- /dev/null +++ b/components-core/src/main/java/org/dllearner/reasoning/ReasonerPool.java @@ -0,0 +1,12 @@ +package org.dllearner.reasoning; + +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.dllearner.core.AbstractReasonerComponent; + +public class ReasonerPool extends GenericObjectPool { + + public ReasonerPool(AbstractReasonerComponent reasonerPrototype, int maxIdle) { + super(new ReasonerFactory(reasonerPrototype)); + setMaxIdle(maxIdle); + } +} From c2affc8774d520782ffd89869bad29120d79c243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 15:58:54 +0100 Subject: [PATCH 19/67] reversing the order of elements in search tree --- .../org/dllearner/algorithms/parcel/ParCELAbstract.java | 7 +++---- .../org/dllearner/algorithms/parcel/ParCELearner.java | 9 +++------ .../dllearner/algorithms/parcelex/ParCELearnerExV12.java | 4 ++-- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 4b03447181..1836ebd934 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -342,10 +342,9 @@ public void newPartialDefinitionsFound(Set definitions) { + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); } else if (logger.isInfoEnabled()) { - logger.info("PARTIAL definition found: " - + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) - + ", uncovered positive examples left: " - + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + logger.info("PARTIAL definition found. Uncovered positive examples left: " + + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + + "\n" + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription())); double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index 0f06a40ba0..86dcb89073 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -26,10 +26,7 @@ import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.management.ManagementFactory; -import java.util.HashSet; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; +import java.util.*; import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.RejectedExecutionException; import java.util.stream.Collectors; @@ -153,7 +150,7 @@ protected void reset() { //allDescriptions = new TreeSet(new ConceptComparator()); allDescriptions = new ConcurrentSkipListSet<>(); - searchTree = new ConcurrentSkipListSet<>(heuristic); + searchTree = new ConcurrentSkipListSet<>(heuristic.reversed()); partialDefinitions = new TreeSet<>(new ParCELCorrectnessComparator()); @@ -197,7 +194,7 @@ public void start() { // ---------------------------------------------------------- while (!isTerminateCriteriaSatisfied()) { - ParCELNode nodeToProcess = searchTree.pollLast(); + ParCELNode nodeToProcess = searchTree.pollFirst(); // TODO: why this? why "blocking" concept does not help in this case? // remove this checking will exploit the heap memory and no definition found diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index b748d44846..e1f7acdb05 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -235,7 +235,7 @@ public void start() { ParCELNode nodeToProcess; - nodeToProcess = searchTree.pollLast(); + nodeToProcess = searchTree.pollFirst(); //TODO: why this? why "blocking" concept does not help in this case? //remove this checking will exploit the heap memory and no definition found @@ -678,7 +678,7 @@ public void newRefinementDescriptions(Set newNodes) { * 3. Create an empty */ private void reset() { - this.searchTree = new ConcurrentSkipListSet<>(heuristic); + this.searchTree = new ConcurrentSkipListSet<>(heuristic.reversed()); //allDescriptions = new TreeSet(new ConceptComparator()); this.allDescriptions = new ConcurrentSkipListSet<>(); From a04d5fd15d6e6254fbc7a9ab94d39b00f1dbacdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 16:00:29 +0100 Subject: [PATCH 20/67] partial-definition-found message reformatted --- .../org/dllearner/algorithms/parcel/ParCELAbstract.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 4b03447181..1836ebd934 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -342,10 +342,9 @@ public void newPartialDefinitionsFound(Set definitions) { + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); } else if (logger.isInfoEnabled()) { - logger.info("PARTIAL definition found: " - + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) - + ", uncovered positive examples left: " - + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + logger.info("PARTIAL definition found. Uncovered positive examples left: " + + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + + "\n" + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription())); double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; From fc81d153e4be45e8f6894d640225de8f90040662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 16:00:29 +0100 Subject: [PATCH 21/67] partial-definition-found message reformatted --- .../org/dllearner/algorithms/parcel/ParCELAbstract.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 4b03447181..1836ebd934 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -342,10 +342,9 @@ public void newPartialDefinitionsFound(Set definitions) { + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); } else if (logger.isInfoEnabled()) { - logger.info("PARTIAL definition found: " - + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) - + ", uncovered positive examples left: " - + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + logger.info("PARTIAL definition found. Uncovered positive examples left: " + + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + + "\n" + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription())); double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; From 9d0e428c1ad44b17b94dd4ae869cd4686aedeb74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 16:00:29 +0100 Subject: [PATCH 22/67] partial-definition-found message reformatted --- .../org/dllearner/algorithms/parcel/ParCELAbstract.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index cea6e325be..ec29d77019 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -345,10 +345,9 @@ public void newPartialDefinitionsFound(Set definitions) { + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); } else if (logger.isInfoEnabled()) { - logger.info("PARTIAL definition found: " - + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) - + ", uncovered positive examples left: " - + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + logger.info("PARTIAL definition found. Uncovered positive examples left: " + + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + + "\n" + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription())); double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; From 461462245764b1f4223196fb49a1338cb564302c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 17:49:49 +0100 Subject: [PATCH 23/67] maxCardinalityLimit in upward refinements, splits for numeric datatype properties corrected --- .../org/dllearner/algorithms/ocel/OCEL.java | 1 - .../refinementoperators/RhoDRDown.java | 30 +++++++++++-------- .../RhoDRDownConfigOptionsMemento.java | 6 ++++ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index 920567fa80..fd1c40cbda 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -315,7 +315,6 @@ public void init() throws ComponentInitException { throw new RuntimeException("does not work with positive examples only yet"); } else { heuristic = new MultiHeuristic(((PosNegLP) getLearningProblem()).getPositiveExamples().size(), ((PosNegLP) getLearningProblem()).getNegativeExamples().size(), negativeWeight, startNodeBonus, expansionPenaltyFactor, negationPenalty); - ((MultiHeuristic) heuristic).setLengthMetric(lengthMetric); } } else { // we need to set some variables to make the heuristic work diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 3119d82df7..02c159a4dc 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -106,7 +106,7 @@ public class RhoDRDown private int cardinalityLimit = 5; @ConfigOption(defaultValue = "cardinalityLimit", description = "limit for max cardinality restrictions") - private int maxCardinalityLimit = -1; + private int maxCardinalityLimit = cardinalityLimit; // start concept (can be used to start from an arbitrary concept, needs // to be Thing or NamedClass), note that when you use e.g. Compound as @@ -158,7 +158,7 @@ public class RhoDRDown private ValuesSplitter numericValuesSplitter; // splits for double datatype properties in ascending order - private Map> splits = new TreeMap<>(); + private Map> splits; @ConfigOption(description = "the number of generated split intervals for numeric types", defaultValue = "12") private int maxNrOfSplits = 12; @@ -393,6 +393,7 @@ public void init() throws ComponentInitException { if (numericValuesSplitter == null) { numericValuesSplitter = new DefaultNumericValuesSplitter(reasoner, df, maxNrOfSplits); } + splits = new TreeMap<>(); splits.putAll(numericValuesSplitter.computeSplits()); if (logger.isDebugEnabled()) { logger.debug(sparql_debug, "Numeric Splits: {}", splits); @@ -480,7 +481,7 @@ public void init() throws ComponentInitException { dataPropertyHierarchy = reasoner.getDatatypePropertyHierarchy(); } - if (maxCardinalityLimit < 0) { + if (maxCardinalityLimit < 0 || maxCardinalityLimit > cardinalityLimit) { maxCardinalityLimit = cardinalityLimit; } @@ -595,9 +596,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = ConceptTransformation.nnf(mc); // check whether the intersection is OK (sanity checks), then add it - if(checkIntersection((OWLObjectIntersectionOf) mc) -// && checkRefinability((OWLNaryBooleanClassExpression) mc) - ) + if(checkIntersection((OWLObjectIntersectionOf) mc)) refinements.add(mc); } } @@ -628,9 +627,7 @@ public Set refine(OWLClassExpression description, int maxLen // note that we do not have to call clean here because a disjunction will // never be nested in another disjunction in this operator -// if (checkRefinability((OWLNaryBooleanClassExpression) md)) { refinements.add(md); -// } } } @@ -896,9 +893,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if (checkIntersection(mc) -// && checkRefinability(mc) - ) + if (checkIntersection(mc)) refinements.add(mc); } } @@ -935,6 +930,8 @@ private Set refineUpwards( applyAllFilter = applyExistsFilter; applyExistsFilter = optionTmp; + maxCardinalityLimit = cardinalityLimit; + TreeSet results = new TreeSet<>(); try { @@ -953,11 +950,13 @@ private Set refineUpwards( OWLClassExpression dNeg = constructNegationInNNF(d); dNeg = ConceptTransformation.cleanConcept(dNeg); - // TODO: dropDisjuncts not supported + // TODO: MY dropDisjuncts not supported + // TODO: MY some values from and has value for datatype properties not supported // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check if(description.compareTo(dNeg) != 0 + && (maxCardinalityLimit == cardinalityLimit || isMaxCardinalityLimitSatisfied(dNeg)) && (useDisjunction || !containsDisjunction(dNeg)) && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) @@ -985,6 +984,13 @@ private OWLClassExpression constructNegationInNNF(OWLClassExpression description return negatedDescription; } + private boolean isMaxCardinalityLimitSatisfied(OWLClassExpression description) { + return decomposer.decompose(description) + .stream().allMatch(e -> + !(e instanceof OWLObjectMaxCardinality) || ((OWLObjectMaxCardinality) e).getCardinality() <= maxCardinalityLimit + ); + } + private boolean containsDisjunction(OWLClassExpression description) { return decomposer.decompose(description) .stream().anyMatch(e -> e instanceof OWLObjectUnionOf); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index 16ab66eba1..ff81e958ed 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -19,6 +19,8 @@ public class RhoDRDownConfigOptionsMemento { private final boolean useSomeOnly; private final boolean useObjectValueNegation; + private final int maxCardinalityLimit; + public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { applyAllFilter = originator.isApplyAllFilter(); applyExistsFilter = originator.isApplyExistsFilter(); @@ -30,6 +32,8 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); useObjectValueNegation = originator.isUseObjectValueNegation(); + + maxCardinalityLimit = originator.getMaxCardinalityLimit(); } public void restore(RhoDRDown originator) { @@ -43,5 +47,7 @@ public void restore(RhoDRDown originator) { originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); originator.setUseObjectValueNegation(useObjectValueNegation); + + originator.setMaxCardinalityLimit(maxCardinalityLimit); } } From 4cde5feb0176752923247453d568275b534fedb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 17:49:49 +0100 Subject: [PATCH 24/67] maxCardinalityLimit in upward refinements, splits for numeric datatype properties corrected --- .../org/dllearner/algorithms/ocel/OCEL.java | 1 - .../refinementoperators/RhoDRDown.java | 30 +++++++++++-------- .../RhoDRDownConfigOptionsMemento.java | 6 ++++ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index 920567fa80..fd1c40cbda 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -315,7 +315,6 @@ public void init() throws ComponentInitException { throw new RuntimeException("does not work with positive examples only yet"); } else { heuristic = new MultiHeuristic(((PosNegLP) getLearningProblem()).getPositiveExamples().size(), ((PosNegLP) getLearningProblem()).getNegativeExamples().size(), negativeWeight, startNodeBonus, expansionPenaltyFactor, negationPenalty); - ((MultiHeuristic) heuristic).setLengthMetric(lengthMetric); } } else { // we need to set some variables to make the heuristic work diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 3119d82df7..02c159a4dc 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -106,7 +106,7 @@ public class RhoDRDown private int cardinalityLimit = 5; @ConfigOption(defaultValue = "cardinalityLimit", description = "limit for max cardinality restrictions") - private int maxCardinalityLimit = -1; + private int maxCardinalityLimit = cardinalityLimit; // start concept (can be used to start from an arbitrary concept, needs // to be Thing or NamedClass), note that when you use e.g. Compound as @@ -158,7 +158,7 @@ public class RhoDRDown private ValuesSplitter numericValuesSplitter; // splits for double datatype properties in ascending order - private Map> splits = new TreeMap<>(); + private Map> splits; @ConfigOption(description = "the number of generated split intervals for numeric types", defaultValue = "12") private int maxNrOfSplits = 12; @@ -393,6 +393,7 @@ public void init() throws ComponentInitException { if (numericValuesSplitter == null) { numericValuesSplitter = new DefaultNumericValuesSplitter(reasoner, df, maxNrOfSplits); } + splits = new TreeMap<>(); splits.putAll(numericValuesSplitter.computeSplits()); if (logger.isDebugEnabled()) { logger.debug(sparql_debug, "Numeric Splits: {}", splits); @@ -480,7 +481,7 @@ public void init() throws ComponentInitException { dataPropertyHierarchy = reasoner.getDatatypePropertyHierarchy(); } - if (maxCardinalityLimit < 0) { + if (maxCardinalityLimit < 0 || maxCardinalityLimit > cardinalityLimit) { maxCardinalityLimit = cardinalityLimit; } @@ -595,9 +596,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = ConceptTransformation.nnf(mc); // check whether the intersection is OK (sanity checks), then add it - if(checkIntersection((OWLObjectIntersectionOf) mc) -// && checkRefinability((OWLNaryBooleanClassExpression) mc) - ) + if(checkIntersection((OWLObjectIntersectionOf) mc)) refinements.add(mc); } } @@ -628,9 +627,7 @@ public Set refine(OWLClassExpression description, int maxLen // note that we do not have to call clean here because a disjunction will // never be nested in another disjunction in this operator -// if (checkRefinability((OWLNaryBooleanClassExpression) md)) { refinements.add(md); -// } } } @@ -896,9 +893,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if (checkIntersection(mc) -// && checkRefinability(mc) - ) + if (checkIntersection(mc)) refinements.add(mc); } } @@ -935,6 +930,8 @@ private Set refineUpwards( applyAllFilter = applyExistsFilter; applyExistsFilter = optionTmp; + maxCardinalityLimit = cardinalityLimit; + TreeSet results = new TreeSet<>(); try { @@ -953,11 +950,13 @@ private Set refineUpwards( OWLClassExpression dNeg = constructNegationInNNF(d); dNeg = ConceptTransformation.cleanConcept(dNeg); - // TODO: dropDisjuncts not supported + // TODO: MY dropDisjuncts not supported + // TODO: MY some values from and has value for datatype properties not supported // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check if(description.compareTo(dNeg) != 0 + && (maxCardinalityLimit == cardinalityLimit || isMaxCardinalityLimitSatisfied(dNeg)) && (useDisjunction || !containsDisjunction(dNeg)) && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) @@ -985,6 +984,13 @@ private OWLClassExpression constructNegationInNNF(OWLClassExpression description return negatedDescription; } + private boolean isMaxCardinalityLimitSatisfied(OWLClassExpression description) { + return decomposer.decompose(description) + .stream().allMatch(e -> + !(e instanceof OWLObjectMaxCardinality) || ((OWLObjectMaxCardinality) e).getCardinality() <= maxCardinalityLimit + ); + } + private boolean containsDisjunction(OWLClassExpression description) { return decomposer.decompose(description) .stream().anyMatch(e -> e instanceof OWLObjectUnionOf); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index 16ab66eba1..ff81e958ed 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -19,6 +19,8 @@ public class RhoDRDownConfigOptionsMemento { private final boolean useSomeOnly; private final boolean useObjectValueNegation; + private final int maxCardinalityLimit; + public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { applyAllFilter = originator.isApplyAllFilter(); applyExistsFilter = originator.isApplyExistsFilter(); @@ -30,6 +32,8 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); useObjectValueNegation = originator.isUseObjectValueNegation(); + + maxCardinalityLimit = originator.getMaxCardinalityLimit(); } public void restore(RhoDRDown originator) { @@ -43,5 +47,7 @@ public void restore(RhoDRDown originator) { originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); originator.setUseObjectValueNegation(useObjectValueNegation); + + originator.setMaxCardinalityLimit(maxCardinalityLimit); } } From 993abac9d63eae5ebd5861c90402b4a9641afd13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 17:49:49 +0100 Subject: [PATCH 25/67] maxCardinalityLimit in upward refinements, splits for numeric datatype properties corrected --- .../org/dllearner/algorithms/ocel/OCEL.java | 1 - .../refinementoperators/RhoDRDown.java | 30 +++++++++++-------- .../RhoDRDownConfigOptionsMemento.java | 6 ++++ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index 920567fa80..fd1c40cbda 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -315,7 +315,6 @@ public void init() throws ComponentInitException { throw new RuntimeException("does not work with positive examples only yet"); } else { heuristic = new MultiHeuristic(((PosNegLP) getLearningProblem()).getPositiveExamples().size(), ((PosNegLP) getLearningProblem()).getNegativeExamples().size(), negativeWeight, startNodeBonus, expansionPenaltyFactor, negationPenalty); - ((MultiHeuristic) heuristic).setLengthMetric(lengthMetric); } } else { // we need to set some variables to make the heuristic work diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 2bc19bfa62..83e4b84f1e 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -106,7 +106,7 @@ public class RhoDRDown private int cardinalityLimit = 5; @ConfigOption(defaultValue = "cardinalityLimit", description = "limit for max cardinality restrictions") - private int maxCardinalityLimit = -1; + private int maxCardinalityLimit = cardinalityLimit; // start concept (can be used to start from an arbitrary concept, needs // to be Thing or NamedClass), note that when you use e.g. Compound as @@ -158,7 +158,7 @@ public class RhoDRDown private ValuesSplitter numericValuesSplitter; // splits for double datatype properties in ascending order - private Map> splits = new TreeMap<>(); + private Map> splits; @ConfigOption(description = "the number of generated split intervals for numeric types", defaultValue = "12") private int maxNrOfSplits = 12; @@ -393,6 +393,7 @@ public void init() throws ComponentInitException { if (numericValuesSplitter == null) { numericValuesSplitter = new DefaultNumericValuesSplitter(reasoner, df, maxNrOfSplits); } + splits = new TreeMap<>(); splits.putAll(numericValuesSplitter.computeSplits()); if (logger.isDebugEnabled()) { logger.debug(sparql_debug, "Numeric Splits: {}", splits); @@ -480,7 +481,7 @@ public void init() throws ComponentInitException { dataPropertyHierarchy = reasoner.getDatatypePropertyHierarchy(); } - if (maxCardinalityLimit < 0) { + if (maxCardinalityLimit < 0 || maxCardinalityLimit > cardinalityLimit) { maxCardinalityLimit = cardinalityLimit; } @@ -595,9 +596,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = ConceptTransformation.nnf(mc); // check whether the intersection is OK (sanity checks), then add it - if(checkIntersection((OWLObjectIntersectionOf) mc) -// && checkRefinability((OWLNaryBooleanClassExpression) mc) - ) + if(checkIntersection((OWLObjectIntersectionOf) mc)) refinements.add(mc); } } @@ -628,9 +627,7 @@ public Set refine(OWLClassExpression description, int maxLen // note that we do not have to call clean here because a disjunction will // never be nested in another disjunction in this operator -// if (checkRefinability((OWLNaryBooleanClassExpression) md)) { refinements.add(md); -// } } } @@ -896,9 +893,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if (checkIntersection(mc) -// && checkRefinability(mc) - ) + if (checkIntersection(mc)) refinements.add(mc); } } @@ -935,6 +930,8 @@ private Set refineUpwards( applyAllFilter = applyExistsFilter; applyExistsFilter = optionTmp; + maxCardinalityLimit = cardinalityLimit; + TreeSet results = new TreeSet<>(); try { @@ -953,11 +950,13 @@ private Set refineUpwards( OWLClassExpression dNeg = constructNegationInNNF(d); dNeg = ConceptTransformation.cleanConcept(dNeg); - // TODO: dropDisjuncts not supported + // TODO: MY dropDisjuncts not supported + // TODO: MY some values from and has value for datatype properties not supported // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check if(description.compareTo(dNeg) != 0 + && (maxCardinalityLimit == cardinalityLimit || isMaxCardinalityLimitSatisfied(dNeg)) && (useDisjunction || !containsDisjunction(dNeg)) && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) @@ -985,6 +984,13 @@ private OWLClassExpression constructNegationInNNF(OWLClassExpression description return negatedDescription; } + private boolean isMaxCardinalityLimitSatisfied(OWLClassExpression description) { + return decomposer.decompose(description) + .stream().allMatch(e -> + !(e instanceof OWLObjectMaxCardinality) || ((OWLObjectMaxCardinality) e).getCardinality() <= maxCardinalityLimit + ); + } + private boolean containsDisjunction(OWLClassExpression description) { return decomposer.decompose(description) .stream().anyMatch(e -> e instanceof OWLObjectUnionOf); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index 16ab66eba1..ff81e958ed 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -19,6 +19,8 @@ public class RhoDRDownConfigOptionsMemento { private final boolean useSomeOnly; private final boolean useObjectValueNegation; + private final int maxCardinalityLimit; + public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { applyAllFilter = originator.isApplyAllFilter(); applyExistsFilter = originator.isApplyExistsFilter(); @@ -30,6 +32,8 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); useObjectValueNegation = originator.isUseObjectValueNegation(); + + maxCardinalityLimit = originator.getMaxCardinalityLimit(); } public void restore(RhoDRDown originator) { @@ -43,5 +47,7 @@ public void restore(RhoDRDown originator) { originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); originator.setUseObjectValueNegation(useObjectValueNegation); + + originator.setMaxCardinalityLimit(maxCardinalityLimit); } } From 362571d0f66f2a8032e1adba8473a084cae00c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 17:49:49 +0100 Subject: [PATCH 26/67] maxCardinalityLimit in upward refinements, splits for numeric datatype properties corrected --- .../org/dllearner/algorithms/ocel/OCEL.java | 1 - .../refinementoperators/RhoDRDown.java | 30 +++++++++++-------- .../RhoDRDownConfigOptionsMemento.java | 6 ++++ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index 920567fa80..fd1c40cbda 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -315,7 +315,6 @@ public void init() throws ComponentInitException { throw new RuntimeException("does not work with positive examples only yet"); } else { heuristic = new MultiHeuristic(((PosNegLP) getLearningProblem()).getPositiveExamples().size(), ((PosNegLP) getLearningProblem()).getNegativeExamples().size(), negativeWeight, startNodeBonus, expansionPenaltyFactor, negationPenalty); - ((MultiHeuristic) heuristic).setLengthMetric(lengthMetric); } } else { // we need to set some variables to make the heuristic work diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 3119d82df7..02c159a4dc 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -106,7 +106,7 @@ public class RhoDRDown private int cardinalityLimit = 5; @ConfigOption(defaultValue = "cardinalityLimit", description = "limit for max cardinality restrictions") - private int maxCardinalityLimit = -1; + private int maxCardinalityLimit = cardinalityLimit; // start concept (can be used to start from an arbitrary concept, needs // to be Thing or NamedClass), note that when you use e.g. Compound as @@ -158,7 +158,7 @@ public class RhoDRDown private ValuesSplitter numericValuesSplitter; // splits for double datatype properties in ascending order - private Map> splits = new TreeMap<>(); + private Map> splits; @ConfigOption(description = "the number of generated split intervals for numeric types", defaultValue = "12") private int maxNrOfSplits = 12; @@ -393,6 +393,7 @@ public void init() throws ComponentInitException { if (numericValuesSplitter == null) { numericValuesSplitter = new DefaultNumericValuesSplitter(reasoner, df, maxNrOfSplits); } + splits = new TreeMap<>(); splits.putAll(numericValuesSplitter.computeSplits()); if (logger.isDebugEnabled()) { logger.debug(sparql_debug, "Numeric Splits: {}", splits); @@ -480,7 +481,7 @@ public void init() throws ComponentInitException { dataPropertyHierarchy = reasoner.getDatatypePropertyHierarchy(); } - if (maxCardinalityLimit < 0) { + if (maxCardinalityLimit < 0 || maxCardinalityLimit > cardinalityLimit) { maxCardinalityLimit = cardinalityLimit; } @@ -595,9 +596,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = ConceptTransformation.nnf(mc); // check whether the intersection is OK (sanity checks), then add it - if(checkIntersection((OWLObjectIntersectionOf) mc) -// && checkRefinability((OWLNaryBooleanClassExpression) mc) - ) + if(checkIntersection((OWLObjectIntersectionOf) mc)) refinements.add(mc); } } @@ -628,9 +627,7 @@ public Set refine(OWLClassExpression description, int maxLen // note that we do not have to call clean here because a disjunction will // never be nested in another disjunction in this operator -// if (checkRefinability((OWLNaryBooleanClassExpression) md)) { refinements.add(md); -// } } } @@ -896,9 +893,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if (checkIntersection(mc) -// && checkRefinability(mc) - ) + if (checkIntersection(mc)) refinements.add(mc); } } @@ -935,6 +930,8 @@ private Set refineUpwards( applyAllFilter = applyExistsFilter; applyExistsFilter = optionTmp; + maxCardinalityLimit = cardinalityLimit; + TreeSet results = new TreeSet<>(); try { @@ -953,11 +950,13 @@ private Set refineUpwards( OWLClassExpression dNeg = constructNegationInNNF(d); dNeg = ConceptTransformation.cleanConcept(dNeg); - // TODO: dropDisjuncts not supported + // TODO: MY dropDisjuncts not supported + // TODO: MY some values from and has value for datatype properties not supported // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check if(description.compareTo(dNeg) != 0 + && (maxCardinalityLimit == cardinalityLimit || isMaxCardinalityLimitSatisfied(dNeg)) && (useDisjunction || !containsDisjunction(dNeg)) && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) @@ -985,6 +984,13 @@ private OWLClassExpression constructNegationInNNF(OWLClassExpression description return negatedDescription; } + private boolean isMaxCardinalityLimitSatisfied(OWLClassExpression description) { + return decomposer.decompose(description) + .stream().allMatch(e -> + !(e instanceof OWLObjectMaxCardinality) || ((OWLObjectMaxCardinality) e).getCardinality() <= maxCardinalityLimit + ); + } + private boolean containsDisjunction(OWLClassExpression description) { return decomposer.decompose(description) .stream().anyMatch(e -> e instanceof OWLObjectUnionOf); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index 16ab66eba1..ff81e958ed 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -19,6 +19,8 @@ public class RhoDRDownConfigOptionsMemento { private final boolean useSomeOnly; private final boolean useObjectValueNegation; + private final int maxCardinalityLimit; + public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { applyAllFilter = originator.isApplyAllFilter(); applyExistsFilter = originator.isApplyExistsFilter(); @@ -30,6 +32,8 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); useObjectValueNegation = originator.isUseObjectValueNegation(); + + maxCardinalityLimit = originator.getMaxCardinalityLimit(); } public void restore(RhoDRDown originator) { @@ -43,5 +47,7 @@ public void restore(RhoDRDown originator) { originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); originator.setUseObjectValueNegation(useObjectValueNegation); + + originator.setMaxCardinalityLimit(maxCardinalityLimit); } } From 960384a2f105df82c38e2bd7e3cca5aa2ec2faca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 4 Mar 2023 18:00:12 +0100 Subject: [PATCH 27/67] negations must not be disjoint with the current domain --- .../main/java/org/dllearner/refinementoperators/RhoDRDown.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 02c159a4dc..f3c40a9766 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -565,7 +565,7 @@ public Set refine(OWLClassExpression description, int maxLen tmp = classHierarchy.getSuperClasses(operand, true); for(OWLClassExpression c : tmp) { - if(!c.isOWLThing()){ + if(!c.isOWLThing() && !isDisjoint(df.getOWLObjectComplementOf(c), currDomain)){ refinements.add(df.getOWLObjectComplementOf(c)); } } From 1b51716b66db3eefbb5cb4f962c49d0745af3f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 07:18:14 +0100 Subject: [PATCH 28/67] shallow copying set of knowledge sources --- .../main/java/org/dllearner/core/AbstractReasonerComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components-core/src/main/java/org/dllearner/core/AbstractReasonerComponent.java b/components-core/src/main/java/org/dllearner/core/AbstractReasonerComponent.java index 026b2e86ad..16c134fbd3 100644 --- a/components-core/src/main/java/org/dllearner/core/AbstractReasonerComponent.java +++ b/components-core/src/main/java/org/dllearner/core/AbstractReasonerComponent.java @@ -165,7 +165,7 @@ public AbstractReasonerComponent(AbstractReasonerComponent reasonerComponent) { setPrecomputeObjectPropertyHierarchy(reasonerComponent.precomputeObjectPropertyHierarchy); setPrecomputeDataPropertyHierarchy(reasonerComponent.precomputeDataPropertyHierarchy); - setSources(reasonerComponent.sources); + setSources(new HashSet<>(reasonerComponent.sources)); precomputePropertyDomains = reasonerComponent.precomputePropertyDomains; precomputeObjectPropertyRanges = reasonerComponent.precomputeObjectPropertyRanges; From 1646ade2ee0d1d312e6e9ad9e13eacf522be762d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 11:55:34 +0100 Subject: [PATCH 29/67] useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored when refining upwards --- .../refinementoperators/RhoDRDown.java | 9 +------ .../RhoDRDownConfigOptionsMemento.java | 24 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 02c159a4dc..53cb473d41 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -922,14 +922,6 @@ private Set refineUpwards( useSomeOnly = false; useObjectValueNegation = true; - boolean optionTmp = useAllConstructor; - useAllConstructor = useExistsConstructor; - useExistsConstructor = optionTmp; - - optionTmp = applyAllFilter; - applyAllFilter = applyExistsFilter; - applyExistsFilter = optionTmp; - maxCardinalityLimit = cardinalityLimit; TreeSet results = new TreeSet<>(); @@ -952,6 +944,7 @@ private Set refineUpwards( // TODO: MY dropDisjuncts not supported // TODO: MY some values from and has value for datatype properties not supported + // TODO: MY useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored (assuming they are all set to true) // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index ff81e958ed..710afac456 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -1,19 +1,7 @@ package org.dllearner.refinementoperators; -import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; -import org.semanticweb.owlapi.model.*; - -import java.util.*; - -// does not store the reasoner used by the originator public class RhoDRDownConfigOptionsMemento { - private final boolean applyAllFilter; - private final boolean applyExistsFilter; - - private final boolean useAllConstructor; - private final boolean useExistsConstructor; - private final boolean useNegation; private final boolean useDisjunction; private final boolean useSomeOnly; @@ -22,12 +10,6 @@ public class RhoDRDownConfigOptionsMemento { private final int maxCardinalityLimit; public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { - applyAllFilter = originator.isApplyAllFilter(); - applyExistsFilter = originator.isApplyExistsFilter(); - - useAllConstructor = originator.isUseAllConstructor(); - useExistsConstructor = originator.isUseExistsConstructor(); - useNegation = originator.isUseNegation(); useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); @@ -37,12 +19,6 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { } public void restore(RhoDRDown originator) { - originator.setApplyAllFilter(applyAllFilter); - originator.setApplyExistsFilter(applyExistsFilter); - - originator.setUseAllConstructor(useAllConstructor); - originator.setUseExistsConstructor(useExistsConstructor); - originator.setUseNegation(useNegation); originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); From e0dada1b93a81274c40f073a0063e2089e04b259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 11:55:34 +0100 Subject: [PATCH 30/67] useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored when refining upwards --- .../refinementoperators/RhoDRDown.java | 9 +------ .../RhoDRDownConfigOptionsMemento.java | 24 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 83e4b84f1e..566fc22966 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -922,14 +922,6 @@ private Set refineUpwards( useSomeOnly = false; useObjectValueNegation = true; - boolean optionTmp = useAllConstructor; - useAllConstructor = useExistsConstructor; - useExistsConstructor = optionTmp; - - optionTmp = applyAllFilter; - applyAllFilter = applyExistsFilter; - applyExistsFilter = optionTmp; - maxCardinalityLimit = cardinalityLimit; TreeSet results = new TreeSet<>(); @@ -952,6 +944,7 @@ private Set refineUpwards( // TODO: MY dropDisjuncts not supported // TODO: MY some values from and has value for datatype properties not supported + // TODO: MY useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored (assuming they are all set to true) // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index ff81e958ed..710afac456 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -1,19 +1,7 @@ package org.dllearner.refinementoperators; -import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; -import org.semanticweb.owlapi.model.*; - -import java.util.*; - -// does not store the reasoner used by the originator public class RhoDRDownConfigOptionsMemento { - private final boolean applyAllFilter; - private final boolean applyExistsFilter; - - private final boolean useAllConstructor; - private final boolean useExistsConstructor; - private final boolean useNegation; private final boolean useDisjunction; private final boolean useSomeOnly; @@ -22,12 +10,6 @@ public class RhoDRDownConfigOptionsMemento { private final int maxCardinalityLimit; public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { - applyAllFilter = originator.isApplyAllFilter(); - applyExistsFilter = originator.isApplyExistsFilter(); - - useAllConstructor = originator.isUseAllConstructor(); - useExistsConstructor = originator.isUseExistsConstructor(); - useNegation = originator.isUseNegation(); useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); @@ -37,12 +19,6 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { } public void restore(RhoDRDown originator) { - originator.setApplyAllFilter(applyAllFilter); - originator.setApplyExistsFilter(applyExistsFilter); - - originator.setUseAllConstructor(useAllConstructor); - originator.setUseExistsConstructor(useExistsConstructor); - originator.setUseNegation(useNegation); originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); From 8206d9ae5658f1605497d243f40c8dbf8b702adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 11:55:34 +0100 Subject: [PATCH 31/67] useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored when refining upwards --- .../refinementoperators/RhoDRDown.java | 9 +------ .../RhoDRDownConfigOptionsMemento.java | 24 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 02c159a4dc..53cb473d41 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -922,14 +922,6 @@ private Set refineUpwards( useSomeOnly = false; useObjectValueNegation = true; - boolean optionTmp = useAllConstructor; - useAllConstructor = useExistsConstructor; - useExistsConstructor = optionTmp; - - optionTmp = applyAllFilter; - applyAllFilter = applyExistsFilter; - applyExistsFilter = optionTmp; - maxCardinalityLimit = cardinalityLimit; TreeSet results = new TreeSet<>(); @@ -952,6 +944,7 @@ private Set refineUpwards( // TODO: MY dropDisjuncts not supported // TODO: MY some values from and has value for datatype properties not supported + // TODO: MY useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored (assuming they are all set to true) // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index ff81e958ed..710afac456 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -1,19 +1,7 @@ package org.dllearner.refinementoperators; -import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; -import org.semanticweb.owlapi.model.*; - -import java.util.*; - -// does not store the reasoner used by the originator public class RhoDRDownConfigOptionsMemento { - private final boolean applyAllFilter; - private final boolean applyExistsFilter; - - private final boolean useAllConstructor; - private final boolean useExistsConstructor; - private final boolean useNegation; private final boolean useDisjunction; private final boolean useSomeOnly; @@ -22,12 +10,6 @@ public class RhoDRDownConfigOptionsMemento { private final int maxCardinalityLimit; public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { - applyAllFilter = originator.isApplyAllFilter(); - applyExistsFilter = originator.isApplyExistsFilter(); - - useAllConstructor = originator.isUseAllConstructor(); - useExistsConstructor = originator.isUseExistsConstructor(); - useNegation = originator.isUseNegation(); useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); @@ -37,12 +19,6 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { } public void restore(RhoDRDown originator) { - originator.setApplyAllFilter(applyAllFilter); - originator.setApplyExistsFilter(applyExistsFilter); - - originator.setUseAllConstructor(useAllConstructor); - originator.setUseExistsConstructor(useExistsConstructor); - originator.setUseNegation(useNegation); originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); From b76ad47d44ed5b6f739ee24bc4821d3f496930a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 11:55:34 +0100 Subject: [PATCH 32/67] useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored when refining upwards --- .../refinementoperators/RhoDRDown.java | 9 +------ .../RhoDRDownConfigOptionsMemento.java | 24 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 02c159a4dc..53cb473d41 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -922,14 +922,6 @@ private Set refineUpwards( useSomeOnly = false; useObjectValueNegation = true; - boolean optionTmp = useAllConstructor; - useAllConstructor = useExistsConstructor; - useExistsConstructor = optionTmp; - - optionTmp = applyAllFilter; - applyAllFilter = applyExistsFilter; - applyExistsFilter = optionTmp; - maxCardinalityLimit = cardinalityLimit; TreeSet results = new TreeSet<>(); @@ -952,6 +944,7 @@ private Set refineUpwards( // TODO: MY dropDisjuncts not supported // TODO: MY some values from and has value for datatype properties not supported + // TODO: MY useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored (assuming they are all set to true) // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index ff81e958ed..710afac456 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -1,19 +1,7 @@ package org.dllearner.refinementoperators; -import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; -import org.semanticweb.owlapi.model.*; - -import java.util.*; - -// does not store the reasoner used by the originator public class RhoDRDownConfigOptionsMemento { - private final boolean applyAllFilter; - private final boolean applyExistsFilter; - - private final boolean useAllConstructor; - private final boolean useExistsConstructor; - private final boolean useNegation; private final boolean useDisjunction; private final boolean useSomeOnly; @@ -22,12 +10,6 @@ public class RhoDRDownConfigOptionsMemento { private final int maxCardinalityLimit; public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { - applyAllFilter = originator.isApplyAllFilter(); - applyExistsFilter = originator.isApplyExistsFilter(); - - useAllConstructor = originator.isUseAllConstructor(); - useExistsConstructor = originator.isUseExistsConstructor(); - useNegation = originator.isUseNegation(); useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); @@ -37,12 +19,6 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { } public void restore(RhoDRDown originator) { - originator.setApplyAllFilter(applyAllFilter); - originator.setApplyExistsFilter(applyExistsFilter); - - originator.setUseAllConstructor(useAllConstructor); - originator.setUseExistsConstructor(useExistsConstructor); - originator.setUseNegation(useNegation); originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); From bbd914409b2c985684661bde82d8bd6be8e3d599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 11:55:34 +0100 Subject: [PATCH 33/67] useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored when refining upwards --- .../refinementoperators/RhoDRDown.java | 9 +------ .../RhoDRDownConfigOptionsMemento.java | 24 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index f3c40a9766..ce8d3c2f17 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -922,14 +922,6 @@ private Set refineUpwards( useSomeOnly = false; useObjectValueNegation = true; - boolean optionTmp = useAllConstructor; - useAllConstructor = useExistsConstructor; - useExistsConstructor = optionTmp; - - optionTmp = applyAllFilter; - applyAllFilter = applyExistsFilter; - applyExistsFilter = optionTmp; - maxCardinalityLimit = cardinalityLimit; TreeSet results = new TreeSet<>(); @@ -952,6 +944,7 @@ private Set refineUpwards( // TODO: MY dropDisjuncts not supported // TODO: MY some values from and has value for datatype properties not supported + // TODO: MY useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored (assuming they are all set to true) // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java index ff81e958ed..710afac456 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDownConfigOptionsMemento.java @@ -1,19 +1,7 @@ package org.dllearner.refinementoperators; -import org.dllearner.utilities.owl.OWLClassExpressionLengthMetric; -import org.semanticweb.owlapi.model.*; - -import java.util.*; - -// does not store the reasoner used by the originator public class RhoDRDownConfigOptionsMemento { - private final boolean applyAllFilter; - private final boolean applyExistsFilter; - - private final boolean useAllConstructor; - private final boolean useExistsConstructor; - private final boolean useNegation; private final boolean useDisjunction; private final boolean useSomeOnly; @@ -22,12 +10,6 @@ public class RhoDRDownConfigOptionsMemento { private final int maxCardinalityLimit; public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { - applyAllFilter = originator.isApplyAllFilter(); - applyExistsFilter = originator.isApplyExistsFilter(); - - useAllConstructor = originator.isUseAllConstructor(); - useExistsConstructor = originator.isUseExistsConstructor(); - useNegation = originator.isUseNegation(); useDisjunction = originator.isUseDisjunction(); useSomeOnly = originator.isUseSomeOnly(); @@ -37,12 +19,6 @@ public RhoDRDownConfigOptionsMemento(RhoDRDown originator) { } public void restore(RhoDRDown originator) { - originator.setApplyAllFilter(applyAllFilter); - originator.setApplyExistsFilter(applyExistsFilter); - - originator.setUseAllConstructor(useAllConstructor); - originator.setUseExistsConstructor(useExistsConstructor); - originator.setUseNegation(useNegation); originator.setUseDisjunction(useDisjunction); originator.setUseSomeOnly(useSomeOnly); From 23e517fe2505e1fa971827a34ba61788333153ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 12:20:29 +0100 Subject: [PATCH 34/67] useDisjunction checked on conjunction creation --- .../org/dllearner/refinementoperators/RhoDRDown.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 53cb473d41..1e118cc152 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -824,12 +824,16 @@ public Set refine(OWLClassExpression description, int maxLen if(topRefLength>0) { Set topRefs; if(currDomain.isOWLThing()) - topRefs = topRefinementsCumulative.get(topRefLength); + topRefs = (TreeSet) topRefinementsCumulative.get(topRefLength).clone(); else - topRefs = topARefinementsCumulative.get(currDomain).get(topRefLength); + topRefs = (TreeSet) topARefinementsCumulative.get(currDomain).get(topRefLength).clone(); if (!useNegation) { - topRefs = topRefs.stream().filter(c -> !containsNegation(c)).collect(Collectors.toSet()); + topRefs.removeIf(this::containsNegation); + } + + if (!useDisjunction) { + topRefs.removeIf(r -> r instanceof OWLObjectUnionOf); } for(OWLClassExpression c : topRefs) { From 3e2f11862a522641eaef6872ff7af3f8efe76aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 12:20:29 +0100 Subject: [PATCH 35/67] useDisjunction checked on conjunction creation --- .../org/dllearner/refinementoperators/RhoDRDown.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 566fc22966..8c879c1a57 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -824,12 +824,16 @@ public Set refine(OWLClassExpression description, int maxLen if(topRefLength>0) { Set topRefs; if(currDomain.isOWLThing()) - topRefs = topRefinementsCumulative.get(topRefLength); + topRefs = (TreeSet) topRefinementsCumulative.get(topRefLength).clone(); else - topRefs = topARefinementsCumulative.get(currDomain).get(topRefLength); + topRefs = (TreeSet) topARefinementsCumulative.get(currDomain).get(topRefLength).clone(); if (!useNegation) { - topRefs = topRefs.stream().filter(c -> !containsNegation(c)).collect(Collectors.toSet()); + topRefs.removeIf(this::containsNegation); + } + + if (!useDisjunction) { + topRefs.removeIf(r -> r instanceof OWLObjectUnionOf); } for(OWLClassExpression c : topRefs) { From b5cb17ca93b9d17311355bb453aae836b0a518d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 12:20:29 +0100 Subject: [PATCH 36/67] useDisjunction checked on conjunction creation --- .../org/dllearner/refinementoperators/RhoDRDown.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 53cb473d41..1e118cc152 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -824,12 +824,16 @@ public Set refine(OWLClassExpression description, int maxLen if(topRefLength>0) { Set topRefs; if(currDomain.isOWLThing()) - topRefs = topRefinementsCumulative.get(topRefLength); + topRefs = (TreeSet) topRefinementsCumulative.get(topRefLength).clone(); else - topRefs = topARefinementsCumulative.get(currDomain).get(topRefLength); + topRefs = (TreeSet) topARefinementsCumulative.get(currDomain).get(topRefLength).clone(); if (!useNegation) { - topRefs = topRefs.stream().filter(c -> !containsNegation(c)).collect(Collectors.toSet()); + topRefs.removeIf(this::containsNegation); + } + + if (!useDisjunction) { + topRefs.removeIf(r -> r instanceof OWLObjectUnionOf); } for(OWLClassExpression c : topRefs) { From 4bfffdfda20a1bc5b08376d0c8ef94cfb0358267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 12:20:29 +0100 Subject: [PATCH 37/67] useDisjunction checked on conjunction creation --- .../org/dllearner/refinementoperators/RhoDRDown.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 53cb473d41..1e118cc152 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -824,12 +824,16 @@ public Set refine(OWLClassExpression description, int maxLen if(topRefLength>0) { Set topRefs; if(currDomain.isOWLThing()) - topRefs = topRefinementsCumulative.get(topRefLength); + topRefs = (TreeSet) topRefinementsCumulative.get(topRefLength).clone(); else - topRefs = topARefinementsCumulative.get(currDomain).get(topRefLength); + topRefs = (TreeSet) topARefinementsCumulative.get(currDomain).get(topRefLength).clone(); if (!useNegation) { - topRefs = topRefs.stream().filter(c -> !containsNegation(c)).collect(Collectors.toSet()); + topRefs.removeIf(this::containsNegation); + } + + if (!useDisjunction) { + topRefs.removeIf(r -> r instanceof OWLObjectUnionOf); } for(OWLClassExpression c : topRefs) { From e642ba28deab5be6ab3ac74f28e86a47f0024d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 12:20:29 +0100 Subject: [PATCH 38/67] useDisjunction checked on conjunction creation --- .../org/dllearner/refinementoperators/RhoDRDown.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index ce8d3c2f17..95af864f7f 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -824,12 +824,16 @@ public Set refine(OWLClassExpression description, int maxLen if(topRefLength>0) { Set topRefs; if(currDomain.isOWLThing()) - topRefs = topRefinementsCumulative.get(topRefLength); + topRefs = (TreeSet) topRefinementsCumulative.get(topRefLength).clone(); else - topRefs = topARefinementsCumulative.get(currDomain).get(topRefLength); + topRefs = (TreeSet) topARefinementsCumulative.get(currDomain).get(topRefLength).clone(); if (!useNegation) { - topRefs = topRefs.stream().filter(c -> !containsNegation(c)).collect(Collectors.toSet()); + topRefs.removeIf(this::containsNegation); + } + + if (!useDisjunction) { + topRefs.removeIf(r -> r instanceof OWLObjectUnionOf); } for(OWLClassExpression c : topRefs) { From 3e0a78414058ecfb897f4652ade31e814005261b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 5 Mar 2023 12:28:01 +0100 Subject: [PATCH 39/67] removing commented-out code in workers --- .../java/org/dllearner/algorithms/parcel/ParCELWorker.java | 4 ---- .../org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java | 4 ---- 2 files changed, 8 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index a7f1c8beb6..1debe554c0 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -90,10 +90,6 @@ public void run() { while (refinements != null && refinements.size() > 0) { OWLClassExpression refinement = refinements.pollFirst(); -// if (refinement instanceof OWLObjectUnionOf) { -// continue; -// } - int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); // we ignore all refinements with lower length (may it happen?) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java index 766d51a205..25cfc31427 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java @@ -88,10 +88,6 @@ public void run() { while (refinements.size() > 0) { OWLClassExpression refinement = refinements.pollFirst(); -// if (refinement instanceof OWLObjectUnionOf) { -// continue; -// } - int refinementLength = new OWLClassExpressionLengthCalculator().getLength(refinement); From e80aa0db8e9bbb101fe8730ddacc3ce7214fd08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 6 Mar 2023 14:28:50 +0100 Subject: [PATCH 40/67] s/parcel always asking for refinements of horizExp length --- .../main/java/org/dllearner/algorithms/parcel/ParCELWorker.java | 2 +- .../org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java | 2 +- .../org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java | 2 +- .../org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java | 2 +- .../org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index a6648b7bf0..492a4ce1ab 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -94,7 +94,7 @@ public void run() { // we ignore all refinements with lower length (may it happen?) // (this also avoids duplicate children) - if (refinementLength > horizExp) { + if (refinementLength >= horizExp) { // calculate accuracy, correctness, positive examples covered by the description, // resulted in a node diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java index 34655cdd37..6d1685383a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorkerAbstract.java @@ -122,7 +122,7 @@ protected TreeSet refineNode(ParCELNode node) { try { // TODO that's odd, we should just restrict the whole code to LengthLimitedRefinementOperator if (refinementOperator instanceof LengthLimitedRefinementOperator) { - refinements = (TreeSet) ((LengthLimitedRefinementOperator) refinementOperator).refine(node.getDescription(), horizExp + 1); + refinements = (TreeSet) ((LengthLimitedRefinementOperator) refinementOperator).refine(node.getDescription(), horizExp); } else { refinements = (TreeSet) refinementOperator.refine(node.getDescription()); } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java index 3f6203b023..3910da7292 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV1.java @@ -91,7 +91,7 @@ public void run() { // we ignore all refinements with lower length (may it happen?) // (this also avoids duplicate node children) - if(refinementLength > horizExp) { + if(refinementLength >= horizExp) { //calculate accuracy, correctness, positive examples covered by the description, resulted in a node ParCELExtraNode newNode = checkAndCreateNewNodeV2(refinement, nodeToProcess); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java index 25cfc31427..928d41a2d0 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java @@ -93,7 +93,7 @@ public void run() { // we ignore all refinements with lower length (may it happen?) // (this also avoids duplicate node children) - if(refinementLength > horizExp) { + if(refinementLength >= horizExp) { //calculate accuracy, correctness, positive examples covered by the description, resulted in a node ParCELExtraNode newNode = null; diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java index 9094e5e78b..2796c237d6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java @@ -110,7 +110,7 @@ public void run() { // we ignore all refinements with lower length (may it happen?) // (this also avoids duplicate node children) - if(refinementLength > horizExp) { + if(refinementLength >= horizExp) { //calculate accuracy, correctness, positive examples covered by the description, resulted in a node ParCELExtraNode newNode = checkAndCreateNewNodeV2(refinement, nodeToProcess); From ea56edcca869f16424bc0cee378f5c8b2abad859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 6 Mar 2023 15:00:11 +0100 Subject: [PATCH 41/67] accuracy/coverage calculation improved in s/parcel --- .../algorithms/parcel/ParCELAbstract.java | 19 ++++++----- .../algorithms/parcel/ParCELPosNegLP.java | 21 ++++++------ .../algorithms/parcel/ParCELearner.java | 14 ++++---- .../parcelex/ParCELearnerExV12.java | 34 ++++++------------- 4 files changed, 37 insertions(+), 51 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index ec29d77019..24866ace2e 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -235,14 +235,6 @@ public ParCELAbstract(ParCELPosNegLP learningProblem, AbstractReasonerComponent //this.reducer = new ParCELPredScoreReducer(); } - private double getCurrentAccuracy() - { - double acc = (this.negativeExamples.size() + this.positiveExamples.size() - - this.uncoveredPositiveExamples.size())/ - (double) (this.positiveExamples.size() + this.negativeExamples.size()); - return acc; - } - protected void initOperatorIfAny() { if (operator == null) { return; @@ -348,10 +340,10 @@ public void newPartialDefinitionsFound(Set definitions) { logger.info("PARTIAL definition found. Uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + "\n" + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription())); - double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); double testAcc = computeTestAccuracy(bestDescription); logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); @@ -375,6 +367,15 @@ public void newPartialDefinitionsFound(Set definitions) { } } + protected double computeAccuracy(OWLClassExpression description) { + if (learningProblem instanceof ParCELPosNegLP) { + return ((ParCELPosNegLP) learningProblem).getAccuracy(description); + } + + return 0.0; + } + + @Override protected double computeTestAccuracy(OWLClassExpression description) { if (learningProblem instanceof ParCELPosNegLP) { diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java index b105501376..311bfc90da 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -10,7 +10,6 @@ */ import java.util.Set; -import java.util.ArrayList; import java.util.HashSet; import java.util.TreeSet; @@ -117,15 +116,15 @@ protected Set coveredUncoveredPositiveExamples(OWLClassExpression * Description * @return Number if positive examples covered by the description */ - protected int getNumberCoveredPositiveExamples(OWLClassExpression description) { - return getNumberCoveredPositiveExamples(description, positiveExamples); + public int getNumberOfCoveredPositiveExamples(OWLClassExpression description) { + return getNumberOfCoveredPositiveExamples(description, positiveExamples); } - protected int getNumberCoveredPositiveTestExamples(OWLClassExpression description) { - return getNumberCoveredPositiveExamples(description, positiveTestExamples); + public int getNumberOfCoveredPositiveTestExamples(OWLClassExpression description) { + return getNumberOfCoveredPositiveExamples(description, positiveTestExamples); } - protected int getNumberCoveredPositiveExamples(OWLClassExpression description, Set allPosExamples) { + protected int getNumberOfCoveredPositiveExamples(OWLClassExpression description, Set allPosExamples) { int coveredPos = 0; for (OWLIndividual example : allPosExamples) { @@ -144,11 +143,11 @@ protected int getNumberCoveredPositiveExamples(OWLClassExpression description, S * * @return Number of negative examples covered by the description */ - protected int getNumberOfCoveredNegativeExamples(OWLClassExpression description) { + public int getNumberOfCoveredNegativeExamples(OWLClassExpression description) { return getNumberOfCoveredNegativeExamples(description, negativeExamples); } - protected int getNumberOfCoveredNegativeTestExamples(OWLClassExpression description) { + public int getNumberOfCoveredNegativeTestExamples(OWLClassExpression description) { return getNumberOfCoveredNegativeExamples(description, negativeTestExamples); } @@ -174,7 +173,7 @@ protected int getNumberOfCoveredNegativeExamples(OWLClassExpression description, * @return Predictive accuracy of a description */ protected double accuracy_cal(OWLClassExpression description) { - int cp = this.getNumberCoveredPositiveExamples(description); + int cp = this.getNumberOfCoveredPositiveExamples(description); int un = this.negativeExamples.size() - this.getNumberOfCoveredNegativeExamples(description); @@ -182,7 +181,7 @@ protected double accuracy_cal(OWLClassExpression description) { } protected double testAccuracy_cal(OWLClassExpression description) { - int cp = this.getNumberCoveredPositiveTestExamples(description); + int cp = this.getNumberOfCoveredPositiveTestExamples(description); int un = this.negativeTestExamples.size() - this.getNumberOfCoveredNegativeTestExamples(description); @@ -212,7 +211,7 @@ protected double correctness_cal(OWLClassExpression description) { * @return Complete if the description */ protected double completeness_cal(OWLClassExpression description) { - int cp = this.getNumberCoveredPositiveExamples(description); + int cp = this.getNumberOfCoveredPositiveExamples(description); return cp / (double) this.positiveExamples.size(); } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index 86dcb89073..759ee1f51e 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -18,7 +18,6 @@ import org.dllearner.core.AbstractReasonerComponent; import org.dllearner.core.ComponentAnn; import org.dllearner.core.ComponentInitException; -import org.dllearner.learningproblems.PosNegLP; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.semanticweb.owlapi.model.OWLClassExpression; @@ -232,18 +231,13 @@ public void start() { // ------------------------------- if (logger.isInfoEnabled()) { synchronized (partialDefinitions) { - double acc = (this.negativeExamples.size() + this.positiveExamples.size() - - this.uncoveredPositiveExamples.size())/ - (double) (this.positiveExamples.size() + this.negativeExamples.size()); - if (this.getCurrentlyOveralMaxCompleteness() == 1) logger.info("Learning finishes in: " + this.miliLearningTime + "ms, with: " + partialDefinitions.size() + " definitions"); else if (this.isTimeout()) { logger.info("Learning timeout in " + this.maxExecutionTimeInSeconds + "s. Overall completeness: " - + df.format(this.getCurrentlyOveralMaxCompleteness()) + ", accuracy: " - + df.format(acc)); + + df.format(this.getCurrentlyOveralMaxCompleteness())); logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() @@ -262,6 +256,10 @@ else if (this.isTimeout()) { this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); } + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); + logger.info("Accuracy: " + acc); logger.info("Total descriptions generated: " + allDescriptions.size() + ", best description length: " + getCurrentlyBestDescriptionLength() @@ -274,7 +272,7 @@ else if (this.isTimeout()) { int count = 1; for (ParCELExtraNode def : compactedDefinitions) { int tpTest = learningProblem instanceof ParCELPosNegLP - ? ((ParCELPosNegLP) learningProblem).getNumberCoveredPositiveTestExamples(def.getDescription()) + ? ((ParCELPosNegLP) learningProblem).getNumberOfCoveredPositiveTestExamples(def.getDescription()) : 0; logger.info(count++ + ". " diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index e1f7acdb05..8d5212c2c6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -14,13 +14,9 @@ * @author An C. Tran */ -import java.text.DecimalFormat; import java.util.*; -import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentSkipListSet; -import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.text.*; import java.util.stream.Collectors; @@ -37,22 +33,13 @@ import org.dllearner.algorithms.parcel.ParCELNode; import org.dllearner.algorithms.parcel.ParCELPosNegLP; import org.dllearner.algorithms.parcel.reducer.ParCELReducer; -import org.dllearner.algorithms.parcel.ParCELRefinementOperatorPool; import org.dllearner.algorithms.parcel.ParCELStringUtilities; -import org.dllearner.algorithms.parcel.split.ParCELDoubleSplitterAbstract; import org.dllearner.algorithms.celoe.OENode; -import org.dllearner.algorithms.parcel.ParCELWorkerThreadFactory; import org.dllearner.core.*; -import org.dllearner.core.owl.ClassHierarchy; -import org.dllearner.refinementoperators.RefinementOperator; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; -import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataProperty; -import org.semanticweb.owlapi.model.OWLIndividual; -import org.springframework.beans.factory.annotation.Autowired; import org.dllearner.algorithms.parcel.ParCELearnerMBean; @ComponentAnn(name="ParCELearnerExV12", shortName="parcelearnerExV12", version=0.1, description="Parallel Class Expression Logic Learning with Exception") @@ -102,14 +89,6 @@ public static String getName() { return "PLLearningReducer"; } - private double getCurrentAccuracy() - { - double acc = (this.negativeExamples.size() + this.positiveExamples.size() - - this.uncoveredPositiveExamples.size())/ - (double) (this.positiveExamples.size() + this.negativeExamples.size()); - return acc; - } - /**=========================================================================================================
* Initial the learning algorithm * - Create distance data @@ -390,15 +369,24 @@ else if (this.isTimeout()) { logger.info("Learning is manually terminated at " + this.miliLearningTime + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); } + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); + logger.info("Accuracy: " + acc); logger.info("**Reduced partial definitions:"); TreeSet compactedDefinitions = (TreeSet) this.getReducedPartialDefinition(); this.noOfCompactedPartialDefinition = compactedDefinitions.size(); int count = 1; for (ParCELExtraNode def : compactedDefinitions) { + int tpTest = learningProblem instanceof ParCELPosNegLP + ? ((ParCELPosNegLP) learningProblem).getNumberOfCoveredPositiveTestExamples(def.getDescription()) + : 0; + logger.info(count++ + ". " + OWLAPIRenderers.toManchesterOWLSyntax(ParCELExUtilities.groupDefinition(def.getDescription())).replace("and (not", "\nand (not") + //def.getDescription().toManchesterSyntaxString(baseURI, prefix) + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + ", accuracy: " + df.format(def.getAccuracy()) + " / " + computeTestAccuracy(def.getDescription()) + + ", coverage: " + def.getCoveredPositiveExamples().size() + " / " + tpTest + ")" + ", type: " + def.getType() + ")"); //print out the learning tree @@ -518,10 +506,10 @@ else if (logger.isInfoEnabled()) { String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); logger.info(timeStamp + ": " + def); - double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); double testAcc = computeTestAccuracy(bestDescription); logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); @@ -634,10 +622,10 @@ else if (logger.isInfoEnabled()) { String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); logger.info(timeStamp + ": " + def); - double acc = this.getCurrentAccuracy(); double actualTrainingTime = getCurrentCpuMillis() / 1000.0; OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); double testAcc = computeTestAccuracy(bestDescription); logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); From 76ada64a0db7e77b9f2fbe6115f95f0ccd6fd054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 6 Mar 2023 15:35:13 +0100 Subject: [PATCH 42/67] s/parcel - first return nodes, then partial definitions --- .../org/dllearner/algorithms/parcel/ParCELWorker.java | 5 ++--- .../dllearner/algorithms/parcelex/ParCELWorkerExV12.java | 8 ++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index 492a4ce1ab..c609867a58 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -127,11 +127,10 @@ public void run() { newNodes.add(nodeToProcess); - if (definitionsFound.size() > 0) - learner.newPartialDefinitionsFound(definitionsFound); - learner.newRefinementDescriptions(newNodes); + if (definitionsFound.size() > 0) + learner.newPartialDefinitionsFound(definitionsFound); } /** diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java index 928d41a2d0..9d6d415df6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV12.java @@ -158,20 +158,16 @@ public void run() { newNodes.add(nodeToProcess); + learner.newRefinementDescriptions(newNodes); //don't need to check for empty since newNodes is never empty if (newPartialDefinitions.size() > 0) learner.newPartialDefinitionsFound(newPartialDefinitions); if (newCounterPartialDefinitions.size() > 0) learner.newCounterPartialDefinitionsFound(newCounterPartialDefinitions); - - + if (newPotentialPartialDefinitions.size() > 0) ((ParCELearnerExV12)learner).newPotentialPartialDefinition(newPotentialPartialDefinitions); - - - learner.newRefinementDescriptions(newNodes); //don't need to check for empty since newNodes is never empty - } } From c723fccba13a7736c2096cf42540150303b87a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 6 Mar 2023 17:43:18 +0100 Subject: [PATCH 43/67] ocel/celoe coverage info added --- .../java/org/dllearner/algorithms/celoe/CELOE.java | 5 +++++ .../main/java/org/dllearner/algorithms/ocel/OCEL.java | 10 ++++++++++ .../src/main/java/org/dllearner/core/AbstractCELA.java | 10 +++++++++- .../java/org/dllearner/learningproblems/PosNegLP.java | 8 ++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index 39c06d0344..f62f3775d0 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -890,9 +890,14 @@ private void printSolutionCandidates() { logger.info("solutions within margin (at most " + maxNrOfResultsWithinMargin + " are shown):"); int show = 1; for (OENode c : solutionCandidates.descendingKeySet()) { + int tpTest = learningProblem instanceof PosNegLP + ? ((PosNegLP) learningProblem).getTestCoverage(c.getDescription()) + : 0; + logger.info(show + ": " + renderer.render(c.getDescription()) + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " + df.format(100 * computeTestAccuracy(c.getDescription())) + "%" + + ", coverage " + c.getCoveredPositiveExamples().size() + " / " + tpTest + ", length " + OWLClassExpressionUtils.getLength(c.getDescription()) + ", depth " + OWLClassExpressionUtils.getDepth(c.getDescription()) + ", time " + df.format(solutionCandidates.get(c)) + "s)"); diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index fd1c40cbda..a3e537bbeb 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -572,9 +572,14 @@ public void start() { logger.info("solutions within margin (at most " + maxNrOfResultsWithinMargin + " are shown):"); int show = 1; for (ExampleBasedNode c : solutionCandidates.descendingKeySet()) { + int tpTest = learningProblem instanceof PosNegLP + ? ((PosNegLP) learningProblem).getTestCoverage(c.getConcept()) + : 0; + logger.info(show + ": " + renderer.render(c.getConcept()) + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " + df.format(100 * computeTestAccuracy(c.getConcept())) + "%" + + ", coverage " + c.getCoveredPositives().size() + " / " + tpTest + ", length " + OWLClassExpressionUtils.getLength(c.getConcept()) + ", depth " + OWLClassExpressionUtils.getDepth(c.getConcept()) + ", time " + df.format(solutionCandidates.get(c)) + "s)"); @@ -592,9 +597,14 @@ public void start() { logger.info("solutions (at most " + maxNrOfResults + " are shown):"); int show = 1; for (ExampleBasedNode c : solutions.descendingKeySet()) { + int tpTest = learningProblem instanceof PosNegLP + ? ((PosNegLP) learningProblem).getTestCoverage(c.getConcept()) + : 0; + logger.info(show + ": " + renderer.render(c.getConcept()) + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " + df.format(100 * computeTestAccuracy(c.getConcept())) + "%" + + ", coverage " + c.getCoveredPositives().size() + " / " + tpTest + ", length " + OWLClassExpressionUtils.getLength(c.getConcept()) + ", depth " + OWLClassExpressionUtils.getDepth(c.getConcept()) + ", time " + df.format(solutions.get(c)) + "s)"); diff --git a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java index ed7d4607a8..d7f5668a09 100644 --- a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java +++ b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java @@ -360,10 +360,18 @@ protected String getSolutionString() { Set positiveExamples = ((PosNegLP)learningProblem).getPositiveExamples(); Set negativeExamples = ((PosNegLP)learningProblem).getNegativeExamples(); ReasoningUtils reasoningUtil = learningProblem.getReasoningUtil(); - + + int tp = learningProblem instanceof PosNegLP + ? ((PosNegLP) learningProblem).getCoverage(description) + : 0; + int tpTest = learningProblem instanceof PosNegLP + ? ((PosNegLP) learningProblem).getTestCoverage(description) + : 0; + str += current + ": " + descriptionString + " (pred. acc.: " + dfPercent.format(reasoningUtil.getAccuracyOrTooWeak2(new AccMethodPredAcc(true), description, positiveExamples, negativeExamples, 1)) + " / " + dfPercent.format(computeTestAccuracy(description)) + + ", coverage " + tp + " / " + tpTest + ", F-measure: "+ dfPercent.format(reasoningUtil.getAccuracyOrTooWeak2(new AccMethodFMeasure(true), description, positiveExamples, negativeExamples, 1)); AccMethodTwoValued accuracyMethod = ((PosNegLP)learningProblem).getAccuracyMethod(); diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java index ac91cd3442..9176b40763 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java @@ -146,6 +146,14 @@ public double getTestAccuracyOrTooWeak(OWLClassExpression description, double no return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); } + public int getCoverage(OWLClassExpression description) { + return reasoningUtil.getCoverageCount(description, positiveExamples)[0].trueCount; + } + + public int getTestCoverage(OWLClassExpression description) { + return reasoningUtil.getCoverageCount(description, positiveTestExamples)[0].trueCount; + } + public double getAccuracyOrTooWeak(Set coveredPositives, Set coveredNegatives, double noise) { int tp = coveredPositives.size(); int fp = coveredNegatives.size(); From f64f1dbb1155fc2773111abdea8d1191a1e87573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 6 Mar 2023 17:48:12 +0100 Subject: [PATCH 44/67] removing todos --- .../src/main/java/org/dllearner/algorithms/celoe/CELOE.java | 5 ----- .../src/main/java/org/dllearner/algorithms/ocel/OCEL.java | 1 - .../algorithms/parcel/ParCELRefinementOperatorFactory.java | 2 +- .../java/org/dllearner/refinementoperators/RhoDRDown.java | 6 +++--- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index f62f3775d0..b4a2297fd6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -276,11 +276,6 @@ public void init() throws ComponentInitException { heuristic = new OEHeuristicRuntime(); heuristic.init(); } - - // TODO: MY copy from MultiHeuristic -// if (heuristic instanceof OEHeuristicRuntime) { -// ((OEHeuristicRuntime) heuristic).setLengthMetric(lengthMetric); -// } minimizer = new OWLClassExpressionMinimizer(dataFactory, reasoner); diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index a3e537bbeb..f5c369788f 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -860,7 +860,6 @@ private void extendNodeProper(ExampleBasedNode node, OWLClassExpression concept, propernessCalcReasoningTimeNs += System.nanoTime() - propCalcReasoningStart2; newNode.setQualityEvaluationMethod(ExampleBasedNode.QualityEvaluationMethod.REASONER); - // TODO: MY use noise or remove noise variable entirely if (quality != -1 && !(((PosNegLP) learningProblem).getAccuracyMethod() instanceof AccMethodNoWeakness) && ((PosNegLP) learningProblem).getAccuracyMethod().getAccOrTooWeak2( newlyCoveredPositives.size(), nrOfPositiveExamples - newlyCoveredPositives.size(), diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java index 4de20adfd6..246cdf26cd 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java @@ -122,7 +122,7 @@ public RefinementOperator create() throws Exception { operatorPrototype.setStartClass(startClass); operatorPrototype.setUseDisjunction(useDisjunction); operatorPrototype.setUseNegation(useNegation); - operatorPrototype.setUseDataHasValueConstructor(useHasData); // TODO: MY set default back to true + operatorPrototype.setUseDataHasValueConstructor(useHasData); operatorPrototype.setUseHasValueConstructor(useHasValue); operatorPrototype.setCardinalityLimit(cardinalityLimit); operatorPrototype.setMaxNrOfSplits(maxNoOfSplits); diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index abf633435b..9dbfe1bf31 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -946,9 +946,9 @@ private Set refineUpwards( OWLClassExpression dNeg = constructNegationInNNF(d); dNeg = ConceptTransformation.cleanConcept(dNeg); - // TODO: MY dropDisjuncts not supported - // TODO: MY some values from and has value for datatype properties not supported - // TODO: MY useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored (assuming they are all set to true) + // TODO: dropDisjuncts not supported + // TODO: some values from and has value for datatype properties not supported + // TODO: useAllConstructor, useExistsConstructor, applyAllFilter, applyExistsFilter ignored (assuming they are all set to true) // to satisfy the guarantee that the method does not return longer // concepts, we perform an additional check From f63804e026f3138b2393aeae0b09b76de1a9cb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Tue, 7 Mar 2023 09:39:23 +0100 Subject: [PATCH 45/67] printing total execution time --- .../src/main/java/org/dllearner/algorithms/celoe/CELOE.java | 5 +++-- .../src/main/java/org/dllearner/algorithms/ocel/OCEL.java | 2 ++ .../java/org/dllearner/algorithms/parcel/ParCELearner.java | 2 ++ .../org/dllearner/algorithms/parcelex/ParCELearnerExV12.java | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index b4a2297fd6..024295e46b 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -867,12 +867,13 @@ private void reset() { } private void printAlgorithmRunStats() { + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + if (stop) { logger.info("Algorithm stopped ("+expressionTests+" descriptions tested). " + searchTree.size() + " nodes in the search tree.\n"); logger.info(reasoner.toString()); } else { - totalRuntimeNs = System.nanoTime()-nanoStartTime; - logger.info("Algorithm terminated successfully (time: " + Helper.prettyPrintNanoSeconds(totalRuntimeNs) + ", "+expressionTests+" descriptions tested, " + searchTree.size() + " nodes in the search tree).\n"); + logger.info("Algorithm terminated successfully ("+expressionTests+" descriptions tested, " + searchTree.size() + " nodes in the search tree).\n"); logger.info(reasoner.toString()); } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index f5c369788f..be028a5501 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -567,6 +567,8 @@ public void start() { loop++; }// end while + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + if (solutionCandidates.size() > 0) { // we do not need to print the best node if we display the top 20 solutions below anyway logger.info("solutions within margin (at most " + maxNrOfResultsWithinMargin + " are shown):"); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index 759ee1f51e..dd8c97385a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -257,6 +257,8 @@ else if (this.isTimeout()) { this.prefix)); } + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); double acc = computeAccuracy(bestDescription); logger.info("Accuracy: " + acc); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index 8d5212c2c6..65978755e6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -370,6 +370,8 @@ else if (this.isTimeout()) { logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); } + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); double acc = computeAccuracy(bestDescription); logger.info("Accuracy: " + acc); From 64088386b58a53926124df7cb4fddc6c9e068bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Tue, 7 Mar 2023 18:55:51 +0100 Subject: [PATCH 46/67] isSomeOnlySatisfied corrected, improved, and used instead of isCombinable --- .../refinementoperators/RhoDRDown.java | 81 ++++++++++--------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 9dbfe1bf31..91a14594bd 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -550,7 +550,7 @@ public Set refine(OWLClassExpression description, int maxLen } if (useSomeOnly) { - refinements.removeIf(r -> r instanceof OWLObjectAllValuesFrom || !isSomeOnlySatisfied(r, Set.of())); + refinements.removeIf(r -> !isSomeOnlySatisfied(r, Set.of())); } // refinements.addAll(classHierarchy.getMoreSpecialConcepts(description)); @@ -583,22 +583,20 @@ public Set refine(OWLClassExpression description, int maxLen // create new intersection for(OWLClassExpression c : tmp) { - if(!useSomeOnly || isCombinable(description, c)) { - List newChildren = new ArrayList<>(operands); - newChildren.add(c); - newChildren.remove(child); - Collections.sort(newChildren); - OWLClassExpression mc = new OWLObjectIntersectionOfImplExt(newChildren); - - // clean concept and transform it to ordered negation normal form - // (non-recursive variant because only depth 1 was modified) - mc = ConceptTransformation.cleanConceptNonRecursive(mc); - mc = ConceptTransformation.nnf(mc); - - // check whether the intersection is OK (sanity checks), then add it - if(checkIntersection((OWLObjectIntersectionOf) mc)) - refinements.add(mc); - } + List newChildren = new ArrayList<>(operands); + newChildren.add(c); + newChildren.remove(child); + Collections.sort(newChildren); + OWLClassExpression mc = new OWLObjectIntersectionOfImplExt(newChildren); + + // clean concept and transform it to ordered negation normal form + // (non-recursive variant because only depth 1 was modified) + mc = ConceptTransformation.cleanConceptNonRecursive(mc); + mc = ConceptTransformation.nnf(mc); + + // check whether the intersection is OK (sanity checks), then add it + if((!useSomeOnly || isSomeOnlySatisfied(mc, Set.of(), 2)) && checkIntersection((OWLObjectIntersectionOf) mc)) + refinements.add(mc); } } @@ -862,9 +860,10 @@ public Set refine(OWLClassExpression description, int maxLen // we only add \forall r.C to an intersection if there is // already some existential restriction \exists r.C - if(useSomeOnly) { - skip = !isCombinable(description, c); - } + // => checking later using isSomeOnlySatisfied +// if(useSomeOnly) { +// skip = !isCombinable(description, c); +// } // check for double datatype properties /* @@ -897,7 +896,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if (checkIntersection(mc)) + if ((!useSomeOnly || isSomeOnlySatisfied(mc, Set.of())) && checkIntersection(mc)) refinements.add(mc); } } @@ -957,7 +956,7 @@ private Set refineUpwards( && (useDisjunction || !containsDisjunction(dNeg)) && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) - && (!useSomeOnly || (!(dNeg instanceof OWLObjectAllValuesFrom) && isSomeOnlySatisfied(dNeg, Set.of()))) + && (!useSomeOnly || isSomeOnlySatisfied(dNeg, Set.of())) && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength ) { results.add(dNeg); @@ -1008,50 +1007,52 @@ private boolean containsObjectValueNegation(OWLClassExpression description) { } private boolean isSomeOnlySatisfied(OWLClassExpression description, Set prevSomeValuesProperties) { - if (description instanceof OWLObjectIntersectionOf) { - Set allValuesProperties = - ((OWLObjectIntersectionOf) description).getOperands() - .stream().filter(op -> op instanceof OWLObjectAllValuesFrom) - .map(op -> ((OWLObjectAllValuesFrom) op).getProperty()) - .collect(Collectors.toSet()); + return isSomeOnlySatisfied(description, prevSomeValuesProperties, -1); + } + + // maxRecursiveCalls < 0 means that the entire description should be traversed recursively + private boolean isSomeOnlySatisfied(OWLClassExpression description, Set prevSomeValuesProperties, int maxRecursiveCalls) { + if (maxRecursiveCalls == 0) { + return !(description instanceof OWLObjectAllValuesFrom) + || prevSomeValuesProperties.contains(((OWLObjectAllValuesFrom) description).getProperty()); + } + if (description instanceof OWLObjectIntersectionOf) { Set someValuesProperties = ((OWLObjectIntersectionOf) description).getOperands() .stream().filter(op -> op instanceof OWLObjectSomeValuesFrom) .map(op -> ((OWLObjectSomeValuesFrom) op).getProperty()) .collect(Collectors.toSet()); - allValuesProperties.removeAll(someValuesProperties); - - return allValuesProperties.isEmpty() - && ((OWLObjectIntersectionOf) description).getOperands() - .stream().allMatch(op -> isSomeOnlySatisfied(op, someValuesProperties)); + return ((OWLObjectIntersectionOf) description).getOperands() + .stream().allMatch(op -> isSomeOnlySatisfied(op, someValuesProperties, maxRecursiveCalls - 1)); } if (description instanceof OWLObjectUnionOf) { return ((OWLObjectUnionOf) description).getOperands() - .stream().allMatch(op -> - (!(op instanceof OWLObjectSomeValuesFrom) || prevSomeValuesProperties.contains(((OWLObjectSomeValuesFrom) op).getProperty())) - && isSomeOnlySatisfied(op, Set.of()) - ); + .stream().allMatch(op -> isSomeOnlySatisfied(op, prevSomeValuesProperties, maxRecursiveCalls - 1)); } if (description instanceof OWLObjectSomeValuesFrom) { OWLClassExpression filler = ((OWLObjectSomeValuesFrom) description).getFiller(); - return isSomeOnlySatisfied(filler, Set.of()); + return isSomeOnlySatisfied(filler, Set.of(), maxRecursiveCalls - 1); } if (description instanceof OWLObjectAllValuesFrom) { + if (!prevSomeValuesProperties.contains(((OWLObjectAllValuesFrom) description).getProperty())) { + return false; + } + OWLClassExpression filler = ((OWLObjectAllValuesFrom) description).getFiller(); - return isSomeOnlySatisfied(filler, Set.of()); + return isSomeOnlySatisfied(filler, Set.of(), maxRecursiveCalls - 1); } if (description instanceof OWLObjectCardinalityRestriction) { OWLClassExpression filler = ((OWLObjectCardinalityRestriction) description).getFiller(); - return isSomeOnlySatisfied(filler, Set.of()); + return isSomeOnlySatisfied(filler, Set.of(), maxRecursiveCalls - 1); } return true; From 1ee2f442217d1c5c8b70a7519373e1ffcb000c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Tue, 7 Mar 2023 19:10:27 +0100 Subject: [PATCH 47/67] printing timestamps --- .../main/java/org/dllearner/algorithms/celoe/CELOE.java | 7 +++++-- .../src/main/java/org/dllearner/algorithms/ocel/OCEL.java | 7 +++++-- .../org/dllearner/algorithms/parcel/ParCELearner.java | 8 ++++++-- .../dllearner/algorithms/parcelex/ParCELearnerExV12.java | 7 +++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index 024295e46b..00b01fa74c 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -48,6 +48,7 @@ import java.io.File; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.TimeUnit; @@ -355,7 +356,8 @@ public void start() { currentHighestAccuracy = 0.0; OENode nextNode; - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); logger.info("start class:" + startClass); addNode(startClass, null); @@ -867,7 +869,8 @@ private void reset() { } private void printAlgorithmRunStats() { - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); if (stop) { logger.info("Algorithm stopped ("+expressionTests+" descriptions tested). " + searchTree.size() + " nodes in the search tree.\n"); diff --git a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java index be028a5501..c7086c2910 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java +++ b/components-core/src/main/java/org/dllearner/algorithms/ocel/OCEL.java @@ -48,6 +48,7 @@ import java.io.File; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; import java.util.*; /** @@ -473,7 +474,8 @@ public void start() { ExampleBasedNode bestNode = startNode; ExampleBasedNode bestNodeStable = startNode; - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); logger.info("starting top down refinement with: " + renderer.render(startNode.getConcept()) + " (" + df.format(100 * startNode.getAccuracy()) + "% accuracy)"); int loop = 0; @@ -567,7 +569,8 @@ public void start() { loop++; }// end while - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); if (solutionCandidates.size() > 0) { // we do not need to print the best node if we display the top 20 solutions below anyway diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index dd8c97385a..fede0cbcfb 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -25,6 +25,7 @@ import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.management.ManagementFactory; +import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.RejectedExecutionException; @@ -185,7 +186,9 @@ public void start() { // start time of the learner miliStarttime = System.currentTimeMillis(); - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); // ---------------------------------------------------------- // perform the learning process until the conditions for @@ -257,7 +260,8 @@ else if (this.isTimeout()) { this.prefix)); } - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); double acc = computeAccuracy(bestDescription); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index 65978755e6..139e867036 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -196,7 +196,9 @@ public void start() { //start time of reducer, statistical purpose only miliStarttime = System.currentTimeMillis(); - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); //---------------------------------------------------------- // perform the learning process until the conditions for @@ -370,7 +372,8 @@ else if (this.isTimeout()) { logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); } - logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s"); + timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); double acc = computeAccuracy(bestDescription); From d4de70f295a731181c9dd596bcb89b5217ff86d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Wed, 8 Mar 2023 09:32:02 +0100 Subject: [PATCH 48/67] isSomeOnlySatisfied refactoring --- .../refinementoperators/RhoDRDown.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 91a14594bd..3a1a3d35af 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -550,7 +550,7 @@ public Set refine(OWLClassExpression description, int maxLen } if (useSomeOnly) { - refinements.removeIf(r -> !isSomeOnlySatisfied(r, Set.of())); + refinements.removeIf(r -> !isSomeOnlySatisfied(r)); } // refinements.addAll(classHierarchy.getMoreSpecialConcepts(description)); @@ -595,7 +595,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = ConceptTransformation.nnf(mc); // check whether the intersection is OK (sanity checks), then add it - if((!useSomeOnly || isSomeOnlySatisfied(mc, Set.of(), 2)) && checkIntersection((OWLObjectIntersectionOf) mc)) + if((!useSomeOnly || isSomeOnlySatisfied(mc, 2)) && checkIntersection((OWLObjectIntersectionOf) mc)) refinements.add(mc); } @@ -896,7 +896,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if ((!useSomeOnly || isSomeOnlySatisfied(mc, Set.of())) && checkIntersection(mc)) + if ((!useSomeOnly || isSomeOnlySatisfied(mc)) && checkIntersection(mc)) refinements.add(mc); } } @@ -956,7 +956,7 @@ private Set refineUpwards( && (useDisjunction || !containsDisjunction(dNeg)) && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) - && (!useSomeOnly || isSomeOnlySatisfied(dNeg, Set.of())) + && (!useSomeOnly || isSomeOnlySatisfied(dNeg)) && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength ) { results.add(dNeg); @@ -1006,8 +1006,13 @@ private boolean containsObjectValueNegation(OWLClassExpression description) { ); } - private boolean isSomeOnlySatisfied(OWLClassExpression description, Set prevSomeValuesProperties) { - return isSomeOnlySatisfied(description, prevSomeValuesProperties, -1); + private boolean isSomeOnlySatisfied(OWLClassExpression description) { + return isSomeOnlySatisfied(description, -1); + } + + // maxRecursiveCalls < 0 means that the entire description should be traversed recursively + private boolean isSomeOnlySatisfied(OWLClassExpression description, int maxRecursiveCalls) { + return isSomeOnlySatisfied(description, Set.of(), maxRecursiveCalls); } // maxRecursiveCalls < 0 means that the entire description should be traversed recursively From 862298cab68f0ebde90d895cefc2cb513dc5e2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Wed, 8 Mar 2023 10:25:54 +0100 Subject: [PATCH 49/67] useRestrictedDisjunction option added --- .../algorithms/parcel/ParCELAbstract.java | 19 +++-- .../ParCELRefinementOperatorFactory.java | 13 ++-- .../algorithms/parcelex/ParCELearnerExV2.java | 4 +- .../refinementoperators/RhoDRDown.java | 69 +++++++++++++++---- 4 files changed, 79 insertions(+), 26 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 24866ace2e..9ec1a7e511 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -1,7 +1,5 @@ package org.dllearner.algorithms.parcel; -import com.jamonapi.Monitor; -import com.jamonapi.MonitorFactory; import org.apache.log4j.Logger; import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer; @@ -13,7 +11,6 @@ import org.dllearner.core.owl.DatatypePropertyHierarchy; import org.dllearner.core.owl.OWLObjectUnionOfImplExt; import org.dllearner.core.owl.ObjectPropertyHierarchy; -import org.dllearner.learningproblems.PosNegLP; import org.dllearner.refinementoperators.*; import org.dllearner.utilities.owl.EvaluatedDescriptionComparator; import org.dllearner.utilities.owl.OWLAPIRenderers; @@ -22,9 +19,7 @@ import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLDataProperty; import org.semanticweb.owlapi.model.OWLIndividual; -import org.springframework.beans.factory.annotation.Autowired; -import javax.naming.OperationNotSupportedException; import java.lang.invoke.MethodHandles; import java.text.DecimalFormat; import java.util.*; @@ -72,6 +67,9 @@ public abstract class ParCELAbstract extends AbstractCELA implements ParCELearne @ConfigOption(defaultValue = "5", description = "Cardinality limit") protected int cardinalityLimit = 5; + @ConfigOption(description="support of disjunction (owl:unionOf) within a qualified number restriction or a universal quantification", defaultValue="false") + protected boolean useRestrictedDisjunction = false; + @ConfigOption(defaultValue = "owl:Thing", description = "You can specify a start class for the algorithm. To do this, you have to use Manchester OWL syntax either with full IRIs or prefixed IRIs.", exampleValue = "ex:Male or http://example.org/ontology/Female") @@ -252,6 +250,7 @@ protected void initOperatorIfAny() { if (operator instanceof RhoDRDown) { ((RhoDRDown) operator).setUseDisjunction(false); + ((RhoDRDown) operator).setUseRestrictedDisjunction(useRestrictedDisjunction); } } @@ -420,11 +419,11 @@ protected void createRefinementOperatorPool() throws ComponentInitException { startClass, numberOfWorkers + 1, maxNoOfSplits); } - refinementOperatorPool.getFactory().setUseDisjunction(false); refinementOperatorPool.getFactory().setUseNegation(useNegation); refinementOperatorPool.getFactory().setUseHasValue(useHasValue); refinementOperatorPool.getFactory().setUseHasData(useHasData); refinementOperatorPool.getFactory().setCardinalityLimit(cardinalityLimit); + refinementOperatorPool.getFactory().setUseRestrictedDisjunction(useRestrictedDisjunction); refinementOperatorPool.getFactory().setUseCardinalityRestrictions(useCardinalityRestrictions); } else { ParCELRefinementOperatorFactory opFactory; @@ -733,6 +732,14 @@ public int getCardinalityLimit() { return this.cardinalityLimit; } + public boolean isUseRestrictedDisjunction() { + return useRestrictedDisjunction; + } + + public void setUseRestrictedDisjunction(boolean useRestrictedDisjunction) { + this.useRestrictedDisjunction = useRestrictedDisjunction; + } + public void setOperator(RefinementOperator refinementOp) { this.operator = refinementOp; } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java index 246cdf26cd..b1b1b8e4fc 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELRefinementOperatorFactory.java @@ -35,7 +35,7 @@ public class ParCELRefinementOperatorFactory extends BasePooledObjectFactory refine(OWLClassExpression description, int maxLen if(description instanceof OWLObjectMaxCardinality) { // rule 1: <= x r.C => <= x r.D if(useNegation || cardinality > 0){ - if (refineMaxCardinalityRestrictionsUpwards) { - tmp = refine(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); - } else { - tmp = refineUpwards(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); + boolean useDisjunctionBackup = useDisjunction; + if (!useDisjunction && useRestrictedDisjunction) { + useDisjunction = true; } - for(OWLClassExpression d : tmp) { - refinements.add(df.getOWLObjectMaxCardinality(cardinality,role,d)); + try { + if (refineMaxCardinalityRestrictionsUpwards) { + tmp = refine(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); + } else { + tmp = refineUpwards(filler, maxLength - lengthMetric.objectCardinalityLength - lengthMetric.objectProperyLength, null, range); + } + + useDisjunction = useDisjunctionBackup; + + for(OWLClassExpression d : tmp) { + refinements.add(df.getOWLObjectMaxCardinality(cardinality,role,d)); + } + } catch (Throwable t) { + useDisjunction = useDisjunctionBackup; } } @@ -726,10 +741,21 @@ public Set refine(OWLClassExpression description, int maxLen } } else if(description instanceof OWLObjectMinCardinality) { - tmp = refine(filler, maxLength-lengthMetric.objectCardinalityLength-lengthMetric.objectProperyLength, null, range); + boolean useDisjunctionBackup = useDisjunction; + if (!useDisjunction && useRestrictedDisjunction) { + useDisjunction = true; + } + + try { + tmp = refine(filler, maxLength-lengthMetric.objectCardinalityLength-lengthMetric.objectProperyLength, null, range); + + useDisjunction = useDisjunctionBackup; - for(OWLClassExpression d : tmp) { - refinements.add(df.getOWLObjectMinCardinality(cardinality,role,d)); + for(OWLClassExpression d : tmp) { + refinements.add(df.getOWLObjectMinCardinality(cardinality,role,d)); + } + } catch (Throwable t) { + useDisjunction = useDisjunctionBackup; } // >= x r.C => >= (x+1) r.C @@ -1098,10 +1124,21 @@ private Set refine(OWLObjectAllValuesFrom ce, int maxLength) OWLClassExpression range = role.isAnonymous() ? opDomains.get(role.getNamedProperty()) : opRanges.get(role.asOWLObjectProperty()); // rule 1: ALL r.D => ALL r.E - Set tmp = refine(filler, maxLength-lengthMetric.objectAllValuesLength-lengthMetric.objectProperyLength, null, range); + boolean useDisjunctionBackup = useDisjunction; + if (!useDisjunction && useRestrictedDisjunction) { + useDisjunction = true; + } + + try { + Set tmp = refine(filler, maxLength-lengthMetric.objectAllValuesLength-lengthMetric.objectProperyLength, null, range); + + useDisjunction = useDisjunctionBackup; - for(OWLClassExpression c : tmp) { - refinements.add(df.getOWLObjectAllValuesFrom(role, c)); + for(OWLClassExpression c : tmp) { + refinements.add(df.getOWLObjectAllValuesFrom(role, c)); + } + } catch (Throwable t) { + useDisjunction = useDisjunctionBackup; } // rule 2 UPDATED: ALL r.TOP => ALL r.BOTTOM @@ -2102,6 +2139,14 @@ public boolean isUseDisjunction() { return useDisjunction; } + public boolean isUseRestrictedDisjunction() { + return useRestrictedDisjunction; + } + + public void setUseRestrictedDisjunction(boolean useRestrictedDisjunction) { + this.useRestrictedDisjunction = useRestrictedDisjunction; + } + public boolean isUseBooleanDatatypes() { return useBooleanDatatypes; } From 6dcf0c73c884a45ad030aca84b980902cceb7047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Wed, 8 Mar 2023 13:41:29 +0100 Subject: [PATCH 50/67] custom numericValuesSplitter supported --- .../main/java/org/dllearner/refinementoperators/RhoDRDown.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 0cd2d74a56..fa47989e16 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -155,12 +155,13 @@ public class RhoDRDown private Map> mgsd = new TreeMap<>(); // numeric values splitter + @ConfigOption(description = "the splitter to use for computing split intervals for numeric types", defaultValue = "DefaultNumericValuesSplitter") private ValuesSplitter numericValuesSplitter; // splits for double datatype properties in ascending order private Map> splits; - @ConfigOption(description = "the number of generated split intervals for numeric types", defaultValue = "12") + @ConfigOption(description = "the number of generated split intervals for numeric types, applies only to default splitter", defaultValue = "12") private int maxNrOfSplits = 12; // data structure for a simple frequent pattern matching preprocessing phase From ad0bef2b4214a79da4cc07b05f5edd481a4b24f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Thu, 9 Mar 2023 06:38:26 +0100 Subject: [PATCH 51/67] isSomeOnlySatisfied considers min restrictions --- .../java/org/dllearner/refinementoperators/RhoDRDown.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index fa47989e16..baf9b3dd0b 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -923,7 +923,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if ((!useSomeOnly || isSomeOnlySatisfied(mc)) && checkIntersection(mc)) + if ((!useSomeOnly || isSomeOnlySatisfied(mc, 2)) && checkIntersection(mc)) refinements.add(mc); } } @@ -1052,8 +1052,10 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description, Set someValuesProperties = ((OWLObjectIntersectionOf) description).getOperands() - .stream().filter(op -> op instanceof OWLObjectSomeValuesFrom) - .map(op -> ((OWLObjectSomeValuesFrom) op).getProperty()) + .stream().filter(op -> + op instanceof OWLObjectSomeValuesFrom + || (op instanceof OWLObjectMinCardinality && ((OWLObjectMinCardinality) op).getCardinality() > 0)) + .map(op -> ((OWLObjectRestriction) op).getProperty()) .collect(Collectors.toSet()); return ((OWLObjectIntersectionOf) description).getOperands() From 654809d6b166628dbf8d898b1155a6e7eb2dfa10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Thu, 9 Mar 2023 11:13:26 +0100 Subject: [PATCH 52/67] CELOE accuracy speedup reverted --- .../org/dllearner/algorithms/celoe/CELOE.java | 90 +++++-------------- 1 file changed, 21 insertions(+), 69 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index 00b01fa74c..902168dc3b 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -567,29 +567,35 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { logger.trace(sparql_debug, sparql_debug_out + "NOT ALLOWED"); return false; } - - OENode node = createNode(parentNode, description); - + + // quality of class expression (return if too weak) + Monitor mon = MonitorFactory.start("lp"); + logger.trace(sparql_debug, sparql_debug_out); + double accuracy = learningProblem.getAccuracyOrTooWeak(description, noise); + logger.trace(sparql_debug, "`acc:"+accuracy); + mon.stop(); + // issue a warning if accuracy is not between 0 and 1 or -1 (too weak) - if(node.getAccuracy() > 1.0 || (node.getAccuracy() < 0.0 && node.getAccuracy() != -1)) { - throw new RuntimeException("Invalid accuracy value " + node.getAccuracy() + " for class expression " + description + + if(accuracy > 1.0 || (accuracy < 0.0 && accuracy != -1)) { + throw new RuntimeException("Invalid accuracy value " + accuracy + " for class expression " + description + ". This could be caused by a bug in the heuristic measure and should be reported to the DL-Learner bug tracker."); } expressionTests++; // return FALSE if 'too weak' - if(node.getAccuracy() == -1) { + if(accuracy == -1) { return false; } + OENode node = new OENode(description, accuracy); searchTree.addNode(parentNode, node); // in some cases (e.g. mutation) fully evaluating even a single class expression is too expensive // due to the high number of examples -- so we just stick to the approximate accuracy if(singleSuggestionMode) { - if(node.getAccuracy() > bestAccuracy) { - bestAccuracy = node.getAccuracy(); + if(accuracy > bestAccuracy) { + bestAccuracy = accuracy; bestDescription = description; logger.info("more accurate (" + dfPercent.format(bestAccuracy) + ") class expression found: " + descriptionToString(bestDescription)); // + getTemporaryString(bestDescription)); } @@ -604,8 +610,8 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { EvaluatedDescription worst = bestEvaluatedDescriptions.getWorst(); double accThreshold = worst.getAccuracy(); isCandidate = - (node.getAccuracy() > accThreshold || - (node.getAccuracy() >= accThreshold && OWLClassExpressionUtils.getLength(description) < worst.getDescriptionLength())); + (accuracy > accThreshold || + (accuracy >= accThreshold && OWLClassExpressionUtils.getLength(description) < worst.getDescriptionLength())); } if(isCandidate) { @@ -626,7 +632,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { boolean shorterDescriptionExists = false; if(forceMutualDifference) { for(EvaluatedDescription ed : bestEvaluatedDescriptions.getSet()) { - if(Math.abs(ed.getAccuracy()-node.getAccuracy()) <= 0.00001 && ConceptTransformation.isSubdescription(niceDescription, ed.getDescription())) { + if(Math.abs(ed.getAccuracy()-accuracy) <= 0.00001 && ConceptTransformation.isSubdescription(niceDescription, ed.getDescription())) { // System.out.println("shorter: " + ed.getDescription()); shorterDescriptionExists = true; break; @@ -639,16 +645,7 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { if(!shorterDescriptionExists) { if(!filterFollowsFromKB || !((ClassLearningProblem)learningProblem).followsFromKB(niceDescription)) { // System.out.println(node + "->" + niceDescription); - - if (learningProblem instanceof PosNegLPStandard) { - EvaluatedDescription ed = ((PosNegLPStandard) learningProblem).constructEvaluatedDescription( - niceDescription, node.getCoveredPositiveExamples(), node.getCoveredNegativeExamples(), node.getAccuracy() - ); - bestEvaluatedDescriptions.add(ed); - } else { - bestEvaluatedDescriptions.add(niceDescription, node.getAccuracy(), learningProblem); - } - + bestEvaluatedDescriptions.add(niceDescription, accuracy, learningProblem); // System.out.println("acc: " + accuracy); // System.out.println(bestEvaluatedDescriptions); } @@ -659,11 +656,11 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { // System.out.println(bestEvaluatedDescriptions.getSet().size()); } - if (node.getAccuracy() >= 1 - noiseWithMargin) { + if (accuracy >= 1 - noiseWithMargin) { if (solutionCandidates.isEmpty() - || (node.getAccuracy() > solutionCandidates.firstKey().getAccuracy() + || (accuracy > solutionCandidates.firstKey().getAccuracy() && solutionCandidates.keySet().stream().allMatch( - n -> Math.abs(node.getAccuracy() - n.getAccuracy()) > solutionCandidatesMinAccuracyDiff + n -> Math.abs(accuracy - n.getAccuracy()) > solutionCandidatesMinAccuracyDiff ) ) ) { @@ -677,51 +674,6 @@ private boolean addNode(OWLClassExpression description, OENode parentNode) { return true; } - - private OENode createNode(OENode parent, OWLClassExpression refinement) { - if (!(learningProblem instanceof PosNegLPStandard)) { - Monitor mon = MonitorFactory.start("lp"); - double accuracy = learningProblem.getAccuracyOrTooWeak(refinement, noise); - mon.stop(); - - return new OENode(refinement, accuracy); - } - - PosNegLPStandard posNegLP = (PosNegLPStandard) learningProblem; - - Set coveredPositives; - Set coveredNegatives; - - Monitor mon = MonitorFactory.start("lp"); - - if (parent == null) { - coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); - } else if (operator instanceof DownwardRefinementOperator) { - coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); - } else { - Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); - uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); - Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); - uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); - - coveredPositives = reasoner.hasType(refinement, uncoveredPositives); - coveredPositives.addAll(parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); - coveredNegatives.addAll(parent.getCoveredNegativeExamples()); - } - - double accuracy = posNegLP.getAccuracyOrTooWeak(coveredPositives, coveredNegatives, noise); - - mon.stop(); - - OENode node = new OENode(refinement, accuracy); - node.setCoveredPositiveExamples(coveredPositives); - node.setCoveredNegativeExamples(coveredNegatives); - - return node; - } // checks whether the class expression is allowed private boolean isDescriptionAllowed(OWLClassExpression description, OENode parentNode) { From 0a9e377449ea2b4c0b05dbc4d2047fdeeacc456f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Thu, 9 Mar 2023 16:13:35 +0100 Subject: [PATCH 53/67] OSBean for measuring CPU time declared as a class property --- .../src/main/java/org/dllearner/core/AbstractCELA.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java index d7f5668a09..766e397c65 100644 --- a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java +++ b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java @@ -135,6 +135,8 @@ public abstract class AbstractCELA extends AbstractComponent implements ClassExp private List bestConceptsTrainingAccuracies = new ArrayList<>(); private List bestConceptsTestAccuracies = new ArrayList<>(); + private final OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + /** * Default Constructor */ @@ -500,8 +502,7 @@ protected DatatypePropertyHierarchy initDataPropertyHierarchy() { // beware that this includes the setup time as well protected long getCurrentCpuMillis() { - OperatingSystemMXBean bean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); - return bean.getProcessCpuTime() / 1_000_000; + return osBean.getProcessCpuTime() / 1_000_000; } protected boolean isTimeExpired() { From e85e0bf251873072078b1067504414b58f69bd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 11 Mar 2023 17:28:43 +0100 Subject: [PATCH 54/67] accuracy synchronization, parcel discarding unpromising concepts, and compacted coverage representation --- .../dllearner/algorithms/celoe/OENode.java | 85 +++++++++++++++++-- .../algorithms/parcel/ParCELAbstract.java | 67 ++++++++++----- .../algorithms/parcel/ParCELNode.java | 12 +++ .../algorithms/parcel/ParCELPosNegLP.java | 43 +++++++++- .../algorithms/parcel/ParCELWorker.java | 8 ++ .../algorithms/parcel/ParCELearner.java | 18 ++++ .../algorithms/parcelex/ParCELExAbstract.java | 14 +++ .../parcelex/ParCELearnerExV12.java | 5 -- .../algorithms/parcelex/ParCELearnerExV2.java | 3 - .../dllearner/cli/ExpressionValidation.java | 28 ++++-- 10 files changed, 238 insertions(+), 45 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java index bab752f857..074d0c5224 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java @@ -18,7 +18,10 @@ */ package org.dllearner.algorithms.celoe; +import org.dllearner.algorithms.parcel.ParCELPosNegLP; import org.dllearner.core.AbstractSearchTreeNode; +import org.dllearner.core.LearningProblem; +import org.dllearner.learningproblems.PosNegLP; import org.dllearner.utilities.datastructures.SearchTreeNode; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionUtils; @@ -26,9 +29,9 @@ import org.semanticweb.owlapi.model.OWLIndividual; import java.text.DecimalFormat; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; /** * A node in the search tree of the ontology engineering algorithm. @@ -58,9 +61,17 @@ public class OENode extends AbstractSearchTreeNode implements SearchTree // (and avoids the problem that adding children changes the heuristic value) private int refinementCount = 0; - private Set coveredPositiveExamples = new TreeSet<>(); - private Set coveredNegativeExamples = new TreeSet<>(); - + private static boolean useCompactedCoverage = false; + + private static OWLIndividual[] allPositiveExamplesSorted; + private static OWLIndividual[] allNegativeExamplesSorted; + + private Boolean[] compactedCoveredPositiveExamples; + private Boolean[] compactedCoveredNegativeExamples; + + private final Set coveredPositiveExamples = new TreeSet<>(); + private final Set coveredNegativeExamples = new TreeSet<>(); + private static DecimalFormat dfPercent = new DecimalFormat("0.00%"); public OENode(OWLClassExpression description, double accuracy) { @@ -143,14 +154,41 @@ public void setRefinementCount(int refinementCount) { } public Set getCoveredPositiveExamples() { + if (useCompactedCoverage) { + return getCompactedCoveredPositiveExamples(); + } + return coveredPositiveExamples; } + private Set getCompactedCoveredPositiveExamples() { + return IntStream.range(0, allPositiveExamplesSorted.length) + .mapToObj(i -> compactedCoveredPositiveExamples[i] ? allPositiveExamplesSorted[i] : null) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + public Set getCoveredNegativeExamples() { + if (useCompactedCoverage) { + return getCompactedCoveredNegativeExamples(); + } + return coveredNegativeExamples; } + private Set getCompactedCoveredNegativeExamples() { + return IntStream.range(0, allNegativeExamplesSorted.length) + .mapToObj(i -> compactedCoveredNegativeExamples[i] ? allNegativeExamplesSorted[i] : null) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + public void setCoveredPositiveExamples(Set coveredPositiveExamples) { + if (useCompactedCoverage) { + setCompactedCoveredPositiveExamples(coveredPositiveExamples); + return; + } + this.coveredPositiveExamples.clear(); if (coveredPositiveExamples != null) { @@ -158,11 +196,46 @@ public void setCoveredPositiveExamples(Set coveredPositiveExample } } + private void setCompactedCoveredPositiveExamples(Set coveredPositiveExamples) { + compactedCoveredPositiveExamples = Arrays.stream(allPositiveExamplesSorted) + .map(coveredPositiveExamples::contains) + .toArray(Boolean[]::new); + } + public void setCoveredNegativeExamples(Set coveredNegativeExamples) { + if (useCompactedCoverage) { + setCompactedCoveredNegativeExamples(coveredNegativeExamples); + return; + } + this.coveredNegativeExamples.clear(); if (coveredNegativeExamples != null) { this.coveredNegativeExamples.addAll(coveredNegativeExamples); } } + + private void setCompactedCoveredNegativeExamples(Set coveredNegativeExamples) { + compactedCoveredNegativeExamples = Arrays.stream(allNegativeExamplesSorted) + .map(coveredNegativeExamples::contains) + .toArray(Boolean[]::new); + } + + public static void enableCompactCoverageRepresentation(LearningProblem learningProblem) { + if (!(learningProblem instanceof PosNegLP)) { + throw new UnsupportedOperationException("Compacted coverage representation is only supported for PosNegLP learning problems."); + } + + Set positives = ((PosNegLP) learningProblem).getPositiveExamples(); + Set negatives = ((PosNegLP) learningProblem).getNegativeExamples(); + + enableCompactCoverageRepresentation(positives, negatives); + } + + protected static void enableCompactCoverageRepresentation(Set allPositiveExamples, Set allNegativeExamples) { + allPositiveExamplesSorted = allPositiveExamples.stream().sorted().toArray(OWLIndividual[]::new); + allNegativeExamplesSorted = allNegativeExamples.stream().sorted().toArray(OWLIndividual[]::new); + + useCompactedCoverage = true; + } } \ No newline at end of file diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 9ec1a7e511..5099433b9c 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -1,5 +1,6 @@ package org.dllearner.algorithms.parcel; +import com.google.common.collect.Sets; import org.apache.log4j.Logger; import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.reducer.ParCELImprovedCoverageGreedyReducer; @@ -257,6 +258,8 @@ protected void initOperatorIfAny() { protected void initSearchTree() { // TODO: only ParCELPosNegLP supported + ParCELNode.enableCompactCoverageRepresentation(learningProblem); + // create a start node in the search tree allDescriptions.add(startClass); @@ -324,9 +327,6 @@ public void newPartialDefinitionsFound(Set definitions) { // for used in bean (for tracing purpose) this.noOfUncoveredPositiveExamples -= uncoveredPositiveExamplesRemoved; - ((ParCELPosNegLP) this.learningProblem) - .setUncoveredPositiveExamples(uncoveredPositiveExamples); - if (logger.isTraceEnabled() || logger.isDebugEnabled()) { logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) @@ -461,30 +461,53 @@ protected void createWorkerPool() { } public ParCELEvaluationResult getAccuracyAndCorrectness(OENode parent, OWLClassExpression refinement) { + if (parent == null) { + return getAccuracyAndCorrectnessRoot(refinement); + } + + if (refinementOperatorPool.getFactory().getOperatorPrototype() instanceof DownwardRefinementOperator) { + return getAccuracyAndCorrectnessDownward(parent, refinement); + } + + return getAccuracyAndCorrectnessUpward(parent, refinement); + } + + protected ParCELEvaluationResult getAccuracyAndCorrectnessRoot(OWLClassExpression refinement) { // TODO: only ParCELPosNegLP supported ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; - Set coveredPositives; - Set coveredNegatives; + Set potentiallyCoveredPositives = posNegLP.getPositiveExamples(); + Set potentiallyCoveredNegatives = posNegLP.getNegativeExamples(); - if (parent == null) { - coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); - } else if (refinementOperatorPool.getFactory().getOperatorPrototype() instanceof DownwardRefinementOperator) { - coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); - } else { - Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); - uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); - Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); - uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); - - coveredPositives = reasoner.hasType(refinement, uncoveredPositives); - coveredPositives.addAll(parent.getCoveredPositiveExamples()); - coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); - coveredNegatives.addAll(parent.getCoveredNegativeExamples()); - } + return posNegLP.getAccuracyAndCorrectness5(refinement, potentiallyCoveredPositives, potentiallyCoveredNegatives); + } + + protected ParCELEvaluationResult getAccuracyAndCorrectnessDownward(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set potentiallyCoveredPositives = parent.getCoveredPositiveExamples(); + Set potentiallyCoveredNegatives = parent.getCoveredNegativeExamples(); + + return posNegLP.getAccuracyAndCorrectness5(refinement, potentiallyCoveredPositives, potentiallyCoveredNegatives); + } + + protected ParCELEvaluationResult getAccuracyAndCorrectnessUpward(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); + uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); + Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); + uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); + + Set coveredPositives = reasoner.hasType(refinement, uncoveredPositives); + coveredPositives.addAll(parent.getCoveredPositiveExamples()); + Set coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); + coveredNegatives.addAll(parent.getCoveredNegativeExamples()); return posNegLP.getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java index 7542c2a482..a52b007f1a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELNode.java @@ -5,6 +5,8 @@ import java.util.Set; import org.dllearner.algorithms.celoe.OENode; +import org.dllearner.core.LearningProblem; +import org.dllearner.learningproblems.PosNegLP; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLIndividual; @@ -77,4 +79,14 @@ public void setDescription(OWLClassExpression newDescription) { this.description = newDescription; } + public static void enableCompactCoverageRepresentation(LearningProblem learningProblem) { + if (!(learningProblem instanceof ParCELPosNegLP)) { + throw new UnsupportedOperationException("Compacted coverage representation is only supported for ParCELPosNegLP learning problems."); + } + + Set positives = ((ParCELPosNegLP) learningProblem).getPositiveExamples(); + Set negatives = ((ParCELPosNegLP) learningProblem).getNegativeExamples(); + + enableCompactCoverageRepresentation(positives, negatives); + } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java index 311bfc90da..beef12fb3d 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -444,7 +444,7 @@ public ParCELEvaluationResult getAccuracyAndCorrectness3(OWLClassExpression desc double correctness = (double) notCoveredNeg / (double) negativeExamples.size(); double completeness = (double) coveredPositiveExamples.size() - / uncoveredPositiveExamples.size(); + / localUncoveredPositiveExamples.size(); // double accuracy = (positiveExamples.size() - notCoveredPos + // notCoveredNeg)/(double)(positiveExamples.size() + negativeExamples.size()); @@ -494,6 +494,43 @@ public ParCELEvaluationResult getAccuracyAndCorrectness4(Set cove return result; } + public ParCELEvaluationResult getAccuracyAndCorrectness5( + OWLClassExpression description, + Set potentiallyCoveredPositiveExamples, Set potentiallyCoveredNegativeExamples + ) { + Set uncoveredPositives; + + if (uncoveredPositiveExamples != null) { + synchronized (uncoveredPositiveExamples) { + uncoveredPositives = new HashSet<>(uncoveredPositiveExamples); + } + } else { + uncoveredPositives = new HashSet<>(positiveExamples); + } + + Set potentiallyCoveredUncoveredPositives = new HashSet<>(); + Set potentiallyCoveredCoveredPositives = new HashSet<>(); + + for (OWLIndividual ex : potentiallyCoveredPositiveExamples) { + if (uncoveredPositives.contains(ex)) { + potentiallyCoveredUncoveredPositives.add(ex); + } else { + potentiallyCoveredCoveredPositives.add(ex); + } + } + + Set coveredPositives = reasoner.hasType(description, potentiallyCoveredUncoveredPositives); + + if (coveredPositives.isEmpty()) { + return new ParCELEvaluationResult(-1, 0, 0); + } + + coveredPositives.addAll(reasoner.hasType(description, potentiallyCoveredCoveredPositives)); + Set coveredNegatives = reasoner.hasType(description, potentiallyCoveredNegativeExamples); + + return getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + } + /** * Accuracy calculation for the exception learning which provide both covered positive and * negative examples by the description
@@ -621,7 +658,9 @@ public void setNegativeExamples(Set negativeExamples) { } public void setUncoveredPositiveExamples(Set uncoveredPositiveExamples) { - this.uncoveredPositiveExamples = uncoveredPositiveExamples; + if (this.uncoveredPositiveExamples == null) { + this.uncoveredPositiveExamples = uncoveredPositiveExamples; + } } public void setPositiveTestExamples(Set positiveTestExamples) { diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index c609867a58..67e543f65b 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -1,12 +1,14 @@ package org.dllearner.algorithms.parcel; import java.util.HashSet; +import java.util.Set; import java.util.TreeSet; import org.dllearner.refinementoperators.RefinementOperator; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.mindswap.pellet.exceptions.InternalReasonerException; import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; /** * ParCEL worker which find and evaluate the refinements for a given node. @@ -61,6 +63,12 @@ public void run() { + ParCELStringUtilities.replaceString(nodeToProcess.toString(), this.baseURI, this.prefix)); + if (!learner.canIncreaseCoverage(nodeToProcess)) { + // we can safely remove the node from the tree, since it is no longer valuable + // TODO: check that it is sufficient to remove it from the parent's children + nodeToProcess.getParent().getChildren().remove(nodeToProcess); + return; + } HashSet definitionsFound = new HashSet<>(); // hold the // partial diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index fede0cbcfb..57c33e8507 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -18,6 +18,7 @@ import org.dllearner.core.AbstractReasonerComponent; import org.dllearner.core.ComponentAnn; import org.dllearner.core.ComponentInitException; +import org.dllearner.refinementoperators.DownwardRefinementOperator; import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.semanticweb.owlapi.model.OWLClassExpression; @@ -319,6 +320,23 @@ private void createNewTask(ParCELNode nodeToProcess) { (ParCELPosNegLP) learningProblem, nodeToProcess, "ParCELTask-" + (noOfTask++))); } + /** + * Determines whether the refinements of the description represented by a given node can cover any uncovered positive + * examples. + * + * @param nodeToProcess the node to investigate + * @return true if an increase is possible, false otherwise + */ + protected boolean canIncreaseCoverage(ParCELNode nodeToProcess) { + if (refinementOperatorPool.getFactory().getOperatorPrototype() instanceof DownwardRefinementOperator) { + synchronized (uncoveredPositiveExamples) { + return nodeToProcess.getCoveredPositiveExamples().stream().anyMatch(uncoveredPositiveExamples::contains); + } + } else { + return true; + } + } + /** * ============================================================================================ * Get the overall completeness of all partial definition found diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java index 9cd2e1aa17..408e18f612 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java @@ -5,10 +5,13 @@ import java.util.Set; import java.util.SortedSet; import org.apache.log4j.Logger; +import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.ParCELAbstract; +import org.dllearner.algorithms.parcel.ParCELEvaluationResult; import org.dllearner.algorithms.parcel.ParCELExtraNode; import org.dllearner.algorithms.parcel.ParCELPosNegLP; import org.dllearner.core.AbstractReasonerComponent; +import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLIndividual; /** @@ -183,4 +186,15 @@ protected boolean isTerminateCriteriaSatisfied() { timeout; } + @Override + protected ParCELEvaluationResult getAccuracyAndCorrectnessDownward(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); + Set coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); + + return posNegLP.getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index 139e867036..9899e362fd 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -111,8 +111,6 @@ public void init() throws ComponentInitException { positiveTestExamples = ((ParCELPosNegLP) learningProblem).getPositiveTestExamples(); negativeTestExamples = ((ParCELPosNegLP) learningProblem).getNegativeTestExamples(); - ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(this.positiveExamples); - //initial heuristic which will be used by reducer to sort the search tree (expansion strategy) //the heuristic need to get some constant from the configurator for scoring the description if (heuristic == null) { @@ -492,9 +490,6 @@ public void newPartialDefinitionsFound(Set definitions) { partialDefinitions.add(def); } - //update the uncovered positive examples for the learning problem - ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); - if (logger.isTraceEnabled()) { logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java index fc5da0ad15..7c9fdf5f41 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java @@ -400,9 +400,6 @@ public void newPartialDefinitionsFound(Set definitions) { partialDefinitions.add(def); } - //update the uncovered positive examples for the learning problem - ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); - if (logger.isTraceEnabled()) { logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + diff --git a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java index 2c891c9007..287502b0e7 100644 --- a/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java +++ b/interfaces/src/main/java/org/dllearner/cli/ExpressionValidation.java @@ -127,23 +127,37 @@ public void run() { // ) // ) // ) +// ); + +// expression = dataFactory.getOWLObjectIntersectionOf( +// dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#ExecutableFile")), +// dataFactory.getOWLObjectSomeValuesFrom( +// dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), +// dataFactory.getOWLObjectIntersectionOf( +// dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), +// dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#UninitializedDataSection")) +// ) +// ) // ); expression = dataFactory.getOWLObjectIntersectionOf( - dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#ExecutableFile")), dataFactory.getOWLObjectSomeValuesFrom( - dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_section")), - dataFactory.getOWLObjectIntersectionOf( - dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#CodeSection")), - dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#UninitializedDataSection")) + dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_file_feature")), + dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#MultipleExecutableSections")) + ), + dataFactory.getOWLObjectMaxCardinality( + 1, + dataFactory.getOWLObjectProperty(IRI.create("https://orbis-security.com/pe-malware-ontology#has_file_feature")), + dataFactory.getOWLObjectComplementOf( + dataFactory.getOWLClass(IRI.create("https://orbis-security.com/pe-malware-ontology#Resources")) ) ) ); logger.info("#EVAL# expression: " + expression); - Set pos = ((ParCELPosNegLP) lp).getPositiveTestExamples(); - Set neg = ((ParCELPosNegLP) lp).getNegativeTestExamples(); + Set pos = ((ParCELPosNegLP) lp).getPositiveExamples(); + Set neg = ((ParCELPosNegLP) lp).getNegativeExamples(); int tp = rs.hasType(expression, pos).size(); int fp = rs.hasType(expression, neg).size(); From ce8f5002b249b806b259381c0adfec03bc66755c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sat, 11 Mar 2023 18:24:07 +0100 Subject: [PATCH 55/67] parcelex accuracy calculation without additional checks --- .../algorithms/parcel/ParCELAbstract.java | 59 ++++++++++++------- .../algorithms/parcel/ParCELPosNegLP.java | 30 +++------- .../algorithms/parcelex/ParCELExAbstract.java | 32 ++++++++-- 3 files changed, 74 insertions(+), 47 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index 5099433b9c..b2b3650bde 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -263,19 +263,15 @@ protected void initSearchTree() { // create a start node in the search tree allDescriptions.add(startClass); - Set coveredPositives = reasoner.hasType(startClass, positiveExamples); - Set coveredNegatives = reasoner.hasType(startClass, negativeExamples); - - ParCELEvaluationResult accAndCorr = ((ParCELPosNegLP) learningProblem) - .getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + ParCELEvaluationResult accAndCorr = getAccuracyAndCorrectness(null, startClass); ParCELNode startNode = new ParCELNode( null, startClass, accAndCorr.accuracy, accAndCorr.correctness, accAndCorr.completeness ); - startNode.setCoveredPositiveExamples(coveredPositives); - startNode.setCoveredNegativeExamples(coveredNegatives); + startNode.setCoveredPositiveExamples(accAndCorr.coveredPositiveExamples); + startNode.setCoveredNegativeExamples(accAndCorr.coveredNegativeExamples); searchTree.add(startNode); } @@ -480,18 +476,20 @@ protected ParCELEvaluationResult getAccuracyAndCorrectnessRoot(OWLClassExpressio Set potentiallyCoveredPositives = posNegLP.getPositiveExamples(); Set potentiallyCoveredNegatives = posNegLP.getNegativeExamples(); - return posNegLP.getAccuracyAndCorrectness5(refinement, potentiallyCoveredPositives, potentiallyCoveredNegatives); + return posNegLP.getAccuracyAndCorrectness5( + refinement, potentiallyCoveredPositives, potentiallyCoveredNegatives + ); } protected ParCELEvaluationResult getAccuracyAndCorrectnessDownward(OENode parent, OWLClassExpression refinement) { // TODO: only ParCELPosNegLP supported - ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; - Set potentiallyCoveredPositives = parent.getCoveredPositiveExamples(); Set potentiallyCoveredNegatives = parent.getCoveredNegativeExamples(); - return posNegLP.getAccuracyAndCorrectness5(refinement, potentiallyCoveredPositives, potentiallyCoveredNegatives); + return ((ParCELPosNegLP) learningProblem).getAccuracyAndCorrectness5( + refinement, potentiallyCoveredPositives, potentiallyCoveredNegatives + ); } protected ParCELEvaluationResult getAccuracyAndCorrectnessUpward(OENode parent, OWLClassExpression refinement) { @@ -499,19 +497,40 @@ protected ParCELEvaluationResult getAccuracyAndCorrectnessUpward(OENode parent, ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; - Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); - uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); - Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); - uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); - - Set coveredPositives = reasoner.hasType(refinement, uncoveredPositives); - coveredPositives.addAll(parent.getCoveredPositiveExamples()); - Set coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); - coveredNegatives.addAll(parent.getCoveredNegativeExamples()); + Set coveredPositives = getCoveredPositiveExamplesUpward(parent, refinement); + Set coveredNegatives = getCoveredNegativeExamplesUpward(parent, refinement); return posNegLP.getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); } + protected Set getCoveredPositiveExamplesUpward(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set uncoveredPositives = new TreeSet<>(posNegLP.getPositiveExamples()); + uncoveredPositives.removeAll(parent.getCoveredPositiveExamples()); + + Set coveredPositives = reasoner.hasType(refinement, uncoveredPositives); + coveredPositives.addAll(parent.getCoveredPositiveExamples()); + + return coveredPositives; + } + + protected Set getCoveredNegativeExamplesUpward(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set uncoveredNegatives = new TreeSet<>(posNegLP.getNegativeExamples()); + uncoveredNegatives.removeAll(parent.getCoveredNegativeExamples()); + + Set coveredNegatives = reasoner.hasType(refinement, uncoveredNegatives); + coveredNegatives.addAll(parent.getCoveredNegativeExamples()); + + return coveredNegatives; + } + /** * Get the union of all the best (reduced) partial definitions * diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java index beef12fb3d..0e53845c1e 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -479,19 +479,7 @@ public ParCELEvaluationResult getAccuracyAndCorrectness4(Set cove return new ParCELEvaluationResult(-1, 0, 0); } - ParCELEvaluationResult result = new ParCELEvaluationResult(); - - int cp = coveredPositiveExamples.size(); - int un = negativeExamples.size() - coveredNegativeExamples.size(); - - result.accuracy = (cp + un) / (double) (positiveExamples.size() + negativeExamples.size()); - result.correctness = un / (double) negativeExamples.size(); - result.completeness = cp / (double) positiveExamples.size(); - - result.coveredPositiveExamples = coveredPositiveExamples; - result.coveredNegativeExamples = coveredNegativeExamples; - - return result; + return getAccuracyAndCorrectnessNoChecks(coveredPositiveExamples, coveredNegativeExamples); } public ParCELEvaluationResult getAccuracyAndCorrectness5( @@ -553,7 +541,6 @@ public ParCELEvaluationResult getAccuracyAndCorrectness5( * @return */ public ParCELEvaluationResult getAccuracyAndCorrectnessEx(OWLClassExpression description) { - Set coveredPositiveExamples = new HashSet<>(); Set coveredNegativeExamples = new HashSet<>(); @@ -569,24 +556,23 @@ public ParCELEvaluationResult getAccuracyAndCorrectnessEx(OWLClassExpression des coveredNegativeExamples.add(example); } + return getAccuracyAndCorrectnessNoChecks(coveredPositiveExamples, coveredNegativeExamples); + } + + public ParCELEvaluationResult getAccuracyAndCorrectnessNoChecks(Set coveredPositiveExamples, Set coveredNegativeExamples) { ParCELEvaluationResult result = new ParCELEvaluationResult(); int cp = coveredPositiveExamples.size(); int un = negativeExamples.size() - coveredNegativeExamples.size(); - double accuracy = (cp + un) / (double) (positiveExamples.size() + negativeExamples.size()); - result.accuracy = accuracy; + result.accuracy = (cp + un) / (double) (positiveExamples.size() + negativeExamples.size()); result.correctness = un / (double) negativeExamples.size(); result.completeness = cp / (double) positiveExamples.size(); - if (coveredPositiveExamples.size() > 0) - result.coveredPositiveExamples = coveredPositiveExamples; - - if (coveredNegativeExamples.size() > 0) - result.coveredNegativeExamples = coveredNegativeExamples; + result.coveredPositiveExamples = coveredPositiveExamples; + result.coveredNegativeExamples = coveredNegativeExamples; return result; - } public static String getName() { diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java index 408e18f612..55ebf220fd 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java @@ -1,9 +1,7 @@ package org.dllearner.algorithms.parcelex; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.SortedSet; +import java.util.*; + import org.apache.log4j.Logger; import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.ParCELAbstract; @@ -186,6 +184,18 @@ protected boolean isTerminateCriteriaSatisfied() { timeout; } + + protected ParCELEvaluationResult getAccuracyAndCorrectnessRoot(OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set coveredPositives = reasoner.hasType(refinement, posNegLP.getPositiveExamples()); + Set coveredNegatives = reasoner.hasType(refinement, posNegLP.getNegativeExamples()); + + return posNegLP.getAccuracyAndCorrectnessNoChecks(coveredPositives, coveredNegatives); + } + @Override protected ParCELEvaluationResult getAccuracyAndCorrectnessDownward(OENode parent, OWLClassExpression refinement) { // TODO: only ParCELPosNegLP supported @@ -195,6 +205,18 @@ protected ParCELEvaluationResult getAccuracyAndCorrectnessDownward(OENode parent Set coveredPositives = reasoner.hasType(refinement, parent.getCoveredPositiveExamples()); Set coveredNegatives = reasoner.hasType(refinement, parent.getCoveredNegativeExamples()); - return posNegLP.getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); + return posNegLP.getAccuracyAndCorrectnessNoChecks(coveredPositives, coveredNegatives); + } + + @Override + protected ParCELEvaluationResult getAccuracyAndCorrectnessUpward(OENode parent, OWLClassExpression refinement) { + // TODO: only ParCELPosNegLP supported + + ParCELPosNegLP posNegLP = (ParCELPosNegLP) learningProblem; + + Set coveredPositives = getCoveredPositiveExamplesUpward(parent, refinement); + Set coveredNegatives = getCoveredNegativeExamplesUpward(parent, refinement); + + return posNegLP.getAccuracyAndCorrectnessNoChecks(coveredPositives, coveredNegatives); } } From a20ce890c518272fc347ba756e372dcbdcafe134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 12 Mar 2023 08:58:43 +0100 Subject: [PATCH 56/67] test accuracy computation moved to PosNegLPStandard --- .../main/java/org/dllearner/core/AbstractCELA.java | 5 +++-- .../org/dllearner/learningproblems/PosNegLP.java | 13 ------------- .../learningproblems/PosNegLPStandard.java | 9 ++------- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java index 766e397c65..6e535bb024 100644 --- a/components-core/src/main/java/org/dllearner/core/AbstractCELA.java +++ b/components-core/src/main/java/org/dllearner/core/AbstractCELA.java @@ -28,6 +28,7 @@ import org.dllearner.accuracymethods.AccMethodPredAcc; import org.dllearner.accuracymethods.AccMethodTwoValued; import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.learningproblems.PosNegLPStandard; import org.dllearner.utilities.Helper; import org.dllearner.utilities.ReasoningUtils; import org.dllearner.utilities.datastructures.DescriptionSubsumptionTree; @@ -392,8 +393,8 @@ protected String getSolutionString() { } protected double computeTestAccuracy(OWLClassExpression description) { - if (learningProblem instanceof PosNegLP) { - return ((PosNegLP) learningProblem).getTestAccuracyOrTooWeak(description, 1); + if (learningProblem instanceof PosNegLPStandard) { + return ((PosNegLPStandard) learningProblem).getTestAccuracyOrTooWeak(description, 1); } return 0.0; diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java index 9176b40763..2850ac0b7e 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLP.java @@ -142,10 +142,6 @@ public void init() throws ComponentInitException { initialized = true; } - public double getTestAccuracyOrTooWeak(OWLClassExpression description, double noise) { - return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); - } - public int getCoverage(OWLClassExpression description) { return reasoningUtil.getCoverageCount(description, positiveExamples)[0].trueCount; } @@ -154,15 +150,6 @@ public int getTestCoverage(OWLClassExpression description) { return reasoningUtil.getCoverageCount(description, positiveTestExamples)[0].trueCount; } - public double getAccuracyOrTooWeak(Set coveredPositives, Set coveredNegatives, double noise) { - int tp = coveredPositives.size(); - int fp = coveredNegatives.size(); - int tn = negativeExamples.size() - fp; - int fn = positiveExamples.size() - tp; - - return accuracyMethod.getAccOrTooWeak2(tp, fn, fp, tn, noise); - } - public void printTestEvaluation(OWLClassExpression description) { Set tp = reasoner.hasType(description, positiveTestExamples); Set fn = new TreeSet<>(positiveTestExamples); diff --git a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java index c301974a19..6b7f6924f8 100644 --- a/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java +++ b/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java @@ -110,13 +110,8 @@ public double getAccuracyOrTooWeak(OWLClassExpression description, double noise) return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveExamples, negativeExamples, noise); } - public double getAccuracyOrTooWeak(Set coveredPositives, Set coveredNegatives, double noise) { - int tp = coveredPositives.size(); - int fp = coveredNegatives.size(); - int tn = negativeExamples.size() - fp; - int fn = positiveExamples.size() - tp; - - return accuracyMethod.getAccOrTooWeak2(tp, fn, fp, tn, noise); + public double getTestAccuracyOrTooWeak(OWLClassExpression description, double noise) { + return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveTestExamples, negativeTestExamples, noise); } /* (non-Javadoc) From dd28ff0d366dde8add9b875edad55c85c63f3352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 12 Mar 2023 09:47:57 +0100 Subject: [PATCH 57/67] cwr corrections --- .../dllearner/reasoning/ClosedWorldReasoner.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java index 1909085e01..e2ee966dce 100644 --- a/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java +++ b/components-core/src/main/java/org/dllearner/reasoning/ClosedWorldReasoner.java @@ -565,6 +565,7 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ OWLClassExpression fillerConcept = ((OWLObjectAllValuesFrom) description).getFiller(); // \forall r.\top \equiv \top -> TRUE + // TODO: not true for NoneEmpty and SomeOnly semantics if (fillerConcept.isOWLThing()) { return true; } @@ -588,18 +589,25 @@ public boolean hasTypeImpl(OWLClassExpression description, OWLIndividual individ return forAllSemantics == ForallSemantics.Standard; } + boolean hasCorrectFiller = false; for (OWLIndividual value : values) { - if (!hasTypeImpl(fillerConcept, value)) { + if (hasTypeImpl(fillerConcept, value)) { + hasCorrectFiller = true; + } else { return false; } } - return true; + if (forAllSemantics == ForallSemantics.SomeOnly) { + return hasCorrectFiller; + } else { + return true; + } } else {// \forall r.C SortedSet values = opPos.get(property).get(individual); // if there is no value, by standard semantics we have to return TRUE - if (values == null) { + if (values == null || values.isEmpty()) { return forAllSemantics == ForallSemantics.Standard; } @@ -1104,6 +1112,7 @@ public SortedSet getIndividualsImplFast(OWLClassExpression descri // each individual is connected to a set of individuals via the property; // we loop through the complete mapping + // TODO: SomeOnly and NoneEmpty semantics not taken into account mapping.entrySet().stream() .filter(e -> e.getValue().stream().anyMatch(ind -> !targetSet.contains(ind))) .forEach(e -> returnSet.remove(e.getKey())); From 30840e064322254532706863047a40b611d2d4e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 12 Mar 2023 14:50:31 +0100 Subject: [PATCH 58/67] rho maxCardinalityLimit copied --- .../main/java/org/dllearner/refinementoperators/RhoDRDown.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index baf9b3dd0b..efe91aa54b 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -275,6 +275,7 @@ public RhoDRDown(RhoDRDown op) { setApplyAllFilter(op.applyAllFilter); setApplyExistsFilter(op.applyExistsFilter); setCardinalityLimit(op.cardinalityLimit); + setMaxCardinalityLimit(op.maxCardinalityLimit); setClassHierarchy(op.classHierarchy.clone()); setObjectPropertyHierarchy(op.objectPropertyHierarchy.clone()); setDataPropertyHierarchy(op.dataPropertyHierarchy.clone()); From 99dedd216559e9bb1775fe57cb3692c2f40885e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Sun, 12 Mar 2023 15:34:03 +0100 Subject: [PATCH 59/67] compact coverage representation even leaner --- .../dllearner/algorithms/celoe/OENode.java | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java index 074d0c5224..9d1fb4306e 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java @@ -18,7 +18,6 @@ */ package org.dllearner.algorithms.celoe; -import org.dllearner.algorithms.parcel.ParCELPosNegLP; import org.dllearner.core.AbstractSearchTreeNode; import org.dllearner.core.LearningProblem; import org.dllearner.learningproblems.PosNegLP; @@ -66,8 +65,8 @@ public class OENode extends AbstractSearchTreeNode implements SearchTree private static OWLIndividual[] allPositiveExamplesSorted; private static OWLIndividual[] allNegativeExamplesSorted; - private Boolean[] compactedCoveredPositiveExamples; - private Boolean[] compactedCoveredNegativeExamples; + private boolean[] coveredPositiveExamplesCompact; + private boolean[] coveredNegativeExamplesCompact; private final Set coveredPositiveExamples = new TreeSet<>(); private final Set coveredNegativeExamples = new TreeSet<>(); @@ -155,37 +154,37 @@ public void setRefinementCount(int refinementCount) { public Set getCoveredPositiveExamples() { if (useCompactedCoverage) { - return getCompactedCoveredPositiveExamples(); + return getCoveredPositiveExamplesCompact(); } return coveredPositiveExamples; } - private Set getCompactedCoveredPositiveExamples() { + private Set getCoveredPositiveExamplesCompact() { return IntStream.range(0, allPositiveExamplesSorted.length) - .mapToObj(i -> compactedCoveredPositiveExamples[i] ? allPositiveExamplesSorted[i] : null) + .mapToObj(i -> coveredPositiveExamplesCompact[i] ? allPositiveExamplesSorted[i] : null) .filter(Objects::nonNull) .collect(Collectors.toSet()); } public Set getCoveredNegativeExamples() { if (useCompactedCoverage) { - return getCompactedCoveredNegativeExamples(); + return getCoveredNegativeExamplesCompact(); } return coveredNegativeExamples; } - private Set getCompactedCoveredNegativeExamples() { + private Set getCoveredNegativeExamplesCompact() { return IntStream.range(0, allNegativeExamplesSorted.length) - .mapToObj(i -> compactedCoveredNegativeExamples[i] ? allNegativeExamplesSorted[i] : null) + .mapToObj(i -> coveredNegativeExamplesCompact[i] ? allNegativeExamplesSorted[i] : null) .filter(Objects::nonNull) .collect(Collectors.toSet()); } public void setCoveredPositiveExamples(Set coveredPositiveExamples) { if (useCompactedCoverage) { - setCompactedCoveredPositiveExamples(coveredPositiveExamples); + setCoveredPositiveExamplesCompact(coveredPositiveExamples); return; } @@ -196,15 +195,17 @@ public void setCoveredPositiveExamples(Set coveredPositiveExample } } - private void setCompactedCoveredPositiveExamples(Set coveredPositiveExamples) { - compactedCoveredPositiveExamples = Arrays.stream(allPositiveExamplesSorted) - .map(coveredPositiveExamples::contains) - .toArray(Boolean[]::new); + private void setCoveredPositiveExamplesCompact(Set coveredPositiveExamples) { + coveredPositiveExamplesCompact = new boolean[allPositiveExamplesSorted.length]; + + for (int i = 0; i < allPositiveExamplesSorted.length; i++) { + coveredPositiveExamplesCompact[i] = coveredPositiveExamples.contains(allPositiveExamplesSorted[i]); + } } public void setCoveredNegativeExamples(Set coveredNegativeExamples) { if (useCompactedCoverage) { - setCompactedCoveredNegativeExamples(coveredNegativeExamples); + setCoveredNegativeExamplesCompact(coveredNegativeExamples); return; } @@ -215,10 +216,12 @@ public void setCoveredNegativeExamples(Set coveredNegativeExample } } - private void setCompactedCoveredNegativeExamples(Set coveredNegativeExamples) { - compactedCoveredNegativeExamples = Arrays.stream(allNegativeExamplesSorted) - .map(coveredNegativeExamples::contains) - .toArray(Boolean[]::new); + private void setCoveredNegativeExamplesCompact(Set coveredNegativeExamples) { + coveredNegativeExamplesCompact = new boolean[allNegativeExamplesSorted.length]; + + for (int i = 0; i < allNegativeExamplesSorted.length; i++) { + coveredNegativeExamplesCompact[i] = coveredNegativeExamples.contains(allNegativeExamplesSorted[i]); + } } public static void enableCompactCoverageRepresentation(LearningProblem learningProblem) { From ebcdd96aff7b93da9ac5abaa68f78b39e37be4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 08:01:25 +0100 Subject: [PATCH 60/67] isSomeOnlySatisfied checked after refining --- .../refinementoperators/RhoDRDown.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index efe91aa54b..8d4a07cb2b 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -505,17 +505,23 @@ public Set refine(OWLClassExpression description, int maxLen if(maxLength < OWLClassExpressionUtils.getLength(description, lengthMetric)) { throw new Error("length has to be at least class expression length (class expression: " + description + " with length " + OWLClassExpressionUtils.getLength(description, lengthMetric) +", and max length: " + maxLength + ")"); } - return refine(description, maxLength, null, startClass); + return refine(description, maxLength, null); } @Override public Set refine(OWLClassExpression description, int maxLength, List knownRefinements) { - return refine(description, maxLength, knownRefinements, startClass); + Set refinements = refine(description, maxLength, knownRefinements, startClass); + + if (useSomeOnly) { + refinements.removeIf(r -> !isSomeOnlySatisfied(r)); + } + + return refinements; } @SuppressWarnings({"unchecked"}) - public Set refine(OWLClassExpression description, int maxLength, + private Set refine(OWLClassExpression description, int maxLength, List knownRefinements, OWLClassExpression currDomain) { // System.out.println("|- " + description + " " + currDomain + " " + maxLength); @@ -555,10 +561,6 @@ public Set refine(OWLClassExpression description, int maxLen refinements.removeIf(r -> r instanceof OWLObjectUnionOf); } - if (useSomeOnly) { - refinements.removeIf(r -> !isSomeOnlySatisfied(r)); - } - // refinements.addAll(classHierarchy.getMoreSpecialConcepts(description)); } else if(description.isOWLNothing()) { // cannot be further refined @@ -601,7 +603,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = ConceptTransformation.nnf(mc); // check whether the intersection is OK (sanity checks), then add it - if((!useSomeOnly || isSomeOnlySatisfied(mc, 2)) && checkIntersection((OWLObjectIntersectionOf) mc)) + if(checkIntersection((OWLObjectIntersectionOf) mc)) refinements.add(mc); } @@ -924,7 +926,7 @@ public Set refine(OWLClassExpression description, int maxLen mc = (OWLObjectIntersectionOf) ConceptTransformation.nnf(mc); // last check before intersection is added - if ((!useSomeOnly || isSomeOnlySatisfied(mc, 2)) && checkIntersection(mc)) + if (checkIntersection(mc)) refinements.add(mc); } } @@ -984,7 +986,6 @@ private Set refineUpwards( && (useDisjunction || !containsDisjunction(dNeg)) && (useNegation || !containsNegation(dNeg)) && (!useHasValueConstructor || useObjectValueNegation || !containsObjectValueNegation(dNeg)) - && (!useSomeOnly || isSomeOnlySatisfied(dNeg)) && OWLClassExpressionUtils.getLength(dNeg, lengthMetric) <= maxLength ) { results.add(dNeg); @@ -1055,7 +1056,7 @@ private boolean isSomeOnlySatisfied(OWLClassExpression description, Set op instanceof OWLObjectSomeValuesFrom - || (op instanceof OWLObjectMinCardinality && ((OWLObjectMinCardinality) op).getCardinality() > 0)) + || (op instanceof OWLObjectMinCardinality && ((OWLObjectMinCardinality) op).getCardinality() > 0)) .map(op -> ((OWLObjectRestriction) op).getProperty()) .collect(Collectors.toSet()); From 59d02607bc2b2557506144b6b93390eae1cc827a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 09:08:18 +0100 Subject: [PATCH 61/67] allFilter improved --- .../refinementoperators/RhoDRDown.java | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java index 8d4a07cb2b..82e0b88f1b 100644 --- a/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java +++ b/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java @@ -592,8 +592,13 @@ private Set refine(OWLClassExpression description, int maxLe // create new intersection for(OWLClassExpression c : tmp) { List newChildren = new ArrayList<>(operands); - newChildren.add(c); newChildren.remove(child); + + if (applyAllFilter && !passesAllFilter(newChildren, c)) { + continue; + } + + newChildren.add(c); Collections.sort(newChildren); OWLClassExpression mc = new OWLObjectIntersectionOfImplExt(newChildren); @@ -871,21 +876,8 @@ private Set refine(OWLClassExpression description, int maxLe // if a refinement of of the form ALL r, we check whether ALL r // does not occur already - if(applyAllFilter) { - if(c instanceof OWLObjectAllValuesFrom) { - if(description instanceof OWLNaryBooleanClassExpression){ - for(OWLClassExpression child : ((OWLNaryBooleanClassExpression) description).getOperands()) { - if(child instanceof OWLObjectAllValuesFrom) { - OWLObjectPropertyExpression r1 = ((OWLObjectAllValuesFrom) c).getProperty(); - OWLObjectPropertyExpression r2 = ((OWLObjectAllValuesFrom) child).getProperty(); - if(r1.equals(r2)){ - skip = true; - break; - } - } - } - } - } + if (applyAllFilter && !passesAllFilter(List.of(description), c)) { + skip = true; } // we only add \forall r.C to an intersection if there is @@ -911,7 +903,7 @@ private Set refine(OWLClassExpression description, int maxLe // this can avoid a lot of superfluous computation in the algorithm e.g. // when A1 looks good, so many refinements of the form (A1 OR (A2 AND A3)) // are generated which are all equal to A1 due to disjointness of A2 and A3 - if(disjointChecks && !c.isAnonymous() && !description.isAnonymous() && isDisjoint(description, c)) { + if(!skip && disjointChecks && !c.isAnonymous() && !description.isAnonymous() && isDisjoint(description, c)) { skip = true; // System.out.println(c + " ignored when refining " + description); } @@ -1035,6 +1027,29 @@ private boolean containsObjectValueNegation(OWLClassExpression description) { ); } + private boolean passesAllFilter(List otherOperands, OWLClassExpression newOperand) { + List operandsToCheck = (newOperand instanceof OWLObjectIntersectionOf) + ? ((OWLObjectIntersectionOf) newOperand).getOperandsAsList() + : List.of(newOperand); + + List allValuesProperties = otherOperands.stream() + .filter(op -> op instanceof OWLObjectAllValuesFrom) + .map(op -> ((OWLObjectAllValuesFrom) op).getProperty()) + .collect(Collectors.toList()); + + for (OWLClassExpression op : operandsToCheck) { + if (op instanceof OWLObjectAllValuesFrom) { + OWLObjectPropertyExpression prop = ((OWLObjectAllValuesFrom) op).getProperty(); + + if (allValuesProperties.contains(prop)) { + return false; + } + } + } + + return true; + } + private boolean isSomeOnlySatisfied(OWLClassExpression description) { return isSomeOnlySatisfied(description, -1); } From d605676e1ec9b8e41bc7c370baef84fd5a11f738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 09:51:45 +0100 Subject: [PATCH 62/67] compact coverage leaner again --- .../dllearner/algorithms/celoe/OENode.java | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java index 9d1fb4306e..c2b7b005c5 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java @@ -30,7 +30,6 @@ import java.text.DecimalFormat; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.IntStream; /** * A node in the search tree of the ontology engineering algorithm. @@ -62,11 +61,14 @@ public class OENode extends AbstractSearchTreeNode implements SearchTree private static boolean useCompactedCoverage = false; - private static OWLIndividual[] allPositiveExamplesSorted; - private static OWLIndividual[] allNegativeExamplesSorted; + private static OWLIndividual[] allPositiveExamples; + private static OWLIndividual[] allNegativeExamples; - private boolean[] coveredPositiveExamplesCompact; - private boolean[] coveredNegativeExamplesCompact; + private static Map positiveExamplesIndices; + private static Map negativeExamplesIndices; + + private int[] coveredPositiveExamplesCompact; + private int[] coveredNegativeExamplesCompact; private final Set coveredPositiveExamples = new TreeSet<>(); private final Set coveredNegativeExamples = new TreeSet<>(); @@ -161,10 +163,8 @@ public Set getCoveredPositiveExamples() { } private Set getCoveredPositiveExamplesCompact() { - return IntStream.range(0, allPositiveExamplesSorted.length) - .mapToObj(i -> coveredPositiveExamplesCompact[i] ? allPositiveExamplesSorted[i] : null) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); + return Arrays.stream(coveredPositiveExamplesCompact).mapToObj(i -> allPositiveExamples[i]) + .collect(Collectors.toSet()); } public Set getCoveredNegativeExamples() { @@ -176,10 +176,8 @@ public Set getCoveredNegativeExamples() { } private Set getCoveredNegativeExamplesCompact() { - return IntStream.range(0, allNegativeExamplesSorted.length) - .mapToObj(i -> coveredNegativeExamplesCompact[i] ? allNegativeExamplesSorted[i] : null) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); + return Arrays.stream(coveredNegativeExamplesCompact).mapToObj(i -> allNegativeExamples[i]) + .collect(Collectors.toSet()); } public void setCoveredPositiveExamples(Set coveredPositiveExamples) { @@ -196,10 +194,12 @@ public void setCoveredPositiveExamples(Set coveredPositiveExample } private void setCoveredPositiveExamplesCompact(Set coveredPositiveExamples) { - coveredPositiveExamplesCompact = new boolean[allPositiveExamplesSorted.length]; + coveredPositiveExamplesCompact = new int[coveredPositiveExamples.size()]; - for (int i = 0; i < allPositiveExamplesSorted.length; i++) { - coveredPositiveExamplesCompact[i] = coveredPositiveExamples.contains(allPositiveExamplesSorted[i]); + int ind = 0; + for (OWLIndividual ex : coveredPositiveExamples) { + coveredPositiveExamplesCompact[ind] = positiveExamplesIndices.get(ex); + ind++; } } @@ -217,10 +217,12 @@ public void setCoveredNegativeExamples(Set coveredNegativeExample } private void setCoveredNegativeExamplesCompact(Set coveredNegativeExamples) { - coveredNegativeExamplesCompact = new boolean[allNegativeExamplesSorted.length]; + coveredNegativeExamplesCompact = new int[coveredNegativeExamples.size()]; - for (int i = 0; i < allNegativeExamplesSorted.length; i++) { - coveredNegativeExamplesCompact[i] = coveredNegativeExamples.contains(allNegativeExamplesSorted[i]); + int ind = 0; + for (OWLIndividual ex : coveredNegativeExamples) { + coveredNegativeExamplesCompact[ind] = negativeExamplesIndices.get(ex); + ind++; } } @@ -236,8 +238,26 @@ public static void enableCompactCoverageRepresentation(LearningProblem learningP } protected static void enableCompactCoverageRepresentation(Set allPositiveExamples, Set allNegativeExamples) { - allPositiveExamplesSorted = allPositiveExamples.stream().sorted().toArray(OWLIndividual[]::new); - allNegativeExamplesSorted = allNegativeExamples.stream().sorted().toArray(OWLIndividual[]::new); + OENode.allPositiveExamples = allPositiveExamples.toArray(OWLIndividual[]::new); + OENode.allNegativeExamples = allNegativeExamples.toArray(OWLIndividual[]::new); + + Map positiveExamplesIndices = new TreeMap<>(); + Map negativeExamplesIndices = new TreeMap<>(); + + int ind = 0; + for (OWLIndividual ex : OENode.allPositiveExamples) { + positiveExamplesIndices.put(ex, ind); + ind++; + } + + ind = 0; + for (OWLIndividual ex : OENode.allNegativeExamples) { + negativeExamplesIndices.put(ex, ind); + ind++; + } + + OENode.positiveExamplesIndices = positiveExamplesIndices; + OENode.negativeExamplesIndices = negativeExamplesIndices; useCompactedCoverage = true; } From 3d7678c3d680790a31a944dc9ed146e68e77a484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 12:00:23 +0100 Subject: [PATCH 63/67] parcel accepting only the partial definitions which contibute to the coverage of positives more than to the coverage of negatives --- .../algorithms/parcel/ParCELAbstract.java | 11 ++++++++++ .../algorithms/parcel/ParCELWorker.java | 20 ++++++++++++++++++- .../algorithms/parcel/ParCELearner.java | 2 ++ .../algorithms/parcelex/ParCELExAbstract.java | 7 ------- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index b2b3650bde..daa66c05d3 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -174,6 +174,13 @@ public abstract class ParCELAbstract extends AbstractCELA implements ParCELearne */ protected Set uncoveredPositiveExamples; + /** + * Holds the covered negative examples, this will be updated when the worker found a partial definition + * since the callback method "partialDefinitionFound" is synchronized, + * there is no need to create a thread-safe for this set + */ + protected Set coveredNegativeExamples; + // --------------------------------------------------------- // flags to indicate the status of the application // --------------------------------------------------------- @@ -320,6 +327,10 @@ public void newPartialDefinitionsFound(Set definitions) { partialDefinitions.add(def); } + synchronized (coveredNegativeExamples) { + coveredNegativeExamples.addAll(def.getCoveredNegativeExamples()); + } + // for used in bean (for tracing purpose) this.noOfUncoveredPositiveExamples -= uncoveredPositiveExamplesRemoved; diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java index 67e543f65b..fd499635f3 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELWorker.java @@ -4,6 +4,7 @@ import java.util.Set; import java.util.TreeSet; +import com.google.common.collect.Sets; import org.dllearner.refinementoperators.RefinementOperator; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.mindswap.pellet.exceptions.InternalReasonerException; @@ -117,7 +118,7 @@ public void run() { if (addedNode != null) { // PARTIAL DEFINITION (correct and not necessary to be complete) - if (addedNode.getCorrectness() >= 1.0d - learner.getNoiseAllowed()) { + if (addedNode.getCorrectness() >= 1.0d - learner.getNoiseAllowed() && addsMorePositives(addedNode)) { addedNode.setGenerationTime(System.currentTimeMillis()); addedNode.setExtraInfo(learner.getTotalDescriptions()); definitionsFound.add(addedNode); @@ -179,6 +180,23 @@ private ParCELExtraNode checkAndCreateNewNode(OWLClassExpression description, Pa } // addNode() + private boolean addsMorePositives(ParCELNode node) { + if (node.getCorrectness() == 1) { + return true; + } + + int tp, fp; + + synchronized (learner.uncoveredPositiveExamples) { + tp = Sets.intersection(node.getCoveredPositiveExamples(), learner.uncoveredPositiveExamples).size(); + } + + synchronized (learner.coveredNegativeExamples) { + fp = Sets.difference(node.getCoveredNegativeExamples(), learner.coveredNegativeExamples).size(); + } + + return tp > fp; + } /** * Get the node which is currently being processed diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index 57c33e8507..be0faaca42 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -88,6 +88,8 @@ public void init() throws ComponentInitException { // this will be used to check the coverage of the partial definition (completeness) this.uncoveredPositiveExamples = new HashSet<>(this.positiveExamples); + this.coveredNegativeExamples = new HashSet<>(); + // initial heuristic which will be used by reducer to sort the search tree // the heuristic need to get some constant from the configurator for scoring the description if (this.heuristic == null) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java index 55ebf220fd..26eabbe67b 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELExAbstract.java @@ -30,13 +30,6 @@ public abstract class ParCELExAbstract extends ParCELAbstract { protected int[] partialDefinitionType = new int[5]; protected int counterPartialDefinitionUsed = 0; - /** - * Holds the covered negative examples, this will be updated when the worker found a partial definition - * since the callback method "partialDefinitionFound" is synchronized, - * there is no need to create a thread-safe for this set - */ - protected HashSet coveredNegativeExamples; - //--------------------------------------------------------- //flags to indicate the status of the application From 74d4681a1e2f35453cd6f0722d331c0ac788cd55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 15:29:31 +0100 Subject: [PATCH 64/67] OENode getting size of covered positives/negatives improved, ParcelExV2 prepared and modified, covered negatives comparator corrected --- .../org/dllearner/algorithms/celoe/CELOE.java | 2 +- .../dllearner/algorithms/celoe/OENode.java | 8 + .../algorithms/parcel/ParCELAbstract.java | 2 +- .../parcel/ParCELCompletenessComparator.java | 4 +- ...arCELCoveredNegativeExampleComparator.java | 4 +- .../algorithms/parcel/ParCELearner.java | 2 +- ...arCELImprovedCoverageGreedyReducer_V2.java | 8 +- .../algorithms/parcelex/ParCELWorkerExV2.java | 68 +++---- .../algorithms/parcelex/ParCELearnerExV1.java | 2 +- .../parcelex/ParCELearnerExV12.java | 72 ++++---- .../algorithms/parcelex/ParCELearnerExV2.java | 174 ++++++++++-------- 11 files changed, 187 insertions(+), 159 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java index 902168dc3b..e3bc6ea4d6 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java @@ -848,7 +848,7 @@ private void printSolutionCandidates() { logger.info(show + ": " + renderer.render(c.getDescription()) + " (accuracy " + df.format(100 * c.getAccuracy()) + "% / " + df.format(100 * computeTestAccuracy(c.getDescription())) + "%" - + ", coverage " + c.getCoveredPositiveExamples().size() + " / " + tpTest + + ", coverage " + c.getNumberOfCoveredPositiveExamples() + " / " + tpTest + ", length " + OWLClassExpressionUtils.getLength(c.getDescription()) + ", depth " + OWLClassExpressionUtils.getDepth(c.getDescription()) + ", time " + df.format(solutionCandidates.get(c)) + "s)"); diff --git a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java index c2b7b005c5..aff8edf4ca 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java +++ b/components-core/src/main/java/org/dllearner/algorithms/celoe/OENode.java @@ -167,6 +167,10 @@ private Set getCoveredPositiveExamplesCompact() { .collect(Collectors.toSet()); } + public int getNumberOfCoveredPositiveExamples() { + return useCompactedCoverage ? coveredPositiveExamplesCompact.length : coveredPositiveExamples.size(); + } + public Set getCoveredNegativeExamples() { if (useCompactedCoverage) { return getCoveredNegativeExamplesCompact(); @@ -180,6 +184,10 @@ private Set getCoveredNegativeExamplesCompact() { .collect(Collectors.toSet()); } + public int getNumberOfCoveredNegativeExamples() { + return useCompactedCoverage ? coveredNegativeExamplesCompact.length : coveredNegativeExamples.size(); + } + public void setCoveredPositiveExamples(Set coveredPositiveExamples) { if (useCompactedCoverage) { setCoveredPositiveExamplesCompact(coveredPositiveExamples); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java index daa66c05d3..9034120fdf 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELAbstract.java @@ -338,7 +338,7 @@ public void newPartialDefinitionsFound(Set definitions) { logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + "\n\t - covered positive examples (" - + def.getCoveredPositiveExamples().size() + "): " + + def.getNumberOfCoveredPositiveExamples() + "): " + def.getCoveredPositiveExamples() + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java index 870e2390ed..1bc44cdb18 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCompletenessComparator.java @@ -16,8 +16,8 @@ public class ParCELCompletenessComparator implements Comparator { @Override public int compare(ParCELNode node1, ParCELNode node2) { - int v1 = node1.getCoveredPositiveExamples().size(); - int v2 = node2.getCoveredPositiveExamples().size(); + int v1 = node1.getNumberOfCoveredPositiveExamples(); + int v2 = node2.getNumberOfCoveredPositiveExamples(); if (v1 > v2) return -1; diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java index 23cd91df14..0a981c8d8d 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELCoveredNegativeExampleComparator.java @@ -15,8 +15,8 @@ public class ParCELCoveredNegativeExampleComparator implements Comparator coveredNeg2) return -1; // smaller will be on the top diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java index be0faaca42..b826ecce81 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELearner.java @@ -288,7 +288,7 @@ else if (this.isTimeout()) { + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + ", accuracy: " + df.format(def.getAccuracy()) + " / " + computeTestAccuracy(def.getDescription()) - + ", coverage: " + def.getCoveredPositiveExamples().size() + " / " + tpTest + ")"); + + ", coverage: " + def.getNumberOfCoveredPositiveExamples() + " / " + tpTest + ")"); // print out the learning tree /* diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java index 17464392e0..3fc2d475cb 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/reducer/ParCELImprovedCoverageGreedyReducer_V2.java @@ -89,7 +89,7 @@ public SortedSet reduce(SortedSet partialDefin maxLength = curLength; //max coverage - int curCoverage = pdef.getCoveredPositiveExamples().size(); + int curCoverage = pdef.getNumberOfCoveredPositiveExamples(); if (maxCoverage < curCoverage) maxCoverage = curCoverage; } @@ -108,7 +108,7 @@ public SortedSet reduce(SortedSet partialDefin //------------------ //count the number of positive examples covered by the partial definition i //------------------ - int counti = ((ParCELExtraNode)partialDefs[i]).getCoveredPositiveExamples().size(); + int counti = ((ParCELExtraNode)partialDefs[i]).getNumberOfCoveredPositiveExamples(); for (OWLIndividual ind : ((ParCELExtraNode)partialDefs[i]).getCoveredPositiveExamples()) { if (coveredPositiveExamples.size() == 0) @@ -129,7 +129,7 @@ public SortedSet reduce(SortedSet partialDefin //----------- //count the number of positive examples covered by the partial definition j //----------- - int countj = ((ParCELExtraNode)partialDefs[j]).getCoveredPositiveExamples().size(); + int countj = ((ParCELExtraNode)partialDefs[j]).getNumberOfCoveredPositiveExamples(); for (OWLIndividual ind : ((ParCELExtraNode)partialDefs[j]).getCoveredPositiveExamples()) { if (coveredPositiveExamples.size() == 0) @@ -161,7 +161,7 @@ public SortedSet reduce(SortedSet partialDefin //calculate the relative coverage score double relativeCoverageScore = scoringRelativeCoverage(maxCoverage, - ((ParCELExtraNode)partialDefs[i]).getCoveredPositiveExamples().size(), + ((ParCELExtraNode)partialDefs[i]).getNumberOfCoveredPositiveExamples(), maxLocalCoverage); //calculate score of other dimensions: currently there is only length diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java index 2796c237d6..e3692e3dd3 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java @@ -2,6 +2,7 @@ import org.dllearner.algorithms.parcel.*; import org.dllearner.refinementoperators.RefinementOperator; +import org.mindswap.pellet.exceptions.InternalReasonerException; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.semanticweb.owlapi.model.OWLClassExpression; @@ -113,7 +114,11 @@ public void run() { if(refinementLength >= horizExp) { //calculate accuracy, correctness, positive examples covered by the description, resulted in a node - ParCELExtraNode newNode = checkAndCreateNewNodeV2(refinement, nodeToProcess); + ParCELExtraNode newNode = null; + + try { + newNode = checkAndCreateNewNodeV2(refinement, nodeToProcess); + } catch (InternalReasonerException | NullPointerException e) {} //check for the type of new node: weak description, partial definition, counter partial definition or potential description if (newNode != null) { @@ -156,21 +161,18 @@ public void run() { //PARTIAL DEFINITION //the new description may be combined with the counter partial definitions to become a partial definition - if (combinableCounterPartialDefinitions != null) { - //for (ParCELExtraNode def : combinableCounterPartialDefinitions) { - newNode.setDescription(ParCELExUtilities.createIntersection(newNode.getDescription(), - combinableCounterPartialDefinitions, true)); - //def.setType(ParCELExNodeTypes.COUNTER_PARTIAL_DEFINITION_USED); //2 - to mark the counter definition had been used to generate the partial definition - //} - - //3 - means the partial definition is the result of the combination of a new refined description and a counter partial definition - newNode.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_ONLINE_COMBINATION); - newNode.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); - newNode.setExtraInfo(learner.getTotalDescriptions()); - newPartialDefinitions.add(newNode); + if (combinableCounterPartialDefinitions != null) { + ParCELExtraNode newPD = new ParCELExtraNode(newNode); + newPD.setDescription(ParCELExUtilities.createIntersection(newNode.getDescription(), + combinableCounterPartialDefinitions, true)); + + newPD.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_ONLINE_COMBINATION); + newPD.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); + newPD.setExtraInfo(learner.getTotalDescriptions()); + newPartialDefinitions.add(newPD); } - else //the new node cannot be combined ==> this is a DESCRIPTION - newNodes.add(newNode); + + newNodes.add(newNode); } } } //if (node != null) @@ -182,32 +184,30 @@ public void run() { } //process the input node: check if is it potentially a partial definition - Set combinableCounterPartialDefinitions = - ParCELExCombineCounterPartialDefinition.getCombinable(nodeToProcess, learner.getCurrentCounterPartialDefinitions()); - - if (combinableCounterPartialDefinitions != null) { - //for (ParCELExtraNode def : combinableCounterPartialDefinitions) - nodeToProcess.setDescription(ParCELExUtilities.createIntersection( - nodeToProcess.getDescription(), combinableCounterPartialDefinitions, true)); - - ParCELExtraNode newPD = new ParCELExtraNode(nodeToProcess); - newPD.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); - newPD.setExtraInfo(learner.getTotalDescriptions()); - newPD.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_REFINED_NODE); //4 - (refined node + counter pdef) - newPartialDefinitions.add(newPD); - } - else +// Set combinableCounterPartialDefinitions = +// ParCELExCombineCounterPartialDefinition.getCombinable(nodeToProcess, learner.getCurrentCounterPartialDefinitions()); +// +// if (combinableCounterPartialDefinitions != null) { +// //for (ParCELExtraNode def : combinableCounterPartialDefinitions) +// nodeToProcess.setDescription(ParCELExUtilities.createIntersection( +// nodeToProcess.getDescription(), combinableCounterPartialDefinitions, true)); +// +// ParCELExtraNode newPD = new ParCELExtraNode(nodeToProcess); +// newPD.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); +// newPD.setExtraInfo(learner.getTotalDescriptions()); +// newPD.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_REFINED_NODE); //4 - (refined node + counter pdef) +// newPartialDefinitions.add(newPD); +// } +// else newNodes.add(nodeToProcess); - + + learner.newRefinementDescriptions(newNodes); //don't need to check for empty since newNodes is never empty if (newPartialDefinitions.size() > 0) learner.newPartialDefinitionsFound(newPartialDefinitions); if (newCounterPartialDefinitions.size() > 0) learner.newCounterPartialDefinitionsFound(newCounterPartialDefinitions); - - learner.newRefinementDescriptions(newNodes); //don't need to check for empty since newNodes is never empty - } } diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java index bf85d65fa7..72ae42b33a 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV1.java @@ -368,7 +368,7 @@ public void newCounterPartialDefinitionsFound(Set counterPartia // but there is no need to do it for the counter partial definition, i.e. no update for covered negative examples if (logger.isTraceEnabled() || logger.isDebugEnabled()) { logger.trace("COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + - "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - covered negative examples (" + def.getNumberOfCoveredNegativeExamples() + "): " + def.getCoveredNegativeExamples() + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() ); } else if (logger.isInfoEnabled()) { diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java index 9899e362fd..cf01f4f3cc 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV12.java @@ -241,7 +241,7 @@ public void start() { this.miliLearningTime = System.currentTimeMillis() - miliStarttime; - stop(); + stop(); //----------------------------------------------------------------------- //try to combine descriptions in the search tree with the counter partial @@ -254,40 +254,40 @@ public void start() { /* synchronized (this.potentialPartialDefinitions) { logger.info("Processing potential partial definition: " + this.potentialPartialDefinitions.size()); - + for (ParCELExtraNode ppd : this.potentialPartialDefinitions) { - Set combinableCounterPartialDefinitions = + Set combinableCounterPartialDefinitions = ParCELCombineCounterPartialDefinition.getCombinable(ppd, this.counterPartialDefinitions); - + //new partial definition found if the description can be combined with the set of counter partial definitions - if (combinableCounterPartialDefinitions != null) { - + if (combinableCounterPartialDefinitions != null) { + ParCELExtraNode newPD = new ParCELExtraNode(ppd); - - + + LinkedList tmpCounterDes = new LinkedList(); tmpCounterDes.add(ppd.getDescription()); - + for (ParCELExtraNode def : combinableCounterPartialDefinitions) { tmpCounterDes.add(def.getDescription()); //newPD.setDescription(new Intersection(newPD.getDescription(), def.getDescription())); def.setType(1); } - + newPD.setDescription(new Intersection(tmpCounterDes)); - + this.uncoveredPositiveExamples.removeAll(ppd.getCoveredPositiveExamples()); newPD.setCompositeList(combinableCounterPartialDefinitions); - + newPD.setGenerationTime(System.currentTimeMillis() - miliStarttime); newPD.setType(2); - + if (allDescriptions.add(newPD.getDescription())) { partialDefinitions.add(newPD); newPartialDefCount++; } - + } //new partial definition found } //for } //synchronise potential partial definitions @@ -301,52 +301,52 @@ public void start() { List newSearchTree = new ArrayList<>(this.searchTree); newSearchTree.sort(new ParCELCompletenessComparator()); - + for (ParCELNode des : newSearchTree) { - + synchronized (this.counterPartialDefinitions) { - Set combinableCounterPartialDefinitions = + Set combinableCounterPartialDefinitions = ParCELExCombineCounterPartialDefinition.getCombinable(des, this.counterPartialDefinitions); //new partial definition found if the description can be combined with the set of counter partial definitions - if (combinableCounterPartialDefinitions != null) { - + if (combinableCounterPartialDefinitions != null) { + ParCELExtraNode newPD = new ParCELExtraNode(des); - - + + /* LinkedList tmpCounterDes = new LinkedList(); tmpCounterDes.add(des.getDescription()); - + for (ParCELExtraNode def : combinableCounterPartialDefinitions) { tmpCounterDes.add(def.getDescription()); //newPD.setDescription(new Intersection(newPD.getDescription(), def.getDescription())); def.setType(1); } */ - - newPD.setDescription(ParCELExUtilities.createIntersection(des.getDescription(), + + newPD.setDescription(ParCELExUtilities.createIntersection(des.getDescription(), combinableCounterPartialDefinitions, true)); - + this.uncoveredPositiveExamples.removeAll(des.getCoveredPositiveExamples()); newPD.setCompositeList(combinableCounterPartialDefinitions); - + //PDLLExtraNode newPD = new PDLLExtraNode(des); newPD.setGenerationTime(System.currentTimeMillis() - miliStarttime); newPD.setType(2); - + if (allDescriptions.add(newPD.getDescription())) { partialDefinitions.add(newPD); newPartialDefCount++; } - + } //new partial definition found } //synch counter partial definition for processing - + } //for each description in the search tree - + } //synch search tree if (logger.isInfoEnabled()) @@ -389,7 +389,7 @@ else if (this.isTimeout()) { logger.info(count++ + ". " + OWLAPIRenderers.toManchesterOWLSyntax(ParCELExUtilities.groupDefinition(def.getDescription())).replace("and (not", "\nand (not") + //def.getDescription().toManchesterSyntaxString(baseURI, prefix) + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + ", accuracy: " + df.format(def.getAccuracy()) + " / " + computeTestAccuracy(def.getDescription()) + - ", coverage: " + def.getCoveredPositiveExamples().size() + " / " + tpTest + ")" + + ", coverage: " + def.getNumberOfCoveredPositiveExamples() + " / " + tpTest + ")" + ", type: " + def.getType() + ")"); //print out the learning tree @@ -492,13 +492,13 @@ public void newPartialDefinitionsFound(Set definitions) { if (logger.isTraceEnabled()) { logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + - "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - covered positive examples (" + def.getNumberOfCoveredPositiveExamples() + "): " +def.getCoveredPositiveExamples() + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() ); } else if (logger.isDebugEnabled()) logger.debug("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + - "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - covered positive examples (" + def.getNumberOfCoveredPositiveExamples() + "): " +def.getCoveredPositiveExamples() + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() ); else if (logger.isInfoEnabled()) { @@ -552,7 +552,7 @@ public void newPotentialPartialDefinition(Set potentialPartialD for (ParCELExtraNode def : potentialPartialDefinitions) { if (this.potentialPartialDefinitions.add(def.getDescription())) { synchronized (uncoveredPositiveExamples) { - this.uncoveredPositiveExamples.removeAll(def.getCoveredPositiveExamples()); + this.uncoveredPositiveExamples.removeAll(def.getCoveredPositiveExamples()); } this.potentialPartialDefinitions.add(def.getDescription()); @@ -608,13 +608,13 @@ public void newCounterPartialDefinitionsFound(Set counterPartia // but there is no need to do it for the counter partial definition, i.e. no update for covered negative examples if (logger.isTraceEnabled()) { logger.trace("COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + - "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - covered negative examples (" + def.getNumberOfCoveredNegativeExamples() + "): " + def.getCoveredNegativeExamples() + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() ); } else if (logger.isDebugEnabled()) logger.debug("COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + - "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - covered negative examples (" + def.getNumberOfCoveredNegativeExamples() + "): " + def.getCoveredNegativeExamples() + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() ); else if (logger.isInfoEnabled()) { diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java index 7c9fdf5f41..c9a6aca0e0 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java @@ -12,8 +12,10 @@ * @author An C. Tran */ +import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.*; +import java.util.stream.Collectors; import org.dllearner.algorithms.celoe.OENode; import org.dllearner.algorithms.parcel.*; @@ -26,6 +28,7 @@ import org.dllearner.utilities.owl.OWLAPIRenderers; import org.dllearner.utilities.owl.OWLClassExpressionLengthCalculator; import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLDataProperty; @@ -86,19 +89,22 @@ public void init() throws ComponentInitException { //get the positive and negative examples from the learning problem positiveExamples = ((ParCELPosNegLP)learningProblem).getPositiveExamples(); negativeExamples = ((ParCELPosNegLP)learningProblem).getNegativeExamples(); - - - ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(this.positiveExamples); + positiveTestExamples = ((ParCELPosNegLP) learningProblem).getPositiveTestExamples(); + negativeTestExamples = ((ParCELPosNegLP) learningProblem).getNegativeTestExamples(); //initial heuristic which will be used by reducer to sort the search tree (expansion strategy) //the heuristic need to get some constant from the configurator for scoring the description - if (heuristic == null) - heuristic = new ParCELDefaultHeuristic(); - - startClass = dataFactory.getOWLThing(); //this will be revise later using least common super class of all observations - + if (heuristic == null) { + heuristic = new ParCELDefaultHeuristic(); + } + + //this will be revise later using least common super class of all observations + if (startClass == null) { + startClass = dataFactory.getOWLThing(); + } - this.uncoveredPositiveExampleAllowed = (int)Math.ceil(getNoisePercentage()*positiveExamples.size()); + this.uncoveredPositiveExampleAllowed = (int)Math.ceil((getNoisePercentage()/100)*positiveExamples.size()); + logger.info("Uncovered positive examples allowed (noise): " + this.uncoveredPositiveExampleAllowed); //initialise the existing uncovered positive examples ((ParCELPosNegLP)this.learningProblem).setUncoveredPositiveExamples(uncoveredPositiveExamples); @@ -106,54 +112,11 @@ public void init() throws ComponentInitException { //---------------------------------- //create refinement operator pool //---------------------------------- - if (operator == null) { - //----------------------------------------- - //prepare for refinement operator creation - //----------------------------------------- - Set usedConcepts = new TreeSet<>(reasoner.getClasses()); - - - //remove the ignored concepts out of the list of concepts will be used by refinement operator - if (this.ignoredConcepts != null) { - try { - usedConcepts.removeAll(ignoredConcepts); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - ClassHierarchy classHiearachy = (ClassHierarchy) reasoner.getClassHierarchy().cloneAndRestrict(usedConcepts); - Map> splits = null; - - //create a splitter and refinement operator pool - //there are two options: i) using object pool, ii) using set of objects (removed from this revision) - if (this.splitter != null) { - splitter.setReasoner(reasoner); - splitter.setPositiveExamples(positiveExamples); - splitter.setNegativeExamples(negativeExamples); - splitter.init(); - - splits = splitter.computeSplits(); - - //i) option 1: create an object pool - refinementOperatorPool = new ParCELRefinementOperatorPool(reasoner, classHiearachy, startClass, splits, numberOfWorkers + 1); - - } - else { //no splitter provided - //i) option 1: create an object pool - refinementOperatorPool = new ParCELRefinementOperatorPool(reasoner, classHiearachy, startClass, numberOfWorkers + 1, maxNoOfSplits); - } - - refinementOperatorPool.getFactory().setUseNegation(false); - refinementOperatorPool.getFactory().setUseHasValue(this.getUseHasValue()); - refinementOperatorPool.getFactory().setUseRestrictedDisjunction(useRestrictedDisjunction); - - } + initOperatorIfAny(); + createRefinementOperatorPool(); baseURI = reasoner.getBaseURI(); prefix = reasoner.getPrefixes(); - //new DecimalFormat(); //logging the information (will use slf4j) @@ -164,6 +127,8 @@ public void init() throws ComponentInitException { minNumberOfWorker = maxNumberOfWorker = numberOfWorkers; + trainingTime = System.currentTimeMillis(); + } //init() @@ -192,6 +157,9 @@ public void start() { //start time of reducer, statistical purpose only miliStarttime = System.currentTimeMillis(); + + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); //---------------------------------------------------------- // perform the learning process until the conditions for @@ -202,7 +170,7 @@ public void start() { //------------------- //check for timeout //------------------- - timeout = (this.maxExecutionTimeInSeconds > 0 && (System.currentTimeMillis() - miliStarttime) > this.maxExecutionTimeInSeconds*1000); + timeout = (this.maxExecutionTimeInSeconds > 0 && (getCurrentCpuMillis()) > this.maxExecutionTimeInSeconds*1000); if (timeout) break; @@ -210,7 +178,7 @@ public void start() { ParCELNode nodeToProcess; - nodeToProcess = searchTree.pollLast(); + nodeToProcess = searchTree.pollFirst(); //TODO: why this? why "blocking" concept does not help in this case? //remove this checking will exploit the heap memory and no definition found @@ -297,27 +265,43 @@ public void start() { //post-learning processing //------------------------------- - if (logger.isInfoEnabled()) { + if (logger.isInfoEnabled()) { + synchronized (searchTree) { + logger.info("Search tree size: " + searchTree.size()); + } + synchronized (partialDefinitions) { if (this.getCurrentlyOveralMaxCompleteness() == 1) logger.info("Learning finishes in: " + this.miliLearningTime + "ms, with: " + partialDefinitions.size() + " definitions"); else if (this.isTimeout()) { - logger.info("Learning timeout in " + this.maxExecutionTimeInSeconds + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); + logger.info("Learning timeout in " + this.maxExecutionTimeInSeconds + "s. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); } else { logger.info("Learning is manually terminated at " + this.miliLearningTime + "ms. Overall completeness (%): " + this.getCurrentlyOveralMaxCompleteness()); logger.info("Uncovered positive examples left " + this.uncoveredPositiveExamples.size() + " - " + ParCELStringUtilities.replaceString(this.uncoveredPositiveExamples.toString(), this.baseURI, this.prefix)); } + + timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info("Time " + getCurrentCpuMillis() / 1000.0 + "s; " + timeStamp); + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); + logger.info("Accuracy: " + acc); logger.info("**Reduced partial definitions:"); TreeSet compactedDefinitions = (TreeSet) this.getReducedPartialDefinition(); this.noOfReducedPartialDefinition = compactedDefinitions.size(); int count = 1; for (ParCELExtraNode def : compactedDefinitions) { + int tpTest = learningProblem instanceof ParCELPosNegLP + ? ((ParCELPosNegLP) learningProblem).getNumberOfCoveredPositiveTestExamples(def.getDescription()) + : 0; + logger.info(count++ + ". " + OWLAPIRenderers.toManchesterOWLSyntax(ParCELExUtilities.groupDefinition(def.getDescription())).replace("and (not", "\nand (not") + //def.getDescription().toManchesterSyntaxString(baseURI, prefix) + " (length:" + new OWLClassExpressionLengthCalculator().getLength(def.getDescription()) + - ", accuracy: " + df.format(def.getAccuracy()) + + ", accuracy: " + df.format(def.getAccuracy()) + " / " + computeTestAccuracy(def.getDescription()) + + ", coverage: " + def.getNumberOfCoveredPositiveExamples() + " / " + tpTest + ")" + ", type: " + def.getType() + ")"); //test the new representation of the partial definition @@ -346,6 +330,15 @@ else if (this.isTimeout()) { } } //end of printing the learning tree } + + if (learningProblem instanceof ParCELPosNegLP) { + Set partialDefs = getReducedPartialDefinition() + .stream().map(OENode::getDescription).collect(Collectors.toSet()); + + ((ParCELPosNegLP) learningProblem).printTestEvaluation(partialDefs); + } + + printBestConceptsTimesAndAccuracies(); } } @@ -402,18 +395,30 @@ public void newPartialDefinitionsFound(Set definitions) { if (logger.isTraceEnabled()) { logger.trace("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + - "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - covered positive examples (" + def.getNumberOfCoveredPositiveExamples() + "): " +def.getCoveredPositiveExamples() + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() + ", des:" + def.getGenerationTime() ); } else if (logger.isDebugEnabled()) logger.debug("PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + - "\n\t - covered positive examples (" + def.getCoveredPositiveExamples().size() + "): " +def.getCoveredPositiveExamples() + + "\n\t - covered positive examples (" + def.getNumberOfCoveredPositiveExamples() + "): " +def.getCoveredPositiveExamples() + "\n\t - uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size() ); else if (logger.isInfoEnabled()) { - logger.info("(+) PARTIAL definition found. Uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + logger.info("PARTIAL definition found. Uncovered positive examples left: " + uncoveredPositiveExamplesSize + "/" + positiveExamples.size()); + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info(timeStamp + ": " + def); + + double actualTrainingTime = getCurrentCpuMillis() / 1000.0; + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); + double testAcc = computeTestAccuracy(bestDescription); + + logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); + + recordBestConceptTimeAndAccuracy(actualTrainingTime, acc, testAcc); } //update the max accuracy and max description length @@ -466,17 +471,29 @@ public void newCounterPartialDefinitionsFound(Set counterPartia // but there is no need to do it for the counter partial definition, i.e. no update for covered negative examples if (logger.isTraceEnabled()) { logger.trace("(-) COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + //TODO def.getDescription().getChild(0) - "\n\t - covered negative examples (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - covered negative examples (" + def.getNumberOfCoveredNegativeExamples() + "): " + def.getCoveredNegativeExamples() + "\n\t - total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() ); } else if (logger.isDebugEnabled()) logger.debug("(-) COUNTER PARTIAL definition found: " + OWLAPIRenderers.toManchesterOWLSyntax(def.getDescription()) + //TODO def.getDescription().getChild(0) - "\n\t - cn (" + def.getCoveredNegativeExamples().size() + "): " + def.getCoveredNegativeExamples() + + "\n\t - cn (" + def.getNumberOfCoveredNegativeExamples() + "): " + def.getCoveredNegativeExamples() + "\n\t - total cn: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size() ); else if (logger.isInfoEnabled()) { - logger.info("(-) COUNTER PARTIAL definition found. Total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size()); + logger.info("COUNTER PARTIAL definition found. Total covered negative examples: " + numberOfCoveredNegativeExamples + "/" + this.negativeExamples.size()); + String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date()); + logger.info(timeStamp + ": " + def); + + double actualTrainingTime = getCurrentCpuMillis() / 1000.0; + + OWLClassExpression bestDescription = getUnionCurrentlyBestDescription(); + double acc = computeAccuracy(bestDescription); + double testAcc = computeTestAccuracy(bestDescription); + + logger.info("Training time: " + actualTrainingTime + "s Accuracy: " + acc + " Test accuracy: " + testAcc); + + recordBestConceptTimeAndAccuracy(actualTrainingTime, acc, testAcc); } //complete counter definition found @@ -498,7 +515,7 @@ else if (logger.isInfoEnabled()) { * 3. Create an empty */ private void reset() { - searchTree = new ConcurrentSkipListSet<>(heuristic); + searchTree = new ConcurrentSkipListSet<>(heuristic.reversed()); //allDescriptions = new TreeSet(new ConceptComparator()); this.allDescriptions = new ConcurrentSkipListSet<>(); @@ -530,24 +547,24 @@ private void reset() { @Override public void stop() { - if (!stop) { + if (!stop) { stop = true; - + List waitingTasks = workerPool.shutdownNow(); - - - + try { - workerPool.awaitTermination(0, TimeUnit.SECONDS); + workerPool.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException ie) { logger.error(ie); } - + //put the unexecuted tasks back to the search tree - logger.debug("Put incompleted task back to the search tree: " + waitingTasks.size()); - for (Runnable node : waitingTasks) - searchTree.add(((ParCELWorkerExV2)node).getProcessingNode()); + synchronized (this.searchTree) { + logger.debug("Put incompleted task back to the search tree: " + waitingTasks.size()); + for (Runnable node : waitingTasks) + searchTree.add(((ParCELWorkerExV2)node).getProcessingNode()); + } //don't stop immediately, wait until all workers finish their jobs /* @@ -561,7 +578,10 @@ public void stop() { */ } } - + + public boolean isTimeout() { + return timeout; + } From dbb15e7bf03145eb4f890ca02b60f9c67cef99a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 18:06:00 +0100 Subject: [PATCH 65/67] ParcelExV2 partial definition resulting from combination has correct data --- .../org/dllearner/algorithms/parcel/ParCELPosNegLP.java | 4 ++++ .../dllearner/algorithms/parcelex/ParCELWorkerExV2.java | 7 +++++++ .../dllearner/algorithms/parcelex/ParCELearnerExV2.java | 9 +++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java index 0e53845c1e..3b8159f0ea 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELPosNegLP.java @@ -519,6 +519,10 @@ public ParCELEvaluationResult getAccuracyAndCorrectness5( return getAccuracyAndCorrectness4(coveredPositives, coveredNegatives); } + public double getAccuracy(int tp, int tn) { + return (tp + tn) / (double) (positiveExamples.size() + negativeExamples.size()); + } + /** * Accuracy calculation for the exception learning which provide both covered positive and * negative examples by the description
diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java index e3692e3dd3..493429e4ff 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java @@ -166,6 +166,13 @@ public void run() { newPD.setDescription(ParCELExUtilities.createIntersection(newNode.getDescription(), combinableCounterPartialDefinitions, true)); + newPD.setCoveredNegativeExamples(Set.of()); + newPD.setCorrectness(1); + newPD.setAccuracy(learningProblem.getAccuracy( + newPD.getNumberOfCoveredPositiveExamples(), + learningProblem.getPositiveExamples().size() + )); + newPD.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_ONLINE_COMBINATION); newPD.setGenerationTime(System.currentTimeMillis() - learner.getMiliStarttime()); newPD.setExtraInfo(learner.getTotalDescriptions()); diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java index c9a6aca0e0..114ba04fda 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELearnerExV2.java @@ -381,8 +381,8 @@ public void newPartialDefinitionsFound(Set definitions) { uncoveredPositiveExamplesRemoved = this.uncoveredPositiveExamples.size(); this.uncoveredPositiveExamples.removeAll(def.getCoveredPositiveExamples()); uncoveredPositiveExamplesSize = this.uncoveredPositiveExamples.size(); - - + } + uncoveredPositiveExamplesRemoved -= uncoveredPositiveExamplesSize; if (uncoveredPositiveExamplesRemoved > 0) { @@ -433,8 +433,6 @@ else if (logger.isInfoEnabled()) { //stop(); } } - } - } //for each partial definition @@ -457,7 +455,7 @@ public void newCounterPartialDefinitionsFound(Set counterPartia this.coveredNegativeExamples.addAll(def.getCoveredNegativeExamples()); numberOfNewCoveredNegativeExamples = this.coveredNegativeExamples.size() - numberOfNewCoveredNegativeExamples; numberOfCoveredNegativeExamples = this.coveredNegativeExamples.size(); - + } //process the counter partial definition if it covers at least 1 new negative example if (numberOfNewCoveredNegativeExamples > 0) { @@ -502,7 +500,6 @@ else if (logger.isInfoEnabled()) { //this.stop(); } } - } } From ea57b0367067e29f5c3ccf6ed9fd5616db324deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 18:07:58 +0100 Subject: [PATCH 66/67] minor fix in corrected data --- .../org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java index 493429e4ff..102ad0c119 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcelex/ParCELWorkerExV2.java @@ -170,7 +170,7 @@ public void run() { newPD.setCorrectness(1); newPD.setAccuracy(learningProblem.getAccuracy( newPD.getNumberOfCoveredPositiveExamples(), - learningProblem.getPositiveExamples().size() + learningProblem.getNegativeExamples().size() )); newPD.setType(ParCELExNodeTypes.PARTIAL_DEFINITION_ONLINE_COMBINATION); From d08592eac5e88be3b96c4721868821ac6a17c9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Bist=C3=A1k?= Date: Mon, 13 Mar 2023 18:33:33 +0100 Subject: [PATCH 67/67] removing code commented out --- .../org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java index b5740678c3..18b33f85b5 100644 --- a/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java +++ b/components-core/src/main/java/org/dllearner/algorithms/parcel/ParCELDefaultHeuristic.java @@ -20,7 +20,7 @@ public class ParCELDefaultHeuristic implements ParCELHeuristic { protected double expansionPenaltyFactor = 0.05; //0.01, 0.05 // bonus for gained accuracy - protected double gainBonusFactor = 0.2; //0.2; //0.1, 0.2 + protected double gainBonusFactor = 0.2; //0.1, 0.2 // penalty if a node description has very many refinements since exploring // such a node is computationally very expensive