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.core;
020
021import org.dllearner.core.config.ConfigOption;
022import org.semanticweb.owlapi.model.OWLObject;
023import org.springframework.beans.factory.annotation.Autowired;
024
025/**
026 * Base class for all learning problems.
027 * See also the wiki page for
028 * <a href="http://dl-learner.org/Projects/DLLearner/Architecture">DL-Learner-Architecture</a>.
029 * 
030 * @author Jens Lehmann
031 *
032 */
033public abstract class AbstractLearningProblem<T extends Score, V extends OWLObject, W extends EvaluatedHypothesis<V, T>>
034                extends AbstractComponent
035                implements LearningProblem {
036        
037        @ConfigOption(description="The reasoner component variable to use for this Learning Problem")
038        protected AbstractReasonerComponent reasoner;
039
040    public AbstractLearningProblem(){
041
042    }
043        /**
044         * Constructs a learning problem using a reasoning service for
045         * querying the background knowledge. It can be used for
046         * evaluating solution candidates.
047         * @param reasoner The reasoning service used as
048         * background knowledge.
049         */
050        public AbstractLearningProblem(AbstractReasonerComponent reasoner) {
051                this.reasoner = reasoner;
052        }
053        
054        /**
055         * Method to exchange the reasoner underlying the learning
056         * problem.
057         * Implementations, which do not only use the provided reasoning
058         * service class variable, must make sure that a call to this method
059         * indeed changes the reasoning service.
060         * @param reasoner New reasoning service.
061         */
062        public void changeReasonerComponent(AbstractReasonerComponent reasoner) {
063                this.reasoner = reasoner;
064        }
065                
066        /**
067         * Computes the <code>Score</code> of a given hypothesis
068         * with respect to this learning problem.
069         * This can (but does not need to) be used by learning algorithms
070         * to measure how good the hypothesis fits the learning problem.
071         * Score objects are used to store e.g. covered examples, accuracy etc.,
072         * so often it is more efficient to only create score objects for
073         * promising hypotheses.
074         * @param hypothesis A hypothesis (as solution candidate for this learning problem).
075         * @return A <code>Score</code> object.
076         */
077        public T computeScore(V hypothesis) {
078                return computeScore(hypothesis, 0.0);
079        }
080        
081        /**
082         * Computes the <code>Score</code> of a given hypothesis
083         * with respect to this learning problem.
084         * This can (but does not need to) be used by learning algorithms
085         * to measure how good the hypothesis fits the learning problem.
086         * Score objects are used to store e.g. covered examples, accuracy etc.,
087         * so often it is more efficient to only create score objects for
088         * promising hypotheses.
089         * @param hypothesis A hypothesis (as solution candidate for this learning problem).
090         * @param noise the (approximated) value of noise within the examples
091         * @return A <code>Score</code> object.
092         */
093        public abstract T computeScore(V hypothesis, double noise);
094        
095        /**
096         * Evaluates the hypothesis by computing the score and returning an
097         * evaluated hypothesis of the correct type (ClassLearningProblem
098         * returns EvaluatedDescriptionClass instead of generic EvaluatedDescription).
099         * @param hypothesis Hypothesis to evaluate.
100         * @return an evaluated hypothesis
101         */
102        public W evaluate(V hypothesis){
103                return evaluate(hypothesis, 1.0);
104        }
105        
106        /**
107         * Evaluates the hypothesis by computing the score and returning an
108         * evaluated hypothesis of the correct type (ClassLearningProblem
109         * returns EvaluatedDescriptionClass instead of generic EvaluatedDescription).
110         * @param hypothesis Hypothesis to evaluate.
111         * @param noise the (approximated) value of noise within the examples
112         * @return an evaluated hypothesis
113         */
114        public W evaluate(V hypothesis, double noise) {
115                return null;
116        }
117        
118        /**
119         * This method returns a value, which indicates how accurate a
120         * hypothesis solves a learning problem. There can be different
121         * ways to compute accuracy depending on the type of learning problem
122         * and other factors. However, all implementations are required to
123         * return a value between 0 and 1, where 1 stands for the highest
124         * possible accuracy and 0 for the lowest possible accuracy.
125         * 
126         * @return A value between 0 and 1 indicating the quality (of a hypothesis).
127         * or -1 as described above.
128         */
129        public double getAccuracyOrTooWeak(V object) {
130                return getAccuracyOrTooWeak(object, 0.0);
131        }
132        
133        /**
134         * This method computes the accuracy and returns -1 instead of the accuracy if
135         *
136         * <ol>
137         *     <li>the accuracy of the hypothesis is below the given threshold and </li>
138         *     <li>the accuracy of all more special w.r.t. subsumption hypotheses is below the given threshold.</li>
139         * </ol>
140         * 
141         * This is used for efficiency reasons, i.e. -1 can be returned instantly if
142         * it is clear that the hypothesis and all its refinements are not
143         * sufficiently accurate.
144         * 
145         * @return A value between 0 and 1 indicating the quality (of a hypothesis)
146         * or -1 as described above.
147         */
148        public abstract double getAccuracyOrTooWeak(V hypothesis, double noise);
149
150    /**
151     * Implementations of learning problems can use this class
152     * variable to perform reasoner operations.
153     */
154    public AbstractReasonerComponent getReasoner() {
155        return reasoner;
156    }
157
158    @Autowired(required=false)
159    public void setReasoner(AbstractReasonerComponent reasoner) {
160        this.reasoner = reasoner;
161    }
162}