001/** 002 * Copyright (C) 2007 - 2016, Jens Lehmann 003 * 004 * This file is part of DL-Learner. 005 * 006 * DL-Learner is free software; you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation; either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * DL-Learner is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package org.dllearner.learningproblems; 020 021import com.google.common.collect.Sets; 022import org.apache.commons.lang3.NotImplementedException; 023import org.dllearner.core.AbstractReasonerComponent; 024import org.dllearner.core.ComponentAnn; 025import org.dllearner.core.ComponentInitException; 026import org.dllearner.core.EvaluatedDescription; 027import org.dllearner.core.config.ConfigOption; 028import org.dllearner.utilities.owl.OWLClassExpressionUtils; 029import org.semanticweb.owlapi.model.OWLClassExpression; 030import org.semanticweb.owlapi.model.OWLIndividual; 031import org.semanticweb.owlapi.model.OWLNamedIndividual; 032 033import java.util.Set; 034import java.util.SortedSet; 035import java.util.TreeSet; 036 037/** 038 * @author Jens Lehmann 039 * 040 */ 041@ComponentAnn(name = "PosNegLPStrict", shortName = "posNegStrict", version = 0.1, description = "three valued definition learning problem") 042public class PosNegLPStrict extends PosNegLP { 043 044 private Set<OWLIndividual> neutralExamples; 045 046 @ConfigOption(description = "if set to true neutral examples are penalised") 047 private boolean penaliseNeutralExamples = false; 048 049 private static final double defaultAccuracyPenalty = 1; 050 051 @ConfigOption(description = "penalty for pos/neg examples which are classified as neutral", defaultValue = "1.0") 052 private double accuracyPenalty = defaultAccuracyPenalty; 053 054 private static final double defaultErrorPenalty = 3; 055 @ConfigOption(description = "penalty for pos. examples classified as negative or vice versa", defaultValue = "3.0") 056 private double errorPenalty = defaultErrorPenalty; 057 058 059 public void setAccuracyPenalty(double accuracyPenalty) { 060 this.accuracyPenalty = accuracyPenalty; 061 } 062 063 public void setErrorPenalty(double errorPenalty) { 064 this.errorPenalty = errorPenalty; 065 } 066 067 public void setPenaliseNeutralExamples(boolean penaliseNeutralExamples) { 068 this.penaliseNeutralExamples = penaliseNeutralExamples; 069 } 070 071 public PosNegLPStrict(AbstractReasonerComponent reasoningService) { 072 super(reasoningService); 073 } 074 075 public PosNegLPStrict() { super(); } 076 077 /* (non-Javadoc) 078 * @see org.dllearner.core.Component#init() 079 */ 080 @Override 081 public void init() throws ComponentInitException { 082 super.init(); 083 // compute neutral examples, i.e. those which are neither positive 084 // nor negative (we have to take care to copy sets instead of 085 // modifying them) 086 neutralExamples = Sets.intersection(getReasoner().getIndividuals(), positiveExamples); 087 neutralExamples.retainAll(negativeExamples); 088 089 initialized = true; 090 } 091 092 /* (non-Javadoc) 093 * @see org.dllearner.learningproblems.DefinitionLP#computeScore(org.dllearner.core.dl.Concept) 094 */ 095 @Override 096 public ScorePosNeg computeScore(OWLClassExpression concept) { 097 if(isUseRetrievalForClassification()) { 098 SortedSet<OWLIndividual> posClassified = getReasoner().getIndividuals(concept); 099 SortedSet<OWLIndividual> negClassified = getReasoner().getIndividuals(dataFactory.getOWLObjectComplementOf(concept)); 100 Set<OWLIndividual> neutClassified = new TreeSet<>(Sets.intersection(getReasoner().getIndividuals(),posClassified)); 101 neutClassified.retainAll(negClassified); 102 return new ScoreThreeValued( 103 OWLClassExpressionUtils.getLength(concept), accuracyPenalty, errorPenalty, 104 penaliseNeutralExamples, getPercentPerLengthUnit(), posClassified, neutClassified, 105 negClassified, positiveExamples, neutralExamples, negativeExamples); 106 } else { 107 if(getReasoner().getReasonerType().isOWLAPIReasoner()) { 108 if(penaliseNeutralExamples) 109 throw new Error("It does not make sense to use single instance checks when" + 110 "neutral examples are penalized. Use Retrievals instead."); 111 112 // TODO: umschreiben in instance checks 113 SortedSet<OWLIndividual> posClassified = new TreeSet<>(); 114 SortedSet<OWLIndividual> negClassified = new TreeSet<>(); 115 // Beispiele durchgehen 116 // TODO: Implementierung ist ineffizient, da man hier schon in Klassen wie 117 // posAsNeut, posAsNeg etc. einteilen koennte; so wird das extra in der Score-Klasse 118 // gemacht; bei wichtigen Benchmarks des 3-wertigen Lernproblems muesste man das 119 // umstellen 120 // pos => pos 121 for(OWLIndividual example : positiveExamples) { 122 if(getReasoner().hasType(concept, example)) 123 posClassified.add(example); 124 } 125 // neg => pos 126 for(OWLIndividual example: negativeExamples) { 127 if(getReasoner().hasType(concept, example)) 128 posClassified.add(example); 129 } 130 131 OWLClassExpression negatedConcept = dataFactory.getOWLObjectComplementOf(concept); 132 133 // pos => neg 134 for(OWLIndividual example : positiveExamples) { 135 if(getReasoner().hasType(negatedConcept, example)) 136 negClassified.add(example); 137 } 138 // neg => neg 139 for(OWLIndividual example : negativeExamples) { 140 if(getReasoner().hasType(negatedConcept, example)) 141 negClassified.add(example); 142 } 143 144 Set<OWLIndividual> neutClassified = new TreeSet<>(Sets.intersection(getReasoner().getIndividuals(),posClassified)); 145 neutClassified.retainAll(negClassified); 146 return new ScoreThreeValued(OWLClassExpressionUtils.getLength(concept), accuracyPenalty, errorPenalty, 147 penaliseNeutralExamples, getPercentPerLengthUnit(), posClassified, 148 neutClassified, negClassified, positiveExamples, neutralExamples, 149 negativeExamples); 150 } else 151 throw new Error("score cannot be computed in this configuration"); 152 } 153 } 154 155 @Override 156 public ScorePosNeg<OWLNamedIndividual> computeScore(OWLClassExpression ce, double noise) { 157 return null; 158 } 159 160 public Set<OWLIndividual> getNeutralExamples() { 161 return neutralExamples; 162 } 163 164 /** 165 * @return the accuracyPenalty 166 */ 167 public double getAccuracyPenalty() { 168 return accuracyPenalty; 169 } 170 171 /** 172 * @return the errorPenalty 173 */ 174 public double getErrorPenalty() { 175 return errorPenalty; 176 } 177 178 /** 179 * @return the penaliseNeutralExamples 180 */ 181 public boolean isPenaliseNeutralExamples() { 182 return penaliseNeutralExamples; 183 } 184 185 /* (non-Javadoc) 186 * @see org.dllearner.core.LearningProblem#getAccuracyOrTooWeak(org.dllearner.core.owl.Description, double) 187 */ 188 @Override 189 public double getAccuracyOrTooWeak(OWLClassExpression description, double minAccuracy) { 190 throw new NotImplementedException("Not implemented yet!"); 191 } 192 193 /* (non-Javadoc) 194 * @see org.dllearner.core.LearningProblem#evaluate(org.dllearner.core.owl.Description) 195 */ 196 @Override 197 public EvaluatedDescription evaluate(OWLClassExpression description) { 198 throw new NotImplementedException("Not implemented yet!"); 199 } 200}