From: <lor...@us...> - 2014-05-07 13:43:59
|
Revision: 4262 http://sourceforge.net/p/dl-learner/code/4262 Author: lorenz_b Date: 2014-05-07 13:43:54 +0000 (Wed, 07 May 2014) Log Message: ----------- Updated libs. Modified Paths: -------------- trunk/components-core/pom.xml trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELLearningAlgorithm.java trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/SearchTreeNode.java trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/AbstractRelevanceMetric.java trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/RelevanceMetric.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2Disjunctive.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/impl/QueryTreeFactoryImpl.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/lgg/LGGGeneratorImpl.java trunk/components-core/src/main/java/org/dllearner/core/AbstractCELA.java trunk/components-core/src/main/java/org/dllearner/core/AbstractReasonerComponent.java trunk/components-core/src/main/java/org/dllearner/core/owl/ClassHierarchy.java trunk/components-core/src/main/java/org/dllearner/kb/OWLAPIOntology.java trunk/components-core/src/main/java/org/dllearner/kb/aquisitors/SparqlTupleAquisitorImproved.java trunk/components-core/src/main/java/org/dllearner/learningproblems/PosNegLPStandard.java trunk/components-core/src/main/java/org/dllearner/reasoning/FastInstanceChecker.java trunk/components-core/src/main/java/org/dllearner/reasoning/OWLAPIReasoner.java trunk/components-core/src/main/java/org/dllearner/reasoning/SPARQLReasoner.java trunk/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java trunk/components-core/src/main/java/org/dllearner/utilities/examples/AutomaticNegativeExampleFinderSPARQL2.java trunk/components-core/src/main/resources/log4j.properties trunk/components-core/src/test/java/org/dllearner/algorithms/isle/DBpediaExperiment.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/LGGTest.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/QALDExperiment.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/QTLTest.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/TreeSubsumptionTest.java trunk/examples/family-benchmark/Brother.conf trunk/interfaces/src/main/java/org/dllearner/cli/CLI.java trunk/interfaces/src/main/java/org/dllearner/cli/CrossValidation.java trunk/interfaces/src/main/java/org/dllearner/cli/SPARQLCrossValidation.java trunk/pom.xml trunk/protege/src/main/resources/META-INF/MANIFEST.MF trunk/scripts/pom.xml trunk/scripts/src/main/java/org/dllearner/scripts/evaluation/QTLEvaluation.java Added Paths: ----------- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DefaultRelevanceWeightings.java trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightedStableHeuristic.java trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightings.java trunk/components-core/src/main/java/org/dllearner/algorithms/isle/index/syntactic/EntityFrequencyCache.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2DisjunctiveMT.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeHeuristic.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/util/QueryTreeConverter.java Removed Paths: ------------- trunk/test/fuzzydll/fuzzyOWL2fuzzyDLparserOutput.fuzzyDL.txt Modified: trunk/components-core/pom.xml =================================================================== --- trunk/components-core/pom.xml 2014-05-07 11:25:54 UTC (rev 4261) +++ trunk/components-core/pom.xml 2014-05-07 13:43:54 UTC (rev 4262) @@ -232,10 +232,10 @@ <artifactId>commons-pool</artifactId> </dependency> <dependency> - <groupId>org.semanticweb.elk</groupId> - <artifactId>elk-owlapi</artifactId> - <version>0.3.0</version> - </dependency> + <groupId>org.semanticweb.elk</groupId> + <artifactId>elk-owlapi</artifactId> + <version>0.4.1</version> +</dependency> <dependency> <groupId>de.tudresden.inf.lat.cel</groupId> <artifactId>reasoner</artifactId> @@ -281,7 +281,7 @@ <dependency> <groupId>org.aksw.jena-sparql-api</groupId> <artifactId>jena-sparql-api-core</artifactId> - <version>2.10.0-5-SNAPSHOT</version> + <version>2.10.0-8</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DefaultRelevanceWeightings.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DefaultRelevanceWeightings.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DefaultRelevanceWeightings.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -0,0 +1,31 @@ +/** + * + */ +package org.dllearner.algorithms.elcopy; + +import org.dllearner.algorithms.isle.metrics.ChiSquareRelevanceMetric; +import org.dllearner.algorithms.isle.metrics.DiceRelevanceMetric; +import org.dllearner.algorithms.isle.metrics.JaccardRelevanceMetric; +import org.dllearner.algorithms.isle.metrics.LLRRelevanceMetric; +import org.dllearner.algorithms.isle.metrics.PMIRelevanceMetric; +import org.dllearner.algorithms.isle.metrics.SCIRelevanceMetric; +import org.dllearner.algorithms.isle.metrics.SignificantPMIRelevanceMetric; +import org.dllearner.algorithms.isle.metrics.TTestRelevanceMetric; + +/** + * @author Lorenz Buehmann + * + */ +public class DefaultRelevanceWeightings extends RelevanceWeightings{ + + public DefaultRelevanceWeightings() { + put(PMIRelevanceMetric.class, 1.0); + put(SignificantPMIRelevanceMetric.class, 1.0); + put(ChiSquareRelevanceMetric.class, 1.0); + put(TTestRelevanceMetric.class, 1.0); + put(JaccardRelevanceMetric.class, 1.0); + put(DiceRelevanceMetric.class, 1.0); + put(SCIRelevanceMetric.class, 1.0); + put(LLRRelevanceMetric.class, 1.0); + } +} Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELLearningAlgorithm.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELLearningAlgorithm.java 2014-05-07 11:25:54 UTC (rev 4261) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELLearningAlgorithm.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -45,6 +45,7 @@ import org.dllearner.learningproblems.EvaluatedDescriptionPosNeg; import org.dllearner.learningproblems.PosNegLP; import org.dllearner.learningproblems.ScorePosNeg; +import org.dllearner.learningproblems.ScoreTwoValued; import org.dllearner.refinementoperators.ELDown3; import org.dllearner.utilities.Helper; import org.dllearner.utilities.owl.EvaluatedDescriptionSet; @@ -148,7 +149,10 @@ @Override public void init() throws ComponentInitException { // currently we use the stable heuristic - heuristic = new StableHeuristic(); + if(heuristic == null){ + heuristic = new StableHeuristic(); + } + candidates = new TreeSet<SearchTreeNode>(heuristic); if(ignoredConcepts != null) { @@ -167,6 +171,13 @@ bestEvaluatedDescriptions = new EvaluatedDescriptionSet(maxNrOfResults); } + /** + * @param heuristic the heuristic to set + */ + public void setHeuristic(ELHeuristic heuristic) { + this.heuristic = heuristic; + } + @Override public void start() { stop = false; @@ -237,7 +248,13 @@ } else { node.setCoveredNegatives(negCovers); } - node.setScore(accuracy); + node.setAccuracy(accuracy); + if(heuristic instanceof RelevanceWeightedStableHeuristic){ + node.setScore(((RelevanceWeightedStableHeuristic)heuristic).getNodeScore(node)); + } else { + node.setScore(accuracy); + } + // System.out.println(description + ":" + accuracy); // link to parent (unless start node) if(parentNode == null) { @@ -259,6 +276,7 @@ // for fully computing the evaluated description if(bestEvaluatedDescriptions.size() == 0 || ((EvaluatedDescriptionPosNeg)bestEvaluatedDescriptions.getWorst()).getCoveredNegatives().size() >= node.getCoveredNegatives()) { ScorePosNeg score = (ScorePosNeg) learningProblem.computeScore(description); + ((ScoreTwoValued)score).setAccuracy(node.getScore()); EvaluatedDescriptionPosNeg ed = new EvaluatedDescriptionPosNeg(description, score); bestEvaluatedDescriptions.add(ed); } @@ -329,7 +347,9 @@ //non of the equivalent classes must occur on the first level TreeSet<Description> toTest = new TreeSet<Description>(descriptionComparator); - toTest.add(classToDescribe); + if(classToDescribe != null){ + toTest.add(classToDescribe); + } while(!toTest.isEmpty()) { Description d = toTest.pollFirst(); if(occursOnFirstLevel(description, d)) { @@ -341,7 +361,9 @@ // none of the superclasses of the class to learn must appear on the // outermost property level TreeSet<Description> toTest = new TreeSet<Description>(descriptionComparator); - toTest.add(classToDescribe); + if(classToDescribe != null){ + toTest.add(classToDescribe); + } while(!toTest.isEmpty()) { Description d = toTest.pollFirst(); if(occursOnFirstLevel(description, d)) { Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightedStableHeuristic.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightedStableHeuristic.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightedStableHeuristic.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -0,0 +1,124 @@ +/** + * Copyright (C) 2007-2011, 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 <http://www.gnu.org/licenses/>. + */ + +package org.dllearner.algorithms.elcopy; + +import java.util.Arrays; +import java.util.List; + +import org.dllearner.algorithms.isle.metrics.RelevanceMetric; +import org.dllearner.core.owl.Description; +import org.dllearner.core.owl.Entity; +import org.dllearner.core.owl.NamedClass; + + +/** + * A stable comparator for search tree nodes. Stable means that the order + * of nodes will not change during the run of the learning algorithm. In + * this implementation, this is ensured by using only covered examples + * and tree size as criteria. + * + * @author Jens Lehmann + * + */ +public class RelevanceWeightedStableHeuristic implements ELHeuristic { + + private ELDescriptionTreeComparator cmp = new ELDescriptionTreeComparator(); + private RelevanceWeightings weightings; + private List<RelevanceMetric> relevanceMetrics; + private NamedClass classToDescribe; + + + public RelevanceWeightedStableHeuristic(NamedClass classToDescribe, RelevanceWeightings weightings, RelevanceMetric... relevanceMetrics) { + this.classToDescribe = classToDescribe; + this.weightings = weightings; + this.relevanceMetrics = Arrays.asList(relevanceMetrics); + } + + public RelevanceWeightedStableHeuristic(NamedClass classToDescribe, RelevanceWeightings weightings, List<RelevanceMetric> relevanceMetrics) { + this.classToDescribe = classToDescribe; + this.weightings = weightings; + this.relevanceMetrics = relevanceMetrics; + } + + public RelevanceWeightedStableHeuristic(NamedClass classToDescribe, RelevanceMetric... relevanceMetrics) { + this(classToDescribe, new DefaultRelevanceWeightings(), relevanceMetrics); + } + + public RelevanceWeightedStableHeuristic(NamedClass classToDescribe, List<RelevanceMetric> relevanceMetrics) { + this(classToDescribe, new DefaultRelevanceWeightings(), relevanceMetrics); + } + + /** + * @param weightings the weightings to set + */ + public void setWeightings(RelevanceWeightings weightings) { + this.weightings = weightings; + } + + /** + * @param relevanceMetrics the relevanceMetrics to set + */ + public void setRelevanceMetrics(List<RelevanceMetric> relevanceMetrics) { + this.relevanceMetrics = relevanceMetrics; + } + + /** + * @param classToDescribe the classToDescribe to set + */ + public void setClassToDescribe(NamedClass classToDescribe) { + this.classToDescribe = classToDescribe; + } + + public double getNodeScore(SearchTreeNode node){ + double score = node.getAccuracy(); + Description d = node.getDescriptionTree().transformToDescription(); + for (RelevanceMetric metric : relevanceMetrics) { + score += weightings.getWeight(metric.getClass()) * metric.getRelevance(classToDescribe, d); + } + return score; + } + + @Override + public int compare(SearchTreeNode o1, SearchTreeNode o2) { + +// int diff = o2.getCoveredNegatives() - o1.getCoveredNegatives(); + double score1 = o1.getScore(); + double score2 = o2.getScore(); + int diff = Double.compare(score1, score2); + if(diff>0) { + return 1; + } else if(diff<0) { + return -1; + } else { + + double sizeDiff = o2.getDescriptionTree().size - o1.getDescriptionTree().size; + + if(sizeDiff == 0) { + return cmp.compare(o1.getDescriptionTree(), o2.getDescriptionTree()); + } else if(sizeDiff>0) { + return 1; + } else { + return -1; + } + + } + } + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightings.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightings.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/RelevanceWeightings.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -0,0 +1,24 @@ +/** + * + */ +package org.dllearner.algorithms.elcopy; + +import java.util.HashMap; + +import org.dllearner.algorithms.isle.metrics.RelevanceMetric; + +/** + * @author Lorenz Buehmann + * + */ +public class RelevanceWeightings extends HashMap<Class<? extends RelevanceMetric>, Double>{ + + public double getWeight(RelevanceMetric metric){ + return get(metric.getClass()); + } + + public double getWeight(Class<? extends RelevanceMetric> metricClass){ + return get(metricClass); + } + +} Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/SearchTreeNode.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/SearchTreeNode.java 2014-05-07 11:25:54 UTC (rev 4261) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/SearchTreeNode.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -38,6 +38,7 @@ private boolean tooWeak = false; private double score; + protected double accuracy; public SearchTreeNode(ELDescriptionTree descriptionTree) { this.descriptionTree = descriptionTree; @@ -127,4 +128,18 @@ this.score = score; } + /** + * @return the accuracy + */ + public double getAccuracy() { + return accuracy; + } + + /** + * @param accuracy the accuracy to set + */ + public void setAccuracy(double accuracy) { + this.accuracy = accuracy; + } + } Added: trunk/components-core/src/main/java/org/dllearner/algorithms/isle/index/syntactic/EntityFrequencyCache.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/isle/index/syntactic/EntityFrequencyCache.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/isle/index/syntactic/EntityFrequencyCache.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -0,0 +1,17 @@ +/** + * + */ +package org.dllearner.algorithms.isle.index.syntactic; + +import java.util.HashMap; +import java.util.Set; + +import org.dllearner.core.owl.Entity; + +/** + * @author Lorenz Buehmann + * + */ +public class EntityFrequencyCache extends HashMap<Set<Entity>, Long>{ + +} Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/AbstractRelevanceMetric.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/AbstractRelevanceMetric.java 2014-05-07 11:25:54 UTC (rev 4261) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/AbstractRelevanceMetric.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -5,8 +5,10 @@ import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.dllearner.algorithms.isle.index.Index; +import org.dllearner.core.owl.Description; import org.dllearner.core.owl.Entity; /** @@ -16,9 +18,12 @@ public abstract class AbstractRelevanceMetric implements RelevanceMetric { protected Index index; + protected String name; public AbstractRelevanceMetric(Index index) { this.index = index; + + name = getClass().getSimpleName().replace("RelevanceMetric", ""); } public static Map<Entity, Double> normalizeMinMax(Map<Entity, Double> hmEntity2Score) { @@ -53,5 +58,47 @@ } return hmEntity2Norm; } + + public String getName() { + return name; + } + + public double getRelevance(Entity entity, Description desc){ + Set<Entity> entities = desc.getSignature(); + double score = 0; + for (Entity otherEntity : entities) { + double relevance = getRelevance(entity, otherEntity); + if(!Double.isInfinite(relevance)){ + score += relevance/entities.size(); + } + } + return score; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AbstractRelevanceMetric other = (AbstractRelevanceMetric) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + } Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/RelevanceMetric.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/RelevanceMetric.java 2014-05-07 11:25:54 UTC (rev 4261) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/RelevanceMetric.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -20,6 +20,7 @@ package org.dllearner.algorithms.isle.metrics; +import org.dllearner.core.owl.Description; import org.dllearner.core.owl.Entity; @@ -38,4 +39,6 @@ * @return */ double getNormalizedRelevance(Entity entity1, Entity entity2); + + double getRelevance(Entity entity, Description desc); } \ No newline at end of file Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2Disjunctive.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2Disjunctive.java 2014-05-07 11:25:54 UTC (rev 4261) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2Disjunctive.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -1,5 +1,6 @@ package org.dllearner.algorithms.qtl; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -28,14 +29,19 @@ import org.dllearner.core.ComponentInitException; import org.dllearner.core.EvaluatedDescription; import org.dllearner.core.KnowledgeSource; +import org.dllearner.core.LearningProblem; import org.dllearner.core.LearningProblemUnsupportedException; +import org.dllearner.core.Score; +import org.dllearner.core.config.ConfigOption; import org.dllearner.core.owl.Description; import org.dllearner.core.owl.Individual; import org.dllearner.core.owl.Union; +import org.dllearner.kb.OWLAPIOntology; import org.dllearner.kb.OWLFile; import org.dllearner.learningproblems.Heuristics; import org.dllearner.learningproblems.PosNegLP; import org.dllearner.learningproblems.QueryTreeScore; +import org.dllearner.learningproblems.ScoreTwoValued; import org.dllearner.utilities.owl.DLLearnerDescriptionConvertVisitor; import org.dllearner.utilities.owl.OWLAPIConverter; import org.semanticweb.owlapi.io.ToStringRenderer; @@ -51,12 +57,12 @@ import com.jamonapi.MonitorFactory; @ComponentAnn(name="query tree learner with noise (disjunctive)", shortName="qtl2dis", version=0.8) -public class QTL2Disjunctive extends AbstractCELA { +public class QTL2Disjunctive extends AbstractCELA implements Cloneable{ private static final Logger logger = Logger.getLogger(QTL2Disjunctive.class.getName()); - private LGGGenerator<String> lggGenerator = new LGGGeneratorImpl<String>(); + private LGGGenerator<String> lggGenerator; private Queue<EvaluatedQueryTree<String>> todoList; private SortedSet<EvaluatedQueryTree<String>> currentPartialSolutions; @@ -69,9 +75,6 @@ private Set<Individual> currentNegExamples; private Map<QueryTree<String>, Individual> tree2Individual; - - private double coverageWeight = 0.8; - private double specifityWeight = 0.2; private QueryTreeCache treeCache; @@ -79,8 +82,6 @@ private Model model; - private AbstractReasonerComponent reasoner; - private volatile boolean stop; private boolean isRunning; @@ -89,16 +90,39 @@ private List<EvaluatedQueryTree<String>> partialSolutions; + private EvaluatedDescription currentBestSolution; + + + + //Parameters + @ConfigOption(name = "noisePercentage", defaultValue="0.0", description="the (approximated) percentage of noise within the examples") + private double noisePercentage = 0.0; + @ConfigOption(defaultValue = "10", name = "maxExecutionTimeInSeconds", description = "maximum execution of the algorithm in seconds") + private int maxExecutionTimeInSeconds = 10; + private double minimumTreeScore = 0.2; + private double coverageWeight = 0.8; + private double specifityWeight = 0.1; + private double noise = 0.3; + private double coverageBeta = 0.7; + + private double posExampleWeight = 1; + public QTL2Disjunctive() {} public QTL2Disjunctive(PosNegLP learningProblem, AbstractReasonerComponent reasoner) throws LearningProblemUnsupportedException{ - this.lp = learningProblem; - this.reasoner = reasoner; + super(learningProblem, reasoner); + loadModel(); } - public QTL2Disjunctive(PosNegLP lp, Model model) { - this.lp = lp; - this.model = model; +// public QTL2Disjunctive(PosNegLP lp, Model model) { +// this.learningProblem = lp; +// this.model = model; +// } + + public QTL2Disjunctive(QTL2Disjunctive qtl) { + super(qtl.getLearningProblem(), qtl.getReasoner()); + this.model = ModelFactory.createDefaultModel(); + this.model.add(qtl.model); } public EvaluatedQueryTree<String> getBestSolution(){ @@ -110,6 +134,14 @@ */ @Override public void init() throws ComponentInitException { + + if(!(learningProblem instanceof PosNegLP)){ + throw new IllegalArgumentException("Only PosNeg learning problems are supported"); + } + lp = (PosNegLP) learningProblem; + + lggGenerator = new LGGGeneratorImpl<String>(); + logger.info("Initializing..."); treeCache = new QueryTreeCache(model); tree2Individual = new HashMap<QueryTree<String>, Individual>(lp.getPositiveExamples().size()+lp.getNegativeExamples().size()); @@ -120,6 +152,18 @@ currentNegExamples = new TreeSet<Individual>(lp.getNegativeExamples()); //get the query trees + generateTrees(); + + //some logging + subMon = MonitorFactory.getTimeMonitor("subsumption-mon"); + lggMon = MonitorFactory.getTimeMonitor("lgg-mon"); + + //console rendering of class expressions + ToStringRenderer.getInstance().setRenderer(new ManchesterOWLSyntaxOWLObjectRendererImpl()); + ToStringRenderer.getInstance().setShortFormProvider(new SimpleShortFormProvider()); + } + + private void generateTrees(){ QueryTree<String> queryTree; for (Individual ind : lp.getPositiveExamples()) { queryTree = treeCache.getQueryTree(ind.getName()); @@ -131,14 +175,6 @@ tree2Individual.put(queryTree, ind); currentNegExampleTrees.add(queryTree); } - - //some logging - subMon = MonitorFactory.getTimeMonitor("subsumption-mon"); - lggMon = MonitorFactory.getTimeMonitor("lgg-mon"); - - //console rendering of class expressions - ToStringRenderer.getInstance().setRenderer(new ManchesterOWLSyntaxOWLObjectRendererImpl()); - ToStringRenderer.getInstance().setShortFormProvider(new SimpleShortFormProvider()); } /* (non-Javadoc) @@ -146,6 +182,11 @@ */ @Override public void start() { + String setup = "Setup:"; + setup += "#Pos. examples:" + currentPosExamples.size(); + setup += "#Neg. examples:" + currentNegExamples.size(); + setup += "Coverage beta:" + coverageBeta; + logger.info(setup); logger.info("Running..."); long startTime = System.currentTimeMillis(); @@ -180,6 +221,7 @@ currentNegExamples.remove(tree2Individual.get(tree)); } } + currentBestSolution = buildCombinedSolution(); } while (!(stop || currentPosExampleTrees.isEmpty())); isRunning = false; @@ -187,22 +229,53 @@ long endTime = System.currentTimeMillis(); logger.info("Finished in " + (endTime-startTime) + "ms."); - EvaluatedDescription combinedSolution = buildCombinedSolution(); - System.out.println(OWLAPIConverter.getOWLAPIDescription(combinedSolution.getDescription())); + logger.info("Combined solution:\n" + OWLAPIConverter.getOWLAPIDescription(currentBestSolution.getDescription())); + logger.info(currentBestSolution.getScore()); } private EvaluatedDescription buildCombinedSolution(){ + if(partialSolutions.size() == 1){ + EvaluatedDescription combinedSolution = partialSolutions.get(0).asEvaluatedDescription(); + double accuracy = lp.getAccuracy(combinedSolution.getDescription()); + System.out.println(accuracy); + return combinedSolution; + } List<Description> disjuncts = new ArrayList<Description>(); + + Set<Individual> posCovered = new HashSet<Individual>(); + Set<Individual> negCovered = new HashSet<Individual>(); + + //build the union of all class expressions Description partialDescription; for (EvaluatedQueryTree<String> partialSolution : partialSolutions) { partialDescription = DLLearnerDescriptionConvertVisitor.getDLLearnerDescription( partialSolution.getTree().asOWLClassExpression(LiteralNodeConversionStrategy.FACET_RESTRICTION)); disjuncts.add(partialDescription); + posCovered.addAll(partialSolution.getTreeScore().getCoveredPositives()); + negCovered.addAll(partialSolution.getTreeScore().getCoveredNegatives()); } Description unionDescription = new Union(disjuncts); - return new EvaluatedDescription(unionDescription, null); + Set<Individual> posNotCovered = Sets.difference(lp.getPositiveExamples(), posCovered); + Set<Individual> negNotCovered = Sets.difference(lp.getNegativeExamples(), negCovered); + + double accuracy = lp.getAccuracy(unionDescription); + System.out.println(accuracy); + + //compute the coverage + double recall = posCovered.size() / (double)lp.getPositiveExamples().size(); + double precision = (posCovered.size() + negCovered.size() == 0) + ? 0 + : posCovered.size() / (double)(posCovered.size() + negCovered.size()); + + double coverageScore = Heuristics.getFScore(recall, precision, coverageBeta); + +// ScoreTwoValued score = new ScoreTwoValued(posCovered, posNotCovered, negCovered, negNotCovered); +// score.setAccuracy(coverageScore); + QueryTreeScore score = new QueryTreeScore(coverageScore, coverageScore, posCovered, posNotCovered, negCovered, negNotCovered, -1, -1); + + return new EvaluatedDescription(unionDescription, score); } private void reset(){ @@ -216,6 +289,7 @@ } private void computeLGG(){ + logger.info("Computing best partial solution..."); currentlyBestScore = 0d; initTodoList(currentPosExampleTrees, currentNegExampleTrees); @@ -246,16 +320,17 @@ } currentlyBestScore = solution.getScore(); } + currentPartialSolutions.add(currentElement); } currentPartialSolutions.add(currentElement); // todoList.remove(currentElement); } while(!terminationCriteriaSatisfied()); long endTime = System.currentTimeMillis(); - logger.info("Finished in " + (endTime-startTime) + "ms."); - EvaluatedDescription bestSolution = getCurrentlyBestEvaluatedDescription(); + logger.info("...finished in " + (endTime-startTime) + "ms."); + EvaluatedDescription bestPartialSolution = currentPartialSolutions.first().asEvaluatedDescription(); - logger.info("Best solution:\n" + OWLAPIConverter.getOWLAPIDescription(bestSolution.getDescription()) + "\n(" + bestSolution.getScore() + ")"); + logger.info("Best partial solution:\n" + OWLAPIConverter.getOWLAPIDescription(bestPartialSolution.getDescription()) + "\n(" + bestPartialSolution.getScore() + ")"); logger.trace("LGG time: " + lggMon.getTotal() + "ms"); logger.trace("Avg. LGG time: " + lggMon.getAvg() + "ms"); @@ -278,7 +353,7 @@ */ @Override public Description getCurrentlyBestDescription() { - return getCurrentlyBestEvaluatedDescription().getDescription(); + return currentBestSolution.getDescription(); } /* (non-Javadoc) @@ -286,8 +361,7 @@ */ @Override public EvaluatedDescription getCurrentlyBestEvaluatedDescription() { - EvaluatedQueryTree<String> bestSolution = currentPartialSolutions.first(); - return bestSolution.asEvaluatedDescription(); + return currentBestSolution; } /* (non-Javadoc) @@ -298,14 +372,18 @@ return isRunning; } +// @Autowired +// public void setLearningProblem(PosNegLP learningProblem) { +// this.lp = learningProblem; +// } + @Autowired - public void setLearningProblem(PosNegLP learningProblem) { - this.lp = learningProblem; + public void setReasoner(AbstractReasonerComponent reasoner){ + super.setReasoner(reasoner); + loadModel(); } - @Autowired - public void setReasoner(AbstractReasonerComponent reasoner){ - this.reasoner = reasoner; + private void loadModel(){ model = ModelFactory.createDefaultModel(); for (KnowledgeSource ks : reasoner.getSources()) { if(ks instanceof OWLFile){ @@ -314,6 +392,14 @@ } catch (IOException e) { e.printStackTrace(); } + } else if(ks instanceof OWLAPIOntology){ + ByteArrayInputStream bais = new ByteArrayInputStream(((OWLAPIOntology) ks).getConverter().convert(((OWLAPIOntology) ks).getOntology())); + model.read(bais, null); + try { + bais.close(); + } catch (IOException e) { + e.printStackTrace(); + } } } } @@ -328,14 +414,14 @@ private EvaluatedQueryTree<String> evaluate(QueryTree<String> tree, boolean useSpecifity){ //1. get a score for the coverage = recall oriented //compute positive examples which are not covered by LGG - Set<QueryTree<String>> uncoveredPositiveExampleTrees = getUncoveredTrees(tree, currentPosExampleTrees); - Set<Individual> uncoveredPosExamples = new HashSet<Individual>(); + List<QueryTree<String>> uncoveredPositiveExampleTrees = getUncoveredTrees(tree, currentPosExampleTrees); + Set<Individual> uncoveredPosExamples = new TreeSet<Individual>(); for (QueryTree<String> queryTree : uncoveredPositiveExampleTrees) { uncoveredPosExamples.add(tree2Individual.get(queryTree)); } //compute negative examples which are covered by LGG Collection<QueryTree<String>> coveredNegativeExampleTrees = getCoveredTrees(tree, currentNegExampleTrees); - Set<Individual> coveredNegExamples = new HashSet<Individual>(); + Set<Individual> coveredNegExamples = new TreeSet<Individual>(); for (QueryTree<String> queryTree : coveredNegativeExampleTrees) { coveredNegExamples.add(tree2Individual.get(queryTree)); } @@ -346,7 +432,8 @@ ? 0 : coveredPositiveExamples / (double)(coveredPositiveExamples + coveredNegativeExampleTrees.size()); - double coverageScore = Heuristics.getFScore(recall, precision); + double beta = 0.5; + double coverageScore = Heuristics.getFScore(recall, precision, beta); //2. get a score for the specifity of the query, i.e. how many edges/nodes = precision oriented int nrOfSpecificNodes = 0; @@ -364,8 +451,8 @@ double score = coverageWeight * coverageScore + specifityWeight * specifityScore; QueryTreeScore queryTreeScore = new QueryTreeScore(score, coverageScore, - Sets.difference(currentPosExamples, uncoveredPosExamples), uncoveredPosExamples, - coveredNegExamples, Sets.difference(currentNegExamples, coveredNegExamples), + new TreeSet<Individual>(Sets.difference(currentPosExamples, uncoveredPosExamples)), uncoveredPosExamples, + coveredNegExamples, new TreeSet<Individual>(Sets.difference(currentNegExamples, coveredNegExamples)), specifityScore, nrOfSpecificNodes); // QueryTreeScore queryTreeScore = new QueryTreeScore(score, coverageScore, @@ -400,8 +487,8 @@ * @param allTrees * @return */ - private Set<QueryTree<String>> getUncoveredTrees(QueryTree<String> tree, List<QueryTree<String>> allTrees){ - Set<QueryTree<String>> uncoveredTrees = new LinkedHashSet<QueryTree<String>>(); + private List<QueryTree<String>> getUncoveredTrees(QueryTree<String> tree, List<QueryTree<String>> allTrees){ + List<QueryTree<String>> uncoveredTrees = new ArrayList<QueryTree<String>>(); for (QueryTree<String> queryTree : allTrees) { boolean subsumed = queryTree.isSubsumedBy(tree); if(!subsumed){ @@ -470,4 +557,33 @@ } todoList.add(solution); } + + /** + * @param noisePercentage the noisePercentage to set + */ + public void setNoisePercentage(double noisePercentage) { + this.noisePercentage = noisePercentage; + } + + /** + * @param maxExecutionTimeInSeconds the maxExecutionTimeInSeconds to set + */ + public void setMaxExecutionTimeInSeconds(int maxExecutionTimeInSeconds) { + this.maxExecutionTimeInSeconds = maxExecutionTimeInSeconds; + } + + /** + * @param coverageBeta the coverageBeta to set + */ + public void setCoverageBeta(double coverageBeta) { + this.coverageBeta = coverageBeta; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + @Override + public Object clone() throws CloneNotSupportedException { + return new QTL2Disjunctive(this); + } } Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2DisjunctiveMT.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2DisjunctiveMT.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL2DisjunctiveMT.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -0,0 +1,559 @@ +package org.dllearner.algorithms.qtl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.apache.log4j.Logger; +import org.dllearner.algorithms.qtl.cache.QueryTreeCache; +import org.dllearner.algorithms.qtl.datastructures.QueryTree; +import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeImpl; +import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeImpl.LiteralNodeConversionStrategy; +import org.dllearner.algorithms.qtl.operations.lgg.EvaluatedQueryTree; +import org.dllearner.algorithms.qtl.operations.lgg.LGGGenerator; +import org.dllearner.algorithms.qtl.operations.lgg.LGGGeneratorImpl; +import org.dllearner.core.AbstractCELA; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentInitException; +import org.dllearner.core.EvaluatedDescription; +import org.dllearner.core.KnowledgeSource; +import org.dllearner.core.LearningProblemUnsupportedException; +import org.dllearner.core.owl.Description; +import org.dllearner.core.owl.Individual; +import org.dllearner.kb.OWLFile; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.learningproblems.QueryTreeScore; +import org.dllearner.utilities.owl.DLLearnerDescriptionConvertVisitor; +import org.dllearner.utilities.owl.OWLAPIConverter; +import org.semanticweb.owlapi.io.ToStringRenderer; +import org.semanticweb.owlapi.util.SimpleShortFormProvider; +import org.springframework.beans.factory.annotation.Autowired; + +import uk.ac.manchester.cs.owl.owlapi.mansyntaxrenderer.ManchesterOWLSyntaxOWLObjectRendererImpl; + +import com.google.common.collect.Sets; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.jamonapi.Monitor; +import com.jamonapi.MonitorFactory; + +@ComponentAnn(name="query tree learner with noise (disjunctive)", shortName="qtl2dis", version=0.8) +public class QTL2DisjunctiveMT extends AbstractCELA { + + + private static final Logger logger = Logger.getLogger(QTL2DisjunctiveMT.class.getName()); + + private LGGGenerator<String> lggGenerator = new LGGGeneratorImpl<String>(); + + private BlockingQueue<EvaluatedQueryTree<String>> todoList; + private SortedSet<EvaluatedQueryTree<String>> solutions; + + private double currentlyBestScore = 0d; + + private List<QueryTree<String>> currentPosExampleTrees; + private List<QueryTree<String>> currentNegExampleTrees; + + private Map<QueryTree<String>, Individual> tree2Indivual; + + private double coverageWeight = 0.8; + private double specifityWeight = 0.2; + + private QueryTreeCache treeCache; + + private PosNegLP lp; + + private Model model; + + private AbstractReasonerComponent reasoner; + + private volatile boolean stop; + private boolean isRunning; + + private Monitor subMon; + private Monitor lggMon; + + private final EvaluatedQueryTree<String> STOP_ELEMENT = new EvaluatedQueryTree<String>(new QueryTreeImpl<String>("STOP"), null, null, null); + + + public QTL2DisjunctiveMT() {} + + public QTL2DisjunctiveMT(PosNegLP learningProblem, AbstractReasonerComponent reasoner) throws LearningProblemUnsupportedException{ + this.lp = learningProblem; + this.reasoner = reasoner; + + } + + public QTL2DisjunctiveMT(PosNegLP lp, Model model) { + this.lp = lp; + this.model = model; + } + + public EvaluatedQueryTree<String> getBestSolution(){ + return solutions.first(); + } + + /* (non-Javadoc) + * @see org.dllearner.core.Component#init() + */ + @Override + public void init() throws ComponentInitException { + logger.info("Initializing..."); + treeCache = new QueryTreeCache(model); + tree2Indivual = new HashMap<QueryTree<String>, Individual>(lp.getPositiveExamples().size()+lp.getNegativeExamples().size()); + + currentPosExampleTrees = new ArrayList<QueryTree<String>>(lp.getPositiveExamples().size()); + currentNegExampleTrees = new ArrayList<QueryTree<String>>(lp.getNegativeExamples().size()); + + //get the query trees + QueryTree<String> queryTree; + for (Individual ind : lp.getPositiveExamples()) { + queryTree = treeCache.getQueryTree(ind.getName()); + tree2Indivual.put(queryTree, ind); + currentPosExampleTrees.add(queryTree); + } + for (Individual ind : lp.getNegativeExamples()) { + queryTree = treeCache.getQueryTree(ind.getName()); + tree2Indivual.put(queryTree, ind); + currentNegExampleTrees.add(treeCache.getQueryTree(ind.getName())); + } + + //some logging + subMon = MonitorFactory.getTimeMonitor("subsumption-mon"); + lggMon = MonitorFactory.getTimeMonitor("lgg-mon"); + + //console rendering of class expressions + ToStringRenderer.getInstance().setRenderer(new ManchesterOWLSyntaxOWLObjectRendererImpl()); + ToStringRenderer.getInstance().setShortFormProvider(new SimpleShortFormProvider()); + } + + /* (non-Javadoc) + * @see org.dllearner.core.LearningAlgorithm#start() + */ + @Override + public void start() { + logger.info("Running..."); + stop = false; + isRunning = true; + long startTime = System.currentTimeMillis(); + + subMon = MonitorFactory.getTimeMonitor("subsumption-mon"); + lggMon = MonitorFactory.getTimeMonitor("lgg-mon"); + + + //outer loop: compute LGG, pick best solution and remove all covered positive and negative examples + List<EvaluatedQueryTree<String>> unionSolutions = new ArrayList<EvaluatedQueryTree<String>>(); + do { + //compute LGG + computeLGG(); + + //pick best solution computed so far + EvaluatedQueryTree<String> bestSolution = solutions.first(); + unionSolutions.add(bestSolution); + logger.info("#Uncovered pos. examples:" + bestSolution.getFalseNegatives().size()); + + //remove all covered examples + QueryTree<String> tree; + for (Iterator<QueryTree<String>> iterator = currentPosExampleTrees.iterator(); iterator.hasNext();) { + tree = iterator.next(); + if(tree.isSubsumedBy(bestSolution.getTree())){ + iterator.remove(); + } + } + for (Iterator<QueryTree<String>> iterator = currentNegExampleTrees.iterator(); iterator.hasNext();) { + tree = iterator.next(); + if(tree.isSubsumedBy(bestSolution.getTree())){ + iterator.remove(); + } + } + } while (!(stop || currentPosExampleTrees.isEmpty())); + + + } + + private void computeLGG(){ + currentlyBestScore = 0d; + initTodoList(currentPosExampleTrees, currentNegExampleTrees); + long startTime = System.currentTimeMillis(); + int nrOfThreads = Runtime.getRuntime().availableProcessors() - 1; + nrOfThreads = 2; + ExecutorService es = Executors.newFixedThreadPool(nrOfThreads); + for(int i = 0; i < nrOfThreads; i++){ + es.submit(new QueryTreeProcessor()); + } + es.shutdown(); + try { + es.awaitTermination(1, TimeUnit.HOURS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + long endTime = System.currentTimeMillis(); + logger.info("Finished in " + (endTime-startTime) + "ms."); + EvaluatedDescription bestSolution = getCurrentlyBestEvaluatedDescription(); + ToStringRenderer.getInstance().setRenderer(new ManchesterOWLSyntaxOWLObjectRendererImpl()); + ToStringRenderer.getInstance().setShortFormProvider(new SimpleShortFormProvider()); +// solutions.first().getTree().dump(); + logger.info("Best solution:\n" + OWLAPIConverter.getOWLAPIDescription(bestSolution.getDescription()) + "\n(" + bestSolution.getScore() + ")"); + + logger.trace("LGG time: " + lggMon.getTotal() + "ms"); + logger.trace("Avg. LGG time: " + lggMon.getAvg() + "ms"); + logger.trace("#LGG computations: " + lggMon.getHits()); + logger.trace("Subsumption test time: " + subMon.getTotal() + "ms"); + logger.trace("Avg. subsumption test time: " + subMon.getAvg() + "ms"); + logger.trace("#Subsumption tests: " + subMon.getHits()); + } + + /* (non-Javadoc) + * @see org.dllearner.core.StoppableLearningAlgorithm#stop() + */ + @Override + public void stop() { + stop = true; + } + + /* (non-Javadoc) + * @see org.dllearner.core.AbstractCELA#getCurrentlyBestDescription() + */ + @Override + public Description getCurrentlyBestDescription() { + return getCurrentlyBestEvaluatedDescription().getDescription(); + } + + /* (non-Javadoc) + * @see org.dllearner.core.AbstractCELA#getCurrentlyBestEvaluatedDescription() + */ + @Override + public EvaluatedDescription getCurrentlyBestEvaluatedDescription() { + EvaluatedQueryTree<String> bestSolution = solutions.first(); + Description description = DLLearnerDescriptionConvertVisitor.getDLLearnerDescription( + bestSolution.getTree().asOWLClassExpression(LiteralNodeConversionStrategy.FACET_RESTRICTION)); + return new EvaluatedDescription(description, bestSolution.getTreeScore()); + } + + /* (non-Javadoc) + * @see org.dllearner.core.StoppableLearningAlgorithm#isRunning() + */ + @Override + public boolean isRunning() { + return isRunning; + } + + @Autowired + public void setLearningProblem(PosNegLP learningProblem) { + this.lp = learningProblem; + } + + @Autowired + public void setReasoner(AbstractReasonerComponent reasoner){ + this.reasoner = reasoner; + model = ModelFactory.createDefaultModel(); + for (KnowledgeSource ks : reasoner.getSources()) { + if(ks instanceof OWLFile){ + try { + model.read(((OWLFile) ks).getURL().openStream(), null); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * @return the treeCache + */ + public QueryTreeCache getTreeCache() { + return treeCache; + } + + private EvaluatedQueryTree<String> evaluate(QueryTree<String> tree, boolean useSpecifity){ + //1. get a score for the coverage = recall oriented + //compute positive examples which are not covered by LGG + Collection<QueryTree<String>> uncoveredPositiveExampleTrees = getUncoveredTrees(tree, currentPosExampleTrees); + Set<Individual> uncoveredPosExamples = new HashSet<Individual>(); + for (QueryTree<String> queryTree : uncoveredPositiveExampleTrees) { + uncoveredPosExamples.add(tree2Indivual.get(queryTree)); + } + //compute negative examples which are covered by LGG + Collection<QueryTree<String>> coveredNegativeExampleTrees = getCoveredTrees(tree, currentNegExampleTrees); + Set<Individual> coveredNegExamples = new HashSet<Individual>(); + for (QueryTree<String> queryTree : coveredNegativeExampleTrees) { + coveredNegExamples.add(tree2Indivual.get(queryTree)); + } + //compute score + int coveredPositiveExamples = currentPosExampleTrees.size() - uncoveredPositiveExampleTrees.size(); + double recall = coveredPositiveExamples / (double)currentPosExampleTrees.size(); + double precision = (coveredNegativeExampleTrees.size() + coveredPositiveExamples == 0) + ? 0 + : coveredPositiveExamples / (double)(coveredPositiveExamples + coveredNegativeExampleTrees.size()); + + double coverageScore = recall;//Heuristics.getFScore(recall, precision); + + //2. get a score for the specifity of the query, i.e. how many edges/nodes = precision oriented + int nrOfSpecificNodes = 0; + for (QueryTree<String> childNode : tree.getChildrenClosure()) { + if(!childNode.getUserObject().equals("?")){ + nrOfSpecificNodes++; + } + } + double specifityScore = Math.log(nrOfSpecificNodes); + + //3.compute the total score + double score = coverageWeight * coverageScore + specifityWeight * specifityScore; + + QueryTreeScore queryTreeScore = new QueryTreeScore(score, coverageScore, + uncoveredPosExamples, Sets.difference(lp.getPositiveExamples(), uncoveredPosExamples), + coveredNegExamples, Sets.difference(lp.getNegativeExamples(), coveredNegExamples), + specifityScore, nrOfSpecificNodes); + + EvaluatedQueryTree<String> evaluatedTree = new EvaluatedQueryTree<String>(tree, uncoveredPositiveExampleTrees, coveredNegativeExampleTrees, queryTreeScore); + + return evaluatedTree; + } + + /** + * Initializes the todo list with all distinct trees contained in the given list {@code trees}. + * Firstly, distinct trees are computed and afterwards, for each tree a score is computed. + * @param trees + */ + private void initTodoList(List<QueryTree<String>> posExamples, List<QueryTree<String>> negExamples){ + todoList = new PriorityBlockingQueue<EvaluatedQueryTree<String>>(); + solutions = new TreeSet<EvaluatedQueryTree<String>>(); +// EvaluatedQueryTree<String> dummy = new EvaluatedQueryTree<String>(new QueryTreeImpl<String>((N)"TOP"), trees, 0d); +// todoList.add(dummy); + //compute distinct trees + Collection<QueryTree<String>> distinctTrees = new ArrayList<QueryTree<String>>(); + for (QueryTree<String> queryTree : posExamples) { + boolean distinct = true; + for (QueryTree<String> otherTree : distinctTrees) { + if(!queryTree.equals(otherTree)){ + if(queryTree.isSameTreeAs(otherTree)){ + distinct = false; + break; + } + } + } + if(distinct){ + distinctTrees.add(queryTree); + } + } + for (QueryTree<String> queryTree : distinctTrees) {//System.out.println(queryTree.getStringRepresentation()); + EvaluatedQueryTree<String> evaluatedQueryTree = evaluate(queryTree, false); + todoList.add(evaluatedQueryTree); + } + } + + /** + * Return all trees from the given list {@code allTrees} which are not already subsumed by {@code tree}. + * @param tree + * @param allTrees + * @return + */ + private Collection<QueryTree<String>> getCoveredTrees(QueryTree<String> tree, List<QueryTree<String>> trees){ + Collection<QueryTree<String>> coveredTrees = new ArrayList<QueryTree<String>>(); + for (QueryTree<String> queryTree : trees) { + boolean subsumed = queryTree.isSubsumedBy(tree); + if(subsumed){ + coveredTrees.add(queryTree); + } + } + return coveredTrees; + } + + /** + * Return all trees from the given list {@code allTrees} which are not already subsumed by {@code tree}. + * @param tree + * @param allTrees + * @return + */ + private Collection<QueryTree<String>> getUncoveredTrees(QueryTree<String> tree, List<QueryTree<String>> allTrees){ + Collection<QueryTree<String>> uncoveredTrees = new ArrayList<QueryTree<String>>(); + for (QueryTree<String> queryTree : allTrees) { + boolean subsumed = queryTree.isSubsumedBy(tree); + if(!subsumed){ + uncoveredTrees.add(queryTree); + } + } + return uncoveredTrees; + } + + private boolean sameTrees(QueryTree<String> tree1, QueryTree<String> tree2){ + return tree1.isSubsumedBy(tree2) && tree2.isSubsumedBy(tree1); + } + + private synchronized boolean terminationCriteriaSatisfied(){ + return stop || todoList.isEmpty() || currentPosExampleTrees.isEmpty(); + } + + /** + * Add tree to todo list if not already contained in that list or the solutions. + * @param solution + */ + private void todo(EvaluatedQueryTree<String> solution){ + //check if not already contained in todo list + for (EvaluatedQueryTree<String> evTree : todoList) { + if(sameTrees(solution.getTree(), evTree.getTree())){ + return; + } + } + //check if not already contained in solutions + for (EvaluatedQueryTree<String> evTree : solutions) { + if(sameTrees(solution.getTree(), evTree.getTree())){ + return; + } + } + try { + todoList.put(solution); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + class QueryTreeProcessor implements Runnable { + + volatile boolean isRunning; + LGGGenerator<String> lggGenerator = new LGGGeneratorImpl<String>(); + + /** + * + */ + public QueryTreeProcessor() { + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + long startTime = System.currentTimeMillis(); + while(!terminationCriteriaSatisfied()){ + double currentlyBestScore = 0d; + try { + long t1 = System.currentTimeMillis(); + EvaluatedQueryTree<String> evaluatedQueryTree = todoList.take(); + long t2 = System.currentTimeMillis(); + System.out.println(Thread.currentThread().getId() + "\t waiting time:" + (t2-t1)); + for (QueryTree<String> example : evaluatedQueryTree.getFalseNegatives()) { + //compute the LGG +// lggMon.start(); + QueryTree<String> lgg = lggGenerator.getLGG(evaluatedQueryTree.getTree(), example); +// lggMon.stop(); + + //evaluate the LGG + EvaluatedQueryTree<String> solution = evaluate(lgg, true); + + if(solution.getScore() >= currentlyBestScore){ + //add to todo list, if not already contained in todo list or solution list + todo(solution); + if(solution.getScore() > currentlyBestScore){ + logger.info("Got better solution:" + solution.getTreeScore()); + } + currentlyBestScore = solution.getScore(); + } + } + long t3 = System.currentTimeMillis(); + System.out.println(Thread.currentThread().getId() + "\t processing time:" + (t3-t2)); + // add currently processed tree to solutions + solutions.add(evaluatedQueryTree); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println(System.currentTimeMillis() + ":" + Thread.currentThread().getId() + " finished"); + } + + private EvaluatedQueryTree<String> evaluate(QueryTree<String> tree, boolean useSpecifity){ + //1. get a score for the coverage = recall oriented + //compute positive examples which are not covered by LGG + Collection<QueryTree<String>> uncoveredPositiveExampleTrees = getUncoveredTrees(tree, currentPosExampleTrees); + Set<Individual> uncoveredPosExamples = new HashSet<Individual>(); + for (QueryTree<String> queryTree : uncoveredPositiveExampleTrees) { + uncoveredPosExamples.add(tree2Indivual.get(queryTree)); + } + //compute negative examples which are covered by LGG + Collection<QueryTree<String>> coveredNegativeExampleTrees = getCoveredTrees(tree, currentNegExampleTrees); + Set<Individual> coveredNegExamples = new HashSet<Individual>(); + for (QueryTree<String> queryTree : coveredNegativeExampleTrees) { + coveredNegExamples.add(tree2Indivual.get(queryTree)); + } + //compute score + int coveredPositiveExamples = currentPosExampleTrees.size() - uncoveredPositiveExampleTrees.size(); + double recall = coveredPositiveExamples / (double)currentPosExampleTrees.size(); + double precision = (coveredNegativeExampleTrees.size() + coveredPositiveExamples == 0) + ? 0 + : coveredPositiveExamples / (double)(coveredPositiveExamples + coveredNegativeExampleTrees.size()); + + double coverageScore = recall;//Heuristics.getFScore(recall, precision); + + //2. get a score for the specifity of the query, i.e. how many edges/nodes = precision oriented + int nrOfSpecificNodes = 0; + for (QueryTree<String> childNode : tree.getChildrenClosure()) { + if(!childNode.getUserObject().equals("?")){ + nrOfSpecificNodes++; + } + } + double specifityScore = Math.log(nrOfSpecificNodes); + + //3.compute the total score + double score = coverageWeight * coverageScore + specifityWeight * specifityScore; + + QueryTreeScore queryTreeScore = new QueryTreeScore(score, coverageScore, + uncoveredPosExamples, Sets.difference(lp.getPositiveExamples(), uncoveredPosExamples), + coveredNegExamples, Sets.difference(lp.getNegativeExamples(), coveredNegExamples), + specifityScore, nrOfSpecificNodes); + + EvaluatedQueryTree<String> evaluatedTree = new EvaluatedQueryTree<String>(tree, uncoveredPositiveExampleTrees, coveredNegativeExampleTrees, queryTreeScore); + + return evaluatedTree; + } + + /** + * Return all trees from the given list {@code allTrees} which are not already subsumed by {@code tree}. + * @param tree + * @param allTrees + * @return + */ + private Collection<QueryTree<String>> getCoveredTrees(QueryTree<String> tree, List<QueryTree<String>> trees){ + Collection<QueryTree<String>> coveredTrees = new ArrayList<QueryTree<String>>(); + for (QueryTree<String> queryTree : trees) { + boolean subsumed = queryTree.isSubsumedBy(tree); + if(subsumed){ + coveredTrees.add(queryTree); + } + } + return coveredTrees; + } + + /** + * Return all trees from the given list {@code allTrees} which are not already subsumed by {@code tree}. + * @param tree + * @param allTrees + * @return + */ + private Collection<QueryTree<String>> getUncoveredTrees(QueryTree<String> tree, List<QueryTree<String>> allTrees){ + Collection<QueryTree<String>> uncoveredTrees = new ArrayList<QueryTree<String>>(); + for (QueryTree<String> queryTree : allTrees) { + boolean subsumed = queryTree.isSubsumedBy(tree); + if(!subsumed){ + uncoveredTrees.add(queryTree); + } + } + return uncoveredTrees; + } + + } + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeHeuristic.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeHeuristic.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeHeuristic.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -0,0 +1,79 @@ +/** + * + */ +package org.dllearner.algorithms.qtl; + +import java.util.Comparator; +import java.util.Set; + +import org.dllearner.algorithms.qtl.operations.lgg.EvaluatedQueryTree; +import org.dllearner.core.AbstractComponent; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentInitException; +import org.dllearner.core.Heuristic; +import org.dllearner.core.owl.Individual; +import org.dllearner.learningproblems.Heuristics; +import org.dllearner.learningproblems.QueryTreeScore; +import org.dllearner.utilities.owl.ConceptComparator; + +/** + * @author Lorenz Buehmann + * + */ +@ComponentAnn(name = "QueryTreeHeuristic", shortName = "qtree_heuristic", version = 0.1) +public class QueryTreeHeuristic extends AbstractComponent implements Heuristic, Comparator<EvaluatedQueryTree<String>>{ + + // F score beta value + private double coverageBeta = 1; + + private double coverageWeight = 0.8; + + private double specifityWeight = 0.1; + + // syntactic comparison as final comparison criterion + private ConceptComparator conceptComparator = new ConceptComparator(); + + /* (non-Javadoc) + * @see org.dllearner.core.Component#init() + */ + @Override + public void init() throws ComponentInitException { + } + + public double getScore(EvaluatedQueryTree<String> tree){ + QueryTreeScore treeScore = tree.getTreeScore(); + + //TODO + double score = treeScore.getScore(); + + return score; + } + + private double getPredictedAccuracy(EvaluatedQueryTree<String> tree){ + QueryTreeScore treeScore = tree.getTreeScore(); + + Set<Individual> truePositives = treeScore.getCoveredPositives(); + Set<Individual> trueNegatives = treeScore.getNotCoveredNegatives(); + Set<Individual> falsePositives = treeScore.getNotCoveredPositives(); + Set<Individual> falseNegatives = treeScore.getCoveredNegatives(); + return 0; + + } + + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(EvaluatedQueryTree<String> tree1, EvaluatedQueryTree<String> tree2) { + double diff = getScore(tree1) - getScore(tree2); + + if (diff > 0) { + return 1; + } else if (diff < 0) { + return -1; + } else { + return conceptComparator.compare(tree1.asEvaluatedDescription().getDescription(), tree2.asEvaluatedDescription().getDescription()); + } + } + +} Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java 2014-05-07 11:25:54 UTC (rev 4261) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java 2014-05-07 13:43:54 UTC (rev 4262) @@ -1488,7 +1488,7 @@ private String prefixed(Map<String, String> prefixes, String uri){ if(uri.startsWith("http://")){ - for (Entry<String, String> entry : prefixes.entrySet()) {System.out.println(entry); + for (Entry<String, String> entry : prefixes.entrySet()) { String prefix = entry.getKey(); String ns = entry.getValue(); if(uri.startsWith(ns)){ Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/impl/QueryTre... [truncated message content] |