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 com.google.common.collect.Sets.SetView;
023import org.apache.log4j.Logger;
024import org.dllearner.accuracymethods.AccMethodApproximate;
025import org.dllearner.accuracymethods.AccMethodPredAcc;
026import org.dllearner.accuracymethods.AccMethodTwoValued;
027import org.dllearner.core.AbstractClassExpressionLearningProblem;
028import org.dllearner.core.AbstractReasonerComponent;
029import org.dllearner.core.ComponentInitException;
030import org.dllearner.core.config.ConfigOption;
031import org.dllearner.reasoning.SPARQLReasoner;
032import org.dllearner.utilities.Helper;
033import org.semanticweb.owlapi.model.OWLIndividual;
034import org.semanticweb.owlapi.model.OWLNamedIndividual;
035import org.springframework.beans.factory.annotation.Autowired;
036
037import java.util.Set;
038import java.util.TreeSet;
039
040/**
041 * @author Jens Lehmann
042 *
043 */
044public abstract class PosNegLP extends AbstractClassExpressionLearningProblem<ScorePosNeg<OWLNamedIndividual>> {
045        protected static final Logger logger = Logger.getLogger(PosNegLP.class);
046
047        @ConfigOption(description = "list of positive examples", required = true)
048        protected Set<OWLIndividual> positiveExamples = new TreeSet<>();
049        @ConfigOption(description = "list of negative examples", required = true)
050        protected Set<OWLIndividual> negativeExamples = new TreeSet<>();
051        protected Set<OWLIndividual> allExamples = new TreeSet<>();
052
053        @ConfigOption(description = "\"Specifies whether to use retrieval or instance checks for testing a concept. - NO LONGER FULLY SUPPORTED.",defaultValue = "false")
054    private boolean useRetrievalForClassification = false;
055    @ConfigOption(description = "Percent Per Length Unit", defaultValue = "0.05", required = false)
056    private double percentPerLengthUnit = 0.05;
057
058        @ConfigOption(description = "Specifies, which method/function to use for computing accuracy. Available measues are \"PRED_ACC\" (predictive accuracy), \"FMEASURE\" (F measure), \"GEN_FMEASURE\" (generalised F-Measure according to Fanizzi and d'Amato).",
059                        defaultValue = "PRED_ACC")
060        protected AccMethodTwoValued accuracyMethod;
061
062    public PosNegLP(){
063
064    }
065
066        public PosNegLP(AbstractReasonerComponent reasoningService) {
067                super(reasoningService);
068        }
069
070        /*
071         * (non-Javadoc)
072         * 
073         * @see org.dllearner.core.Component#init()
074         */
075        @Override
076        public void init() throws ComponentInitException {
077                ExampleLoader exampleLoaderHelper = this.getExampleLoaderHelper();
078                if (exampleLoaderHelper != null && !exampleLoaderHelper.isInitialized()) {
079                        logger.info("Loading examples by expression");
080                        exampleLoaderHelper.setPosNegLP(this);
081                        exampleLoaderHelper.init();
082                }
083                // check if some positive examples have been set
084                if(positiveExamples.isEmpty()) {
085                        throw new ComponentInitException("No positive examples have been set.");
086                }
087                
088                // check if some negative examples have been set and give warning if not
089                if(negativeExamples.isEmpty()) {
090                        logger.warn("No negative examples have been set, but you decided to use the positive-negative learning"
091                                        + "problem. We recommend to use the positive-only learning problem for the case of no negative examples instead.");
092                }
093                
094                // check if there is some overlap between positive and negative examples and give warning
095                // in that case
096                SetView<OWLIndividual> overlap = Sets.intersection(positiveExamples, negativeExamples);
097                if(!overlap.isEmpty()) {
098                        logger.warn("You declared some individuals as both positive and negative examples.");
099                }
100                
101                allExamples = Sets.union(positiveExamples, negativeExamples);
102                
103                if (accuracyMethod == null) {
104                        accuracyMethod = new AccMethodPredAcc(true);
105                }
106                if (accuracyMethod instanceof AccMethodApproximate) {
107                        ((AccMethodApproximate)accuracyMethod).setReasoner(reasoner);
108                }
109                
110                // sanity check whether examples are contained in KB
111                Helper.checkIndividuals(reasoner, allExamples);
112                
113                initialized = true;
114        }
115
116        public Set<OWLIndividual> getNegativeExamples() {
117                return negativeExamples;
118        }
119
120        public Set<OWLIndividual> getPositiveExamples() {
121                return positiveExamples;
122        }
123        
124        public void setNegativeExamples(Set<OWLIndividual> set) {
125                this.negativeExamples=set;
126        }
127
128        public void setPositiveExamples(Set<OWLIndividual> set) {
129                this.positiveExamples=set;
130        }
131
132        public double getPercentPerLengthUnit() {
133                return percentPerLengthUnit;
134        }
135
136    public void setPercentPerLengthUnit(double percentPerLengthUnit) {
137        this.percentPerLengthUnit = percentPerLengthUnit;
138    }
139
140    public boolean isUseRetrievalForClassification() {
141        return useRetrievalForClassification;
142    }
143
144    public void setUseRetrievalForClassification(boolean useRetrievalForClassification) {
145        this.useRetrievalForClassification = useRetrievalForClassification;
146    }
147
148        public AccMethodTwoValued getAccuracyMethod() {
149            return accuracyMethod;
150        }
151
152        @Autowired(required=false)
153        public void setAccuracyMethod(AccMethodTwoValued accuracyMethod) {
154            this.accuracyMethod = accuracyMethod;
155        }
156
157}