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 org.dllearner.core.*;
022import org.dllearner.utilities.CoverageAdapter;
023import org.dllearner.utilities.ReasoningUtils.Coverage;
024import org.dllearner.utilities.owl.OWLClassExpressionUtils;
025import org.semanticweb.owlapi.model.OWLClassExpression;
026import org.semanticweb.owlapi.model.OWLIndividual;
027
028import java.util.SortedSet;
029
030/**
031 * The aim of this learning problem is to learn a concept definition such that
032 * the positive examples and the negative examples do not follow. It is
033 * 2-valued, because we only distinguish between covered and non-covered
034 * examples. (A 3-valued problem distinguishes between covered examples,
035 * examples covered by the negation of the concept, and all other examples.) The
036 * 2-valued learning problem is often more useful for Description Logics due to
037 * (the Open World Assumption and) the fact that negative knowledge, e.g. that a
038 * person does not have a child, is or cannot be expressed.
039 * 
040 * @author Jens Lehmann
041 * 
042 */
043@ComponentAnn(name = "PosNegLPStandard", shortName = "posNegStandard", version = 0.8)
044public class PosNegLPStandard extends PosNegLP implements Cloneable{
045        
046
047    public PosNegLPStandard() {
048        }
049
050    public PosNegLPStandard(AbstractReasonerComponent reasoningService){
051        super(reasoningService);
052    }
053    
054    /**
055     * Copy constructor
056     * @param lp the learning problem
057     */
058    public PosNegLPStandard(PosNegLP lp) {
059        this.positiveExamples = lp.getPositiveExamples();
060        this.negativeExamples = lp.getNegativeExamples();
061        
062        this.reasoner = lp.getReasoner();
063        this.accuracyMethod = lp.getAccuracyMethod();
064        setUseRetrievalForClassification(lp.isUseRetrievalForClassification());
065        }
066
067        public PosNegLPStandard(AbstractReasonerComponent reasoningService, SortedSet<OWLIndividual> positiveExamples, SortedSet<OWLIndividual> negativeExamples) {
068                this.setReasoner(reasoningService);
069                this.positiveExamples = positiveExamples;
070                this.negativeExamples = negativeExamples;
071        }
072
073        @Override
074        public void init() throws ComponentInitException {
075                super.init();
076                
077                initialized = true;
078        }
079
080        /**
081         * Computes score of a given concept using the reasoner.
082         * 
083         * @param concept
084         *            The concept to test.
085         * @return Corresponding Score object.
086         */
087        @Override
088        public ScorePosNeg computeScore(OWLClassExpression concept, double noise) {
089
090                Coverage[] cc = reasoningUtil.getCoverage(concept, positiveExamples, negativeExamples);
091
092                // TODO: this computes accuracy twice - more elegant method should be implemented
093                double accuracy = reasoningUtil.getAccuracyOrTooWeakExact2(accuracyMethod, cc, noise);
094                CoverageAdapter.CoverageAdapter2 c2 = new CoverageAdapter.CoverageAdapter2(cc);
095
096                return new ScoreTwoValued(
097                                OWLClassExpressionUtils.getLength(concept),
098                                getPercentPerLengthUnit(),
099                                c2.posAsPos(), c2.posAsNeg(), c2.negAsPos(), c2.negAsNeg(),
100                                accuracy);
101
102        }
103
104        @Override
105        public double getAccuracyOrTooWeak(OWLClassExpression description, double noise) {
106                return reasoningUtil.getAccuracyOrTooWeak2(accuracyMethod, description, positiveExamples, negativeExamples, noise);
107        }
108
109        /* (non-Javadoc)
110         * @see org.dllearner.core.LearningProblem#evaluate(org.dllearner.core.owl.Description)
111         */
112        @Override
113        public EvaluatedDescription evaluate(OWLClassExpression description, double noise) {
114                ScorePosNeg score = computeScore(description, noise);
115                return new EvaluatedDescriptionPosNeg(description, score);
116        }
117
118    /* (non-Javadoc)
119     * @see java.lang.Object#clone()
120     */
121    @Override
122    public Object clone() throws CloneNotSupportedException {
123        super.clone();
124        return new PosNegLPStandard(this);
125    }
126}