From: <lor...@us...> - 2013-11-11 15:35:47
|
Revision: 4144 http://sourceforge.net/p/dl-learner/code/4144 Author: lorenz_b Date: 2013-11-11 15:35:44 +0000 (Mon, 11 Nov 2013) Log Message: ----------- Added exact FScore accuracy method to PosOnlyLP + JUnit test. Modified Paths: -------------- trunk/components-core/src/main/java/org/dllearner/learningproblems/PosOnlyLP.java trunk/components-core/src/test/java/org/dllearner/algorithms/isle/Experiment.java Added Paths: ----------- trunk/components-core/src/test/java/org/dllearner/test/junit/LearningProblemTest.java Modified: trunk/components-core/src/main/java/org/dllearner/learningproblems/PosOnlyLP.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/learningproblems/PosOnlyLP.java 2013-11-11 14:48:21 UTC (rev 4143) +++ trunk/components-core/src/main/java/org/dllearner/learningproblems/PosOnlyLP.java 2013-11-11 15:35:44 UTC (rev 4144) @@ -28,6 +28,7 @@ import java.util.SortedSet; import java.util.TreeSet; +import org.apache.log4j.Logger; import org.dllearner.core.AbstractLearningProblem; import org.dllearner.core.AbstractReasonerComponent; import org.dllearner.core.ComponentAnn; @@ -39,6 +40,8 @@ import org.dllearner.core.owl.Description; import org.dllearner.core.owl.Individual; +import com.google.common.collect.Sets; + /** * A learning problem, where we learn from positive examples only. * @@ -47,16 +50,24 @@ */ @ComponentAnn(name = "positive only learning problem", shortName = "posonlylp", version = 0.6) public class PosOnlyLP extends AbstractLearningProblem { + + private static Logger logger = Logger.getLogger(PosOnlyLP.class); + private long nanoStartTime; protected SortedSet<Individual> positiveExamples; private List<Individual> positiveExamplesShuffled; // protected SortedSet<Individual> pseudoNegatives; private List<Individual> individuals; + + private boolean useApproximations = false; // approximation of accuracy +- 0.03 % private static final double approx = 0.03; + // factor for higher weight on recall (needed for subclass learning) + private double coverageFactor; + public PosOnlyLP() { super(null); } @@ -130,6 +141,13 @@ } /** + * @param useApproximations the useApproximations to set + */ + public void setUseApproximations(boolean useApproximations) { + this.useApproximations = useApproximations; + } + + /** * @return the pseudoNegatives */ // public SortedSet<Individual> getPseudoNegatives() { @@ -139,7 +157,7 @@ // public int coveredPseudoNegativeExamplesOrTooWeak(Description concept) { // return definitionLP.coveredNegativeExamplesOrTooWeak(concept); -// } +// }posOnlyLPLearningTests /* (non-Javadoc) * @see org.dllearner.core.LearningProblem#computeScore(org.dllearner.core.owl.Description) @@ -195,11 +213,8 @@ return getAccuracy(coverage, protusion); } - /* (non-Javadoc) - * @see org.dllearner.core.LearningProblem#getAccuracyOrTooWeak(org.dllearner.core.owl.Description, double) - */ - @Override - public double getAccuracyOrTooWeak(Description description, double noise) { + + public double getAccuracyOrTooWeakApprox(Description description, double noise) { // instead of using the standard operation, we use optimisation // and approximation here @@ -317,6 +332,48 @@ return getAccuracy(coverage, protusion); } + /* (non-Javadoc) + * @see org.dllearner.core.AbstractLearningProblem#getAccuracyOrTooWeak(org.dllearner.core.owl.Description, double) + */ + @Override + public double getAccuracyOrTooWeak(Description description, double noise) { + return useApproximations ? getAccuracyOrTooWeakApprox(description, noise) : getAccuracyOrTooWeakExact(description, noise); + } + + // exact computation for 5 heuristics; each one adapted to super class + // learning; + // each one takes the noise parameter into account + public double getAccuracyOrTooWeakExact(Description description, double noise) { + + nanoStartTime = System.nanoTime(); + + SortedSet<Individual> individualsC = reasoner.getIndividuals(description); + + // computing R(C) restricted to relevant instances + int additionalInstances = Sets.difference(individualsC, positiveExamples).size(); + + // computing R(A) + int coveredInstances = Sets.intersection(individualsC, positiveExamples).size(); + + double recall = coveredInstances / (double) positiveExamples.size(); + + // noise computation is incorrect + // if(recall < 1 - noise) { + // return -1; + // } + + double precision = (additionalInstances + coveredInstances == 0) ? 0 : coveredInstances + / (double) (coveredInstances + additionalInstances); + + // best reachable concept has same recall and precision 1: + if (((1 + Math.sqrt(coverageFactor)) * recall) / (Math.sqrt(coverageFactor) + 1) < 1 - noise) { + return -1; + } else { + return Heuristics.getFScore(recall, precision, coverageFactor); + } + + } + // see paper: expression used in confidence interval estimation private static double p3(double p1, int total) { return 1.96 * Math.sqrt(p1*(1-p1)/(total+4)); Modified: trunk/components-core/src/test/java/org/dllearner/algorithms/isle/Experiment.java =================================================================== --- trunk/components-core/src/test/java/org/dllearner/algorithms/isle/Experiment.java 2013-11-11 14:48:21 UTC (rev 4143) +++ trunk/components-core/src/test/java/org/dllearner/algorithms/isle/Experiment.java 2013-11-11 15:35:44 UTC (rev 4144) @@ -53,6 +53,10 @@ public abstract class Experiment { /** + * + */ + private static final int maxExecutionTimeInSeconds = 20; + /** * The number of folds for the cross-validation */ private final int FOLDS = 10; @@ -61,6 +65,8 @@ */ private final boolean LEAVE_ONE_OUT = false; + private boolean equivalence = true; + private PosOnlyLP lp; private RelevanceMetric relevance; private AbstractReasonerComponent reasoner; @@ -221,30 +227,28 @@ lp.init(); //get the start class for the learning algorithms - Description startClass = getStartClass(cls, true, true); + Description startClass = getStartClass(cls, equivalence, true); Map<Entity, Double> entityRelevance = RelevanceUtils.getRelevantEntities(cls, ontology, relevance); NLPHeuristic heuristic = new NLPHeuristic(entityRelevance); - // heuristic.setStartNodeBonus(100); - heuristic.init(); ClassLearningProblem clp = new ClassLearningProblem(reasoner); clp.setClassToDescribe(cls); + clp.setEquivalence(equivalence); clp.init(); - System.out.println(reasoner.getObjectProperties()); - RhoDRDown rop = new RhoDRDown(); rop.setReasoner(reasoner); rop.setUseNegation(true); rop.init(); // perform cross validation with ISLE - ISLE isle = new ISLE(clp, reasoner); + ISLE isle = new ISLE(lp, reasoner); isle.setHeuristic(heuristic); - isle.setMaxNrOfResults(1); + isle.setMaxNrOfResults(3); isle.setOperator(rop); -// isle.setStartClass(startClass); + isle.setMaxExecutionTimeInSeconds(maxExecutionTimeInSeconds); + isle.setStartClass(startClass); new File(testFolder).mkdirs(); isle.setSearchTreeFile(testFolder + "searchTreeISLE.txt"); isle.setWriteSearchTree(true); Added: trunk/components-core/src/test/java/org/dllearner/test/junit/LearningProblemTest.java =================================================================== --- trunk/components-core/src/test/java/org/dllearner/test/junit/LearningProblemTest.java (rev 0) +++ trunk/components-core/src/test/java/org/dllearner/test/junit/LearningProblemTest.java 2013-11-11 15:35:44 UTC (rev 4144) @@ -0,0 +1,79 @@ +/** + * + */ +package org.dllearner.test.junit; + +import static org.junit.Assert.*; + +import java.util.SortedSet; +import java.util.TreeSet; + +import org.dllearner.core.AbstractKnowledgeSource; +import org.dllearner.core.AbstractReasonerComponent; +import org.dllearner.core.ComponentInitException; +import org.dllearner.core.ComponentManager; +import org.dllearner.core.owl.ClassAssertionAxiom; +import org.dllearner.core.owl.Individual; +import org.dllearner.core.owl.KB; +import org.dllearner.core.owl.NamedClass; +import org.dllearner.core.owl.Thing; +import org.dllearner.kb.KBFile; +import org.dllearner.learningproblems.PosNegLPStandard; +import org.dllearner.learningproblems.PosOnlyLP; +import org.dllearner.reasoning.FastInstanceChecker; +import org.dllearner.reasoning.OWLAPIReasoner; +import org.junit.Test; + +import com.google.common.collect.Sets; + +/** + * @author Lorenz Buehmann + * + */ +public class LearningProblemTest { + + @Test + public void posOnlyLPLearningTests() throws ComponentInitException { + // create artificial ontology + KB kb = new KB(); + String ns = "http://dl-learner.org/junit/"; + NamedClass[] nc = new NamedClass[5]; + for(int i=0; i<5; i++) { + nc[i] = new NamedClass(ns + "A" + i); + } + Individual[] ind = new Individual[100]; + for(int i=0; i<100; i++) { + ind[i] = new Individual(ns + "i" + i); + } + + // assert individuals to owl:Thing (such that they exist in the knowledge base) + for(int i=0; i<100; i++) { + kb.addAxiom(new ClassAssertionAxiom(Thing.instance,ind[i])); + } + + // A0 + kb.addAxiom(new ClassAssertionAxiom(nc[0],ind[0])); + kb.addAxiom(new ClassAssertionAxiom(nc[0],ind[1])); + kb.addAxiom(new ClassAssertionAxiom(nc[0],ind[5])); + + // A1 + kb.addAxiom(new ClassAssertionAxiom(nc[1],ind[0])); + kb.addAxiom(new ClassAssertionAxiom(nc[1],ind[1])); + kb.addAxiom(new ClassAssertionAxiom(nc[1],ind[2])); + kb.addAxiom(new ClassAssertionAxiom(nc[1],ind[5])); + + AbstractKnowledgeSource ks = new KBFile(kb); + + AbstractReasonerComponent reasoner = new FastInstanceChecker(ks); + reasoner.init(); + + SortedSet<Individual> positiveExamples = new TreeSet<Individual>(Sets.newHashSet(ind[0], ind[1], ind[2], ind[3], ind[4])); + PosOnlyLP lp = new PosOnlyLP(reasoner); + lp.setPositiveExamples(positiveExamples); + + assertEquals(lp.getAccuracyOrTooWeak(nc[0], 1.0), 2/3d, 0.000000001d); // P=2/3, R=2/5 + assertEquals(lp.getAccuracyOrTooWeak(nc[1], 1.0), 3/4d, 0.000000001d); // P=3/4, R=3/5 + assertEquals(lp.getAccuracyOrTooWeak(nc[2], 1.0), 0d, 0.000000001d); // P=0, R=0 + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |