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.algorithms.decisiontrees.dsttdt; 020 021import java.util.ArrayList; 022//import knowledgeBasesHandler.KnowledgeBase; 023import java.util.List; 024import java.util.Set; 025import java.util.SortedSet; 026import java.util.Stack; 027import java.util.TreeSet; 028 029import org.dllearner.algorithms.decisiontrees.dsttdt.dst.MassFunction; 030import org.dllearner.algorithms.decisiontrees.dsttdt.models.DSTDLTree; 031import org.dllearner.algorithms.decisiontrees.dsttdt.models.EvidentialModel; 032import org.dllearner.algorithms.decisiontrees.heuristics.TreeInductionHeuristics; 033import org.dllearner.algorithms.decisiontrees.refinementoperators.DLTreesRefinementOperator; 034import org.dllearner.algorithms.decisiontrees.utils.Couple; 035import org.dllearner.algorithms.decisiontrees.utils.Npla; 036import org.dllearner.algorithms.decisiontrees.utils.Split; 037import org.dllearner.core.AbstractCELA; 038import org.dllearner.core.AbstractClassExpressionLearningProblem; 039import org.dllearner.core.AbstractReasonerComponent; 040import org.dllearner.core.ComponentAnn; 041import org.dllearner.core.ComponentInitException; 042import org.dllearner.core.EvaluatedDescription; 043import org.dllearner.core.annotations.OutVariable; 044import org.dllearner.core.annotations.Unused; 045import org.dllearner.core.config.ConfigOption; 046import org.dllearner.learningproblems.PosNegUndLP; 047import org.dllearner.refinementoperators.RefinementOperator; 048import org.semanticweb.owlapi.model.OWLClassExpression; 049import org.semanticweb.owlapi.model.OWLIndividual; 050import org.slf4j.Logger; 051import org.slf4j.LoggerFactory; 052 053@ComponentAnn(name="ETDT", shortName="etdt", version=1.0, description="An Evidence-based Terminological Decision Tree") 054public class DSTTDTClassifier extends AbstractCELA{ 055 056 //static final double THRESHOLD = 0.05; 057 //static final double M = 3; 058 private static Logger logger= LoggerFactory.getLogger(DSTTDTClassifier.class); 059 060 @OutVariable 061 private DSTDLTree currentmodel; // model induced from the procedure 062 private boolean stop; 063 064 @Unused 065 protected OWLClassExpression classToDescribe; //target concept 066 @ConfigOption(description = "instance of heuristic to use", defaultValue = "TreeInductionHeuristics") 067 protected TreeInductionHeuristics heuristic; // heuristic 068 //protected LengthLimitedRefinementOperator operator ;// refinement operator 069 070 @ConfigOption(description = "refinement operator instance to use", defaultValue = "DLTreesRefinementOperator") 071 protected RefinementOperator operator; 072 073 //private KnowledgeBase kb; 074 public DSTTDTClassifier() { 075 //this.kb=kb; 076 super(); 077 } 078 079 public DSTTDTClassifier(AbstractClassExpressionLearningProblem problem, AbstractReasonerComponent reasoner) { 080 super(problem, reasoner); 081 // configurator = new CELOEConfigurator(this); 082 } 083 084 @ConfigOption(defaultValue = "0.05", description = "Purity threshold for setting a leaf") 085 protected double puritythreshold; 086 087 @ConfigOption(defaultValue = "4", description = "value for limiting the number of generated concepts") 088 protected int beam; 089 090 091 @ConfigOption(defaultValue = "false", description = "a flag to decide if further control on the purity measure should be made") 092 protected boolean nonSpecifityControl; 093 094 095 public boolean isNonSpecifityControl() { 096 return nonSpecifityControl; 097 } 098 099 public void setNonSpecifityControl(boolean nonSpecifityControl) { 100 this.nonSpecifityControl = nonSpecifityControl; 101 } 102 103 //@ConfigOption(defaultValue = "false", description = "for overcoming the problem of missing values in tree algorithms.tree.models") 104 //protected boolean missingValueTreatmentForTDT; 105 protected double prPos; 106 protected double prNeg; 107 //protected OWLClassExpression classToDescribe; //target concept 108 //protected DLTreeHeuristics heuristic; // heuristic 109 //protected LengthLimitedRefinementOperator operator ;// refinement operator 110 111 //protected RefinementOperator operator; 112 113 public double getPuritythreshold() { 114 return puritythreshold; 115 } 116 117 public void setPuritythreshold(double puritythreshold) { 118 this.puritythreshold = puritythreshold; 119 } 120 121 public int getBeam() { 122 return beam; 123 } 124 125 public void setBeam(int beam) { 126 this.beam = beam; 127 } 128 129// public boolean isBinaryClassification() { 130// return binaryClassification; 131// } 132// 133// 134// public void setBinaryClassification(boolean binaryClassification) { 135// this.binaryClassification = binaryClassification; 136// } 137 138 public OWLClassExpression getClassToDescribe() { 139 return classToDescribe; 140 } 141 142 public void setClassToDescribe(OWLClassExpression classToDescribe) { 143 this.classToDescribe = classToDescribe; 144 } 145 146 public TreeInductionHeuristics getHeuristic() { 147 return heuristic; 148 } 149 150 public void setHeuristic(TreeInductionHeuristics heuristic) { 151 this.heuristic = heuristic; 152 } 153 154 public RefinementOperator getOperator() { 155 return operator; 156 } 157 158 public void setOperator(RefinementOperator operator) { 159 this.operator = operator; 160 } 161 162 @Override 163 public void init() throws ComponentInitException{ 164 //inizialization 165 166 // TODO Auto-generated method stub 167 baseURI = reasoner.getBaseURI(); 168 prefixes = reasoner.getPrefixes(); 169 170 // if no one injected a heuristic, we use a default one 171 if(heuristic == null) { 172 heuristic = new TreeInductionHeuristics(); 173 heuristic.setProblem(learningProblem); 174 heuristic.setReasoner(reasoner); 175 176 heuristic.init(); 177 } 178 179 if(operator == null) { 180 // default operator 181 operator= new DLTreesRefinementOperator((PosNegUndLP)super.learningProblem, getReasoner(), 4); 182 //operator = new DLTreesRefinementOperator( this.learningProblem,reasoner,4); 183 ((DLTreesRefinementOperator)operator).setReasoner(reasoner); 184 ((DLTreesRefinementOperator)operator).setBeam(4); // default value 185 //System.out.println("Refinement operator"+operator); 186 187// if(operator instanceof CustomStartRefinementOperator) { 188// ((CustomStartRefinementOperator)operator).setStartClass(startClass); 189// } 190// if(operator instanceof ReasoningBasedRefinementOperator) { 191// ((ReasoningBasedRefinementOperator)operator).setReasoner(reasoner); 192// } 193 operator.init(); 194 195 196 197 } 198 199 //start(); 200 201 initialized = true; 202 } 203 204 205 206 207 @SuppressWarnings({ "unchecked", "rawtypes" }) 208 public DSTDLTree induceDSTDLTree 209 (SortedSet<OWLIndividual> posExs, SortedSet<OWLIndividual> negExs, SortedSet<OWLIndividual> undExs) { 210 211 212 Npla<SortedSet<OWLIndividual>,SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double> examples = new Npla<>(posExs, negExs, undExs, beam, prPos, prNeg); 213 DSTDLTree tree = new DSTDLTree(); // new (sub)tree 214 Stack<Couple<DSTDLTree,Npla<SortedSet<OWLIndividual>,SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double>>> stack= new Stack<>(); 215 Couple<DSTDLTree,Npla<SortedSet<OWLIndividual>,SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double>> toInduce= new Couple<>(); 216 toInduce.setFirstElement(tree); 217 toInduce.setSecondElement(examples); 218 stack.push(toInduce); 219 220 Stack<DSTDLTree> lastTrees= new Stack<>(); // for refine hierarchically a concept 221 while (!stack.isEmpty()){ 222 223 // pop from the stack 224 Couple<DSTDLTree,Npla<SortedSet<OWLIndividual>,SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double>> current= stack.pop(); // extract the next element 225 Npla<SortedSet<OWLIndividual>, SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double> currentExamples= current.getSecondElement(); 226 // set of negative, positive and undefined example 227 posExs=currentExamples.getFirst(); 228 negExs=currentExamples.getSecond(); 229 undExs=currentExamples.getThird(); 230 DSTDLTree currentTree= current.getFirstElement(); 231 //System.out.println("Current Tree: "+ (currentTree==null)); 232 int psize = posExs.size(); 233 int nsize = negExs.size(); 234 int usize = undExs.size(); 235 System.out.printf("Learning problem\t p:%d\t n:%d\t u:%d\t prPos:%4f\t prNeg:%4f\n", 236 psize, nsize, usize, prPos, prNeg); 237 238 //build the BBA for the current node 239 ArrayList<Integer> frame = new ArrayList<>(); 240 frame.add(-1); 241 frame.add(1); 242 MassFunction mass= new MassFunction(frame); 243 ArrayList<Integer> positive= new ArrayList<>(); 244 positive.add(1); 245 double positiveValue = (double)psize/(psize+ nsize+usize); 246 if( (psize+ nsize+usize)==0){ 247 positiveValue= prPos; 248 } 249 mass.setValues(positive, positiveValue); 250 ArrayList<Integer> negative= new ArrayList<>(); 251 negative.add(-1); 252 double negativeValue = (double)nsize/(psize+ nsize+usize); 253 if( (psize+ nsize+usize)==0){ 254 negativeValue= prNeg; 255 } 256 mass.setValues(negative, negativeValue); 257 double undValue = ((double)usize/(psize+ nsize+usize)); 258 259 if( (psize+ nsize+usize)==0){ 260 undValue= 0; 261 } 262 mass.setValues(frame, undValue); 263 264 265 // System.out.println("MASS: "+ positiveValue +", "+negativeValue+", "+undValue); 266 // ragionamento sui prior 267 268 if (psize == 0 && nsize == 0) // no exs 269 if (prPos >= prNeg) { 270 // prior majority of positives 271 currentTree.setRoot(dataFactory.getOWLThing(), mass); // set positive leaf 272 // return tree; 273 } 274 else { // prior majority of negatives 275 currentTree.setRoot(dataFactory.getOWLNothing(),mass); // set negative leaf 276 // return tree; 277 } 278 else{ 279 // double numPos = posExs.size() + undExs.size()*prPos; 280 // double numNeg = negExs.size() + undExs.size()*prNeg; 281 double numPos = psize; 282 double numNeg = nsize; 283 double perPos = numPos/(numPos+numNeg); 284 double perNeg = numNeg/(numPos+numNeg); 285 if (perNeg==0 && perPos > puritythreshold) { // no negative 286 // System.out.println("Thing as leaf"); 287 currentTree.setRoot(dataFactory.getOWLThing(), mass); // set positive lea 288 // return tree; 289 } 290 else if (perPos==0 && perNeg > puritythreshold) { // no positive 291 // System.out.println("NoThing as leaf"); 292 currentTree.setRoot(dataFactory.getOWLNothing(), mass); // set negative leaf 293 // return tree; 294 } 295 else{ 296 //System.out.println("Non specificity: "+nonSpecifityControl); 297 if (!nonSpecifityControl){ 298 //OWLClassExpression[] cConcepts= new OWLClassExpression[0]; 299 DLTreesRefinementOperator dlTreesRefinementOperator = (DLTreesRefinementOperator)operator; 300 301 //System.out.println("is null?: "+dlTreesRefinementOperator==null); 302 Set<OWLClassExpression> refine = null; 303 if (lastTrees.isEmpty()){ 304 refine = dlTreesRefinementOperator.refine(dataFactory.getOWLThing(), posExs, negExs); 305 } 306 else 307 refine = dlTreesRefinementOperator.refine(lastTrees.pop().getRoot(), posExs, negExs); 308 309 310 // dlTreesRefinementOperator.refine(dataFactory.getOWLThing(), posExs, negExs); 311 System.out.println("Refinement:"+refine); 312 313 ArrayList<OWLClassExpression> generateNewConcepts = new ArrayList<>(refine); // a generic refinement operator 314 OWLClassExpression[] cConcepts = new OWLClassExpression[generateNewConcepts.size()]; 315 316 cConcepts= generateNewConcepts.toArray(cConcepts); 317 318 // OWLClassExpression[] cConcepts = allConcepts; 319 320 // select node couoncept 321 Couple<OWLClassExpression,MassFunction> newRootConcept = null; 322 if (dlTreesRefinementOperator.getRo() ==DLTreesRefinementOperator.ORIGINAL) // 3: the original refinement operator for terminological trees 323 newRootConcept= heuristic.selectBestConceptDST(cConcepts, posExs, negExs, undExs, prPos, prNeg); 324 else 325 newRootConcept= heuristic.selectWorstConceptDST(cConcepts, posExs, negExs, undExs, prPos, prNeg); MassFunction refinementMass = newRootConcept.getSecondElement(); 326 327 //System.out.println(newRootConcept.getFirstElement()+"----"+refinementMass); 328 SortedSet<OWLIndividual> posExsT = new TreeSet<>(); 329 SortedSet<OWLIndividual> negExsT = new TreeSet<>(); 330 SortedSet<OWLIndividual> undExsT = new TreeSet<>(); 331 SortedSet<OWLIndividual> posExsF = new TreeSet<>(); 332 SortedSet<OWLIndividual> negExsF = new TreeSet<>(); 333 SortedSet<OWLIndividual> undExsF = new TreeSet<>(); 334 335 Split.split(newRootConcept.getFirstElement(), dataFactory, reasoner, posExs, negExs, undExs, posExsT, negExsT, undExsT, posExsF, negExsF, undExsF); 336 // select node concept 337 338 currentTree.setRoot(newRootConcept.getFirstElement(), refinementMass); 339 340 // undExsT = union(undExsT, 341 // tree.setPosTree(induceDSTDLTree(posExsT, negExsT, undExsT, dim, prPos, prNeg)); 342 // tree.setNegTree(induceDSTDLTree(posExsF, negExsF, undExsF, dim, prPos, prNeg)); 343 344 DSTDLTree posTree= new DSTDLTree(); 345 DSTDLTree negTree= new DSTDLTree(); // recursive calls simulation 346 currentTree.setPosTree(posTree); 347 currentTree.setNegTree(negTree); 348 Npla<SortedSet<OWLIndividual>, SortedSet<OWLIndividual>, SortedSet<OWLIndividual>, Integer, Double, Double> npla1 = new Npla<>(posExsT, negExsT, undExsT, beam, perPos, perNeg); 349 Npla<SortedSet<OWLIndividual>, SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double> npla2 = new Npla<>(posExsF, negExsF, undExsF, beam, perPos, perNeg); 350 Couple<DSTDLTree,Npla<SortedSet<OWLIndividual>, SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double>> pos= new Couple<>(); 351 pos.setFirstElement(posTree); 352 pos.setSecondElement(npla1); 353 // negative branch 354 Couple<DSTDLTree,Npla<SortedSet<OWLIndividual>, SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double>> neg= new Couple<>(); 355 neg.setFirstElement(negTree); 356 neg.setSecondElement(npla2); 357 stack.push(neg); 358 stack.push(pos); 359 lastTrees.push(currentTree); 360 361 } 362 else if(mass.getNonSpecificityMeasureValue()<0.1){ 363 //System.out.println(); 364 DLTreesRefinementOperator dlTreesRefinementOperator = (DLTreesRefinementOperator)operator; 365 366 //System.out.println("is null?: "+dlTreesRefinementOperator==null); 367 //Set<OWLClassExpression> 368 369 //refine = dlTreesRefinementOperator.refine(dataFactory.getOWLThing(), posExs, negExs); 370 Set<OWLClassExpression> refine = null; 371 if (lastTrees.isEmpty()){ 372 refine = dlTreesRefinementOperator.refine(dataFactory.getOWLThing(), posExs, negExs); 373 } 374 else 375 refine = dlTreesRefinementOperator.refine(lastTrees.pop().getRoot(), posExs, negExs); 376 377 378 //ArrayList<OWLClassExpression> exps=new ArrayList<OWLClassExpression>(operator.refine(OWL_THING)); 379 OWLClassExpression[] cConcepts = new OWLClassExpression[refine.size()]; // concept generation 380 cConcepts = refine.toArray(cConcepts); 381 382 // select node concept 383 Couple<OWLClassExpression,MassFunction> newRootConcept = null; 384 if (dlTreesRefinementOperator.getRo() ==DLTreesRefinementOperator.ORIGINAL) // 3: the original refinement operator for terminological trees 385 newRootConcept= heuristic.selectBestConceptDST(cConcepts, posExs, negExs, undExs, prPos, prNeg); 386 else 387 newRootConcept= heuristic.selectWorstConceptDST(cConcepts, posExs, negExs, undExs, prPos, prNeg); // otherwise select the worst concept 388 389 //heuristic.selectBestConceptDST(cConcepts, posExs, negExs, undExs, prPos, prNeg); 390 MassFunction refinementMass = newRootConcept.getSecondElement(); 391 392 //logger.debug(newRootConcept.getFirstElement()+"----"+refinementMass); 393 SortedSet<OWLIndividual> posExsT = new TreeSet<>(); 394 SortedSet<OWLIndividual> negExsT = new TreeSet<>(); 395 SortedSet<OWLIndividual> undExsT = new TreeSet<>(); 396 SortedSet<OWLIndividual> posExsF = new TreeSet<>(); 397 SortedSet<OWLIndividual> negExsF = new TreeSet<>(); 398 SortedSet<OWLIndividual> undExsF = new TreeSet<>(); 399 400 //split(newRootConcept.getFirstElement(), posExs, negExs, undExs, posExsT, negExsT, undExsT, posExsF, negExsF, undExsF); 401 Split.split(newRootConcept.getFirstElement(), dataFactory, reasoner, posExs, negExs, undExs, posExsT, negExsT, undExsT, posExsF, negExsF, undExsF); 402 // select node concept 403 404 //tree.setRoot(newRootConcept.getFirstElement(), refinementMass); 405 currentTree.setRoot(newRootConcept.getFirstElement(), refinementMass); 406 // undExsT = union(undExsT, 407 // tree.setPosTree(induceDSTDLTree(posExsT, negExsT, undExsT, dim, prPos, prNeg)); 408 // tree.setNegTree(induceDSTDLTree(posExsF, negExsF, undExsF, dim, prPos, prNeg)); 409 410 DSTDLTree posTree= new DSTDLTree(); 411 DSTDLTree negTree= new DSTDLTree(); // recursive calls simulation through iteration 412 413 414 currentTree.setPosTree(posTree); 415 currentTree.setNegTree(negTree); 416 Npla<SortedSet<OWLIndividual>, SortedSet<OWLIndividual>, SortedSet<OWLIndividual>, Integer, Double, Double> npla1 = new Npla<>(posExsT, negExsT, undExsT, beam, perPos, perNeg); 417 Npla<SortedSet<OWLIndividual>, SortedSet<OWLIndividual>, SortedSet<OWLIndividual>, Integer, Double, Double> npla2 = new Npla<>(posExsF, negExsF, undExsF, beam, perPos, perNeg); 418 Couple<DSTDLTree,Npla<SortedSet<OWLIndividual>,SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double>> pos= new Couple<>(); 419 pos.setFirstElement(posTree); 420 pos.setSecondElement(npla1); 421 // negative branch 422 Couple<DSTDLTree,Npla<SortedSet<OWLIndividual>,SortedSet<OWLIndividual>,SortedSet<OWLIndividual>, Integer, Double, Double>> neg= new Couple<>(); 423 neg.setFirstElement(negTree); 424 neg.setSecondElement(npla2); 425 stack.push(neg); 426 stack.push(pos); 427 lastTrees.push(currentTree); 428 }else{ 429 430 if (perPos > perNeg) { // no negative 431 currentTree.setRoot(dataFactory.getOWLThing(), mass); // set positive leaf 432 // return tree; 433 } 434 else {// no positive 435 currentTree.setRoot(dataFactory.getOWLNothing(), mass); // set negative leaf 436 // return tree; 437 } 438 439 } 440 441 } 442 } 443 444 } 445 446 currentmodel= tree; 447 stop=true; 448 return tree; 449 } 450 451 @SuppressWarnings({ "unchecked", "rawtypes" }) 452 private void classifyExampleDST(List<Couple<Integer,MassFunction<Integer>>> list,OWLIndividual indTestEx, DSTDLTree tree) { 453 454 455 // System.out.println("BBA "+m); 456 457 Stack<DSTDLTree> stack= new Stack<>(); 458 stack.push(tree); 459 460 461 //OWLDataFactory dataFactory = kb.getDataFactory(); 462 while (!stack.isEmpty()){ 463 464 DSTDLTree currenttree=stack.pop(); 465 OWLClassExpression rootClass = currenttree.getRoot(); 466 MassFunction m= currenttree.getRootBBA(); 467 if (rootClass.equals(dataFactory.getOWLThing())){ 468 // System.out.println("Caso 1"); 469 Couple<Integer,MassFunction<Integer>> result= new Couple<>(); 470 result.setFirstElement(+1); 471 result.setSecondElement(m); 472 list.add(result); 473 // if(testConcepts!=null){ 474 // if(kb.getReasoner().hasType(kb.getIndividuals()[indTestEx], testConcepts[0])) 475 // tree.addPosExample(indTestEx); 476 // else if (kb.getReasoner().hasType(kb.getIndividuals()[indTestEx], dataFactory.getOWLObjectComplementOf(testConcepts[0]))) 477 // tree.addNegExample(indTestEx); 478 // else{ 479 // tree.addPosExample(indTestEx); 480 // tree.addNegExample(indTestEx); 481 // } 482 // } 483 } 484 else if (rootClass.equals(dataFactory.getOWLNothing())){ 485 // System.out.println("Caso 2"); 486 Couple<Integer,MassFunction<Integer>> result= new Couple<>(); 487 result.setFirstElement(-1); 488 result.setSecondElement(m); 489 list.add(result); 490 491 } 492 else if (reasoner.hasType(rootClass, indTestEx)){ 493 //System.out.println(kb.getReasoner().hasType(kb.getIndividuals()[indTestEx], rootClass)); 494 if (currenttree.getPosSubTree()!=null){ 495 496// classifyExampleDST( list, indTestEx, tree.getPosSubTree()); 497 stack.push(currenttree.getPosSubTree()); 498 // System.out.println("------"); 499 } 500 else{ 501 // System.out.println("Caso 4"); 502 Couple<Integer,MassFunction<Integer>> result= new Couple<>(); 503 result.setFirstElement(+1); 504 result.setSecondElement(m); 505 list.add(result); 506 // System.out.println("ADdded"); 507 } 508 } 509 else if (reasoner.hasType(dataFactory.getOWLObjectComplementOf(rootClass), indTestEx)){ 510 // System.out.println(kb.getReasoner().hasType(kb.getIndividuals()[indTestEx], dataFactory.getOWLObjectComplementOf(rootClass))); 511 if (currenttree.getNegSubTree()!=null){ 512// classifyExampleDST(list,indTestEx, tree.getNegSubTree()); 513 stack.push(currenttree.getNegSubTree()); 514 // System.out.println("#######"); 515 } 516 else{ 517 // System.out.println("Caso 6"+ tree); 518 Couple<Integer,MassFunction<Integer>> result= new Couple<>(); 519 result.setFirstElement(-1); 520 result.setSecondElement(m); 521 list.add(result); 522 // System.out.println("ADdded"); 523 } 524 } 525 else{ 526 //follow both paths 527 if (currenttree.getPosSubTree()!=null){ 528 // System.out.println("Caso 7"); 529 530// classifyExampleDST(list, indTestEx, tree.getPosSubTree()); 531 532 stack.push(currenttree.getPosSubTree()); 533 } 534 else{ 535 // System.out.println("Caso 8"); 536 Couple<Integer,MassFunction<Integer>> result= new Couple<>(); 537 result.setFirstElement(+1); 538 result.setSecondElement(m); 539 list.add(result); 540 // System.out.println("ADdded"); 541 } 542 //System.out.println("---->"); 543 if (currenttree.getNegSubTree()!=null){ 544 // System.out.println("Caso 9"); 545// classifyExampleDST(list,indTestEx, tree.getNegSubTree()); 546 stack.push(currenttree.getNegSubTree()); 547 } 548 else{ 549 Couple<Integer,MassFunction<Integer>> result= new Couple<>(); 550 result.setFirstElement(-1); 551 result.setSecondElement(m); 552 list.add(result); 553 // System.out.println("ADdded"); 554 } 555 556 } 557 558 559 } 560 // System.out.println("Tree "+ tree); 561 } 562 563 public DSTDLTree getCurrentmodel() { 564 return currentmodel; 565 } 566 567 public void setCurrentmodel(DSTDLTree currentmodel) { 568 this.currentmodel = currentmodel; 569 } 570 571 @SuppressWarnings({ }) 572 public int classifyExamplesDST(OWLIndividual indTestEx, DSTDLTree tree) { 573 //int length = testConcepts!=null?testConcepts.length:1; 574 //for (int c=0; c < length; c++) { 575 MassFunction<Integer> bba = getBBA(indTestEx, tree); // to have a soft prediction 576 int result= predict(bba); 577 return result;// belief or plausibility or confirmation function computation 578 579 //} 580 } 581 582 @SuppressWarnings({ "unchecked", "rawtypes" }) 583 public MassFunction<Integer> getBBA(OWLIndividual indTestEx, EvidentialModel tree) { 584 // for now the method is not quite general for making predictions via other algorithms.tree.models, e.g. Evidential k-NN 585 586 DSTDLTree model= (DSTDLTree) tree; // only classification with DST trees are supported for now 587 ArrayList<Couple<Integer, MassFunction<Integer>>> list; 588// System.out.println("Tree \n"+ model); 589 list= new ArrayList<>(); 590 classifyExampleDST(list,indTestEx, model); 591 // BBA from the reached leaves 592// System.out.println("Lista di foglie"); 593 //System.out.println(list); 594 MassFunction<Integer> bba=list.get(0).getSecondElement(); 595 596 MassFunction<Integer>[] others= new MassFunction[(list.size()-1)]; 597 //System.out.println("_____________BBA TO COMBINE______________________"); 598 //System.out.println("BBA: "+bba); 599 for(int i=1; i<list.size();i++){ 600 MassFunction next=list.get(i).getSecondElement(); 601//combination rule 602 others[i-1]=next; 603 } 604 if(others.length>=1){ 605 bba=bba.combineEvidences(others); 606 607 } 608 return bba; 609 } 610 611 /** 612 * Implementation of forcing criterion for the final class assignement 613 * @param bba 614 */ 615 private int predict(MassFunction<Integer> bba) { 616 ArrayList<Integer> hypothesis= new ArrayList<>(); 617 hypothesis.add(+1); 618 double confirmationFunctionValuePos = bba.getConfirmationFunctionValue(hypothesis); 619 // double confirmationFunctionValuePos = bba.calcolaBeliefFunction(ipotesi); 620 // not concept 621 ArrayList<Integer> hypothesis2= new ArrayList<>(); 622 hypothesis2.add(-1); 623 double confirmationFunctionValueNeg = bba.getConfirmationFunctionValue(hypothesis2); 624 // double confirmationFunctionValueNeg = bba.calcolaBeliefFunction(ipotesi2); 625 ArrayList<Integer> hypothesis3= new ArrayList<>(); 626 hypothesis3.add(-1); 627 hypothesis3.add(+1); 628 double confirmationFunctionValueUnc = bba.getConfirmationFunctionValue(hypothesis3); 629 // double confirmationFunctionValueUnc = bba.calcolaBeliefFunction(ipotesi3); 630 631 //System.out.println(confirmationFunctionValuePos+ " vs. "+ confirmationFunctionValueNeg+ "vs." +confirmationFunctionValueUnc); 632 633 if((confirmationFunctionValueUnc>confirmationFunctionValuePos)&&(confirmationFunctionValueUnc>confirmationFunctionValueNeg)) 634 if (confirmationFunctionValuePos>confirmationFunctionValueNeg) 635 return +1; 636 else if (confirmationFunctionValuePos<confirmationFunctionValueNeg) 637 return -1; 638 else return 0; 639 else if(confirmationFunctionValuePos>=confirmationFunctionValueNeg) 640 return +1; 641 else 642 return -1; 643 644 645 } 646 647 @Override 648 public void start() { 649 // TODO Auto-generated method stub 650 651 652 PosNegUndLP learningProblem2 = (PosNegUndLP)learningProblem; 653 SortedSet<OWLIndividual> posExs = (SortedSet<OWLIndividual>)learningProblem2.getPositiveExamples(); 654 SortedSet<OWLIndividual> negExs = (SortedSet<OWLIndividual>)learningProblem2.getNegativeExamples(); 655 SortedSet<OWLIndividual> undExs = (SortedSet<OWLIndividual>)learningProblem2.getUncertainExamples(); 656 657 //System.out.printf("--- Query Concept #%d \n",c); 658 659 // the individuals of the ABox are the training individuals 660 //OWLIndividual[] trainingExs= reasoner.getIndividuals().toArray(new OWLIndividual[reasoner.getIndividuals().size()]); 661 //boolean binaryClassification= false; // when you use the evidential version of TDT model you must use only a ternary splitting 662 //Split.splitting(dataFactory, reasoner, trainingExs, posExs, negExs, undExs, classToDescribe, binaryClassification); 663 664 prPos = (double)posExs.size()/(posExs.size()+ negExs.size()+undExs.size()); 665 prNeg = (double)negExs.size()/(posExs.size()+ negExs.size()+undExs.size()); 666 667 //System.out.println("Training set composition: "+ posExs.size()+" - "+ negExs.size()+"-"+undExs.size()); 668 669 double normSum = prPos+prNeg; 670 if (normSum==0) { prPos=.5; prNeg=.5; } 671 else { prPos=prPos/normSum; prNeg=prNeg/normSum; } 672 673 System.out.printf("New learning problem prepared.\n"); 674 System.out.println("Learning a tree "); 675 currentmodel= induceDSTDLTree(posExs, negExs, undExs); // training procedure for induce a DSTTDT 676 677 stop(); 678 679 680 } 681 682 @Override 683 public void stop() { 684 // TODO Auto-generated method stub 685 stop=true; 686 } 687 688 @Override 689 public boolean isRunning() { 690 // TODO Auto-generated method stub 691 return !(stop); 692 } 693 694 @Override 695 public OWLClassExpression getCurrentlyBestDescription() { 696 // TODO Auto-generated method stub 697 OWLClassExpression owlClassExpression = DSTDLTree.deriveDefinition(currentmodel, false); 698 return owlClassExpression; 699 } 700 701 @Override 702 public EvaluatedDescription getCurrentlyBestEvaluatedDescription() { 703 // TODO Auto-generated method stub 704 return null; 705 } 706 707 708 709}