From: <lor...@us...> - 2012-08-23 13:19:14
|
Revision: 3834 http://dl-learner.svn.sourceforge.net/dl-learner/?rev=3834&view=rev Author: lorenz_b Date: 2012-08-23 13:19:03 +0000 (Thu, 23 Aug 2012) Log Message: ----------- Started feature to explain score in enrichment algorithms and return pos and neg examples. Modified Paths: -------------- trunk/components-core/pom.xml trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java trunk/components-core/src/main/java/org/dllearner/core/AbstractAxiomLearningAlgorithm.java Added Paths: ----------- trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner2.java Modified: trunk/components-core/pom.xml =================================================================== --- trunk/components-core/pom.xml 2012-08-23 13:13:39 UTC (rev 3833) +++ trunk/components-core/pom.xml 2012-08-23 13:19:03 UTC (rev 3834) @@ -242,7 +242,12 @@ <artifactId>jsexp</artifactId> <version>0.1.0</version> </dependency> - + + <dependency> + <groupId>xerces</groupId> + <artifactId>xercesImpl</artifactId> + <version>2.8.0</version> + </dependency> </dependencies> <dependencyManagement> <dependencies> Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java 2012-08-23 13:13:39 UTC (rev 3833) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java 2012-08-23 13:19:03 UTC (rev 3834) @@ -20,6 +20,11 @@ package org.dllearner.algorithms.properties; import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; import org.dllearner.core.AbstractAxiomLearningAlgorithm; import org.dllearner.core.ComponentAnn; @@ -27,12 +32,14 @@ import org.dllearner.core.config.ConfigOption; import org.dllearner.core.config.ObjectPropertyEditor; import org.dllearner.core.owl.FunctionalObjectPropertyAxiom; +import org.dllearner.core.owl.Individual; import org.dllearner.core.owl.ObjectProperty; import org.dllearner.kb.SparqlEndpointKS; import org.dllearner.kb.sparql.SparqlEndpoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.hp.hpl.jena.query.ParameterizedSparqlString; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Model; @@ -51,6 +58,8 @@ public FunctionalObjectPropertyAxiomLearner(SparqlEndpointKS ks){ this.ks = ks; + posExamplesQueryTemplate = new ParameterizedSparqlString("SELECT ?s WHERE {?s ?p ?o1. FILTER NOT EXISTS {?s ?p ?o2. FILTER(?o1 != ?o2)} }"); + negExamplesQueryTemplate = new ParameterizedSparqlString("SELECT ?s WHERE {?s ?p ?o1. ?s ?p ?o2. FILTER(?o1 != ?o2)}"); } public ObjectProperty getPropertyToDescribe() { @@ -59,6 +68,8 @@ public void setPropertyToDescribe(ObjectProperty propertyToDescribe) { this.propertyToDescribe = propertyToDescribe; + posExamplesQueryTemplate.setIri("p", propertyToDescribe.getURI().toString()); + negExamplesQueryTemplate.setIri("p", propertyToDescribe.getURI().toString()); } @Override @@ -86,36 +97,36 @@ } private void runSPARQL1_0_Mode() { - Model model = ModelFactory.createDefaultModel(); + workingModel = ModelFactory.createDefaultModel(); int limit = 1000; int offset = 0; String baseQuery = "CONSTRUCT {?s <%s> ?o.} WHERE {?s <%s> ?o} LIMIT %d OFFSET %d"; String query = String.format(baseQuery, propertyToDescribe.getName(), propertyToDescribe.getName(), limit, offset); Model newModel = executeConstructQuery(query); while(!terminationCriteriaSatisfied() && newModel.size() != 0){System.out.println(query); - model.add(newModel); + workingModel.add(newModel); // get number of instances of s with <s p o> query = String.format( "SELECT (COUNT(DISTINCT ?s) AS ?all) WHERE {?s <%s> ?o.}", propertyToDescribe.getName()); - ResultSet rs = executeSelectQuery(query, model); + ResultSet rs = executeSelectQuery(query, workingModel); QuerySolution qs; int all = 1; while (rs.hasNext()) { qs = rs.next(); all = qs.getLiteral("all").getInt(); } - System.out.println(all); + // get number of instances of s with <s p o> <s p o1> where o != o1 query = "SELECT (COUNT(DISTINCT ?s) AS ?functional) WHERE {?s <%s> ?o1. FILTER NOT EXISTS {?s <%s> ?o2. FILTER(?o1 != ?o2)} }"; query = query.replace("%s", propertyToDescribe.getURI().toString()); - rs = executeSelectQuery(query, model); + rs = executeSelectQuery(query, workingModel); int functional = 1; while (rs.hasNext()) { qs = rs.next(); functional = qs.getLiteral("functional").getInt(); } - System.out.println(functional); + if (all > 0) { currentlyBestAxioms.clear(); currentlyBestAxioms.add(new EvaluatedAxiom( @@ -155,13 +166,21 @@ } public static void main(String[] args) throws Exception{ - FunctionalObjectPropertyAxiomLearner l = new FunctionalObjectPropertyAxiomLearner(new SparqlEndpointKS(SparqlEndpoint.getEndpointDBpediaLiveAKSW())); - l.setPropertyToDescribe(new ObjectProperty("http://dbpedia.org/ontology/wikiPageExternalLink")); - l.setMaxExecutionTimeInSeconds(10); -// l.setForceSPARQL_1_0_Mode(true); + FunctionalObjectPropertyAxiomLearner l = new FunctionalObjectPropertyAxiomLearner(new SparqlEndpointKS(SparqlEndpoint.getEndpointDBpedia())); + l.setPropertyToDescribe(new ObjectProperty("http://dbpedia.org/ontology/league")); + l.setMaxExecutionTimeInSeconds(20); + l.setForceSPARQL_1_0_Mode(true); l.init(); l.start(); - System.out.println(l.getCurrentlyBestEvaluatedAxioms(5)); + List<EvaluatedAxiom> axioms = l.getCurrentlyBestEvaluatedAxioms(5); + System.out.println(axioms); + + for(EvaluatedAxiom axiom : axioms){ + printSubset(l.getPositiveExamples(axiom), 10); + printSubset(l.getNegativeExamples(axiom), 10); + l.explainScore(axiom); + } + } } Added: trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner2.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner2.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner2.java 2012-08-23 13:19:03 UTC (rev 3834) @@ -0,0 +1,221 @@ +/** + * Copyright (C) 2007-2011, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.dllearner.algorithms.properties; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; + +import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.Level; +import org.apache.log4j.SimpleLayout; +import org.dllearner.core.AbstractAxiomLearningAlgorithm; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.EvaluatedAxiom; +import org.dllearner.core.config.ConfigOption; +import org.dllearner.core.config.ObjectPropertyEditor; +import org.dllearner.core.owl.Description; +import org.dllearner.core.owl.Individual; +import org.dllearner.core.owl.NamedClass; +import org.dllearner.core.owl.ObjectProperty; +import org.dllearner.core.owl.ObjectPropertyDomainAxiom; +import org.dllearner.kb.SparqlEndpointKS; +import org.dllearner.kb.sparql.SparqlEndpoint; +import org.dllearner.reasoning.SPARQLReasoner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.hp.hpl.jena.query.ParameterizedSparqlString; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.vocabulary.OWL; +import com.hp.hpl.jena.vocabulary.RDF; +import com.hp.hpl.jena.vocabulary.RDFS; + +@ComponentAnn(name="objectproperty domain axiom learner", shortName="opldomain", version=0.1) +public class ObjectPropertyDomainAxiomLearner2 extends AbstractAxiomLearningAlgorithm { + + private static final Logger logger = LoggerFactory.getLogger(ObjectPropertyDomainAxiomLearner2.class); + + private Map<Individual, SortedSet<Description>> individual2Types; + + + @ConfigOption(name="propertyToDescribe", description="", propertyEditorClass=ObjectPropertyEditor.class) + private ObjectProperty propertyToDescribe; + + public ObjectPropertyDomainAxiomLearner2(SparqlEndpointKS ks){ + this.ks = ks; + super.posExamplesQueryTemplate = new ParameterizedSparqlString("SELECT DISTINCT ?s WHERE {?s a ?type}"); + super.negExamplesQueryTemplate = new ParameterizedSparqlString("SELECT DISTINCT ?s WHERE {?s ?p ?o. FILTER NOT EXISTS{?s a ?type}}"); + + } + + public ObjectProperty getPropertyToDescribe() { + return propertyToDescribe; + } + + public void setPropertyToDescribe(ObjectProperty propertyToDescribe) { + this.propertyToDescribe = propertyToDescribe; +// negExamplesQueryTemplate.clearParams(); +// posExamplesQueryTemplate.clearParams(); + } + + @Override + public void start() { + iterativeQueryTemplate.setIri("p", propertyToDescribe.getName()); + logger.info("Start learning..."); + startTime = System.currentTimeMillis(); + fetchedRows = 0; + currentlyBestAxioms = new ArrayList<EvaluatedAxiom>(); + + if(returnOnlyNewAxioms){ + //get existing domains + Description existingDomain = reasoner.getDomain(propertyToDescribe); + if(existingDomain != null){ + existingAxioms.add(new ObjectPropertyDomainAxiom(propertyToDescribe, existingDomain)); + if(reasoner.isPrepared()){ + if(reasoner.getClassHierarchy().contains(existingDomain)){ + for(Description sup : reasoner.getClassHierarchy().getSuperClasses(existingDomain)){ + existingAxioms.add(new ObjectPropertyDomainAxiom(propertyToDescribe, existingDomain)); + logger.info("Existing domain(inferred): " + sup); + } + } + + } + } + } + + runSPARQL1_0_Mode(); + logger.info("...finished in {}ms.", (System.currentTimeMillis()-startTime)); + } + + private void runSPARQL1_0_Mode() { + workingModel = ModelFactory.createDefaultModel(); + int limit = 1000; + int offset = 0; + String baseQuery = "CONSTRUCT {?s a ?type.} WHERE {?s <%s> ?o. ?s a ?type.} LIMIT %d OFFSET %d"; + String query = String.format(baseQuery, propertyToDescribe.getName(), limit, offset); + Model newModel = executeConstructQuery(query); + while(!terminationCriteriaSatisfied() && newModel.size() != 0){ + workingModel.add(newModel); + // get number of distinct subjects + query = "SELECT (COUNT(DISTINCT ?s) AS ?all) WHERE {?s a ?type.}"; + ResultSet rs = executeSelectQuery(query, workingModel); + QuerySolution qs; + int all = 1; + while (rs.hasNext()) { + qs = rs.next(); + all = qs.getLiteral("all").getInt(); + } + + // get class and number of instances + query = "SELECT ?type (COUNT(DISTINCT ?s) AS ?cnt) WHERE {?s a ?type.} GROUP BY ?type"; + rs = executeSelectQuery(query, workingModel); + + if (all > 0) { + currentlyBestAxioms.clear(); + while(rs.hasNext()){ + qs = rs.next(); + Resource type = qs.get("type").asResource(); + //omit owl:Thing as trivial domain + if(type.equals(OWL.Thing)){ + continue; + } + currentlyBestAxioms.add(new EvaluatedAxiom( + new ObjectPropertyDomainAxiom(propertyToDescribe, new NamedClass(type.getURI())), + computeScore(all, qs.get("cnt").asLiteral().getInt()))); + } + + } + offset += limit; + query = String.format(baseQuery, propertyToDescribe.getName(), limit, offset); + newModel = executeConstructQuery(query); + fillWithInference(newModel); + } + } + + private void fillWithInference(Model model){ + Model additionalModel = ModelFactory.createDefaultModel(); + if(reasoner.isPrepared()){ + for(StmtIterator iter = model.listStatements(null, RDF.type, (RDFNode)null); iter.hasNext();){ + Statement st = iter.next(); + Description cls = new NamedClass(st.getObject().asResource().getURI()); + if(reasoner.getClassHierarchy().contains(cls)){ + for(Description sup : reasoner.getClassHierarchy().getSuperClasses(cls)){ + additionalModel.add(st.getSubject(), st.getPredicate(), model.createResource(sup.toString())); + } + } + } + } + model.add(additionalModel); + } + + @Override + protected SortedSet<Individual> getPositiveExamples(EvaluatedAxiom evAxiom) { + ObjectPropertyDomainAxiom axiom = (ObjectPropertyDomainAxiom) evAxiom.getAxiom(); + posExamplesQueryTemplate.setIri("type", axiom.getDomain().toString()); + return super.getPositiveExamples(evAxiom); + } + + @Override + protected SortedSet<Individual> getNegativeExamples(EvaluatedAxiom evAxiom) { + ObjectPropertyDomainAxiom axiom = (ObjectPropertyDomainAxiom) evAxiom.getAxiom(); + negExamplesQueryTemplate.setIri("type", axiom.getDomain().toString()); + return super.getNegativeExamples(evAxiom); + } + + public static void main(String[] args) throws Exception{ + org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new SimpleLayout())); + org.apache.log4j.Logger.getRootLogger().setLevel(Level.INFO); + org.apache.log4j.Logger.getLogger(DataPropertyDomainAxiomLearner.class).setLevel(Level.INFO); + + SparqlEndpointKS ks = new SparqlEndpointKS(SparqlEndpoint.getEndpointDBpediaLiveAKSW()); + + SPARQLReasoner reasoner = new SPARQLReasoner(ks); + reasoner.prepareSubsumptionHierarchy(); + + + ObjectPropertyDomainAxiomLearner2 l = new ObjectPropertyDomainAxiomLearner2(ks); + l.setReasoner(reasoner); + l.setPropertyToDescribe(new ObjectProperty("http://dbpedia.org/ontology/league")); + l.setMaxFetchedRows(20000); + l.setMaxExecutionTimeInSeconds(20); + l.addFilterNamespace("http://dbpedia.org/ontology/"); +// l.setReturnOnlyNewAxioms(true); + l.init(); + l.start(); + + List<EvaluatedAxiom> axioms = l.getCurrentlyBestEvaluatedAxioms(10, 0.3); + System.out.println(axioms); + for(EvaluatedAxiom axiom : axioms){ + printSubset(l.getPositiveExamples(axiom), 10); + printSubset(l.getNegativeExamples(axiom), 10); + l.explainScore(axiom); + } + } + +} Modified: trunk/components-core/src/main/java/org/dllearner/core/AbstractAxiomLearningAlgorithm.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/core/AbstractAxiomLearningAlgorithm.java 2012-08-23 13:13:39 UTC (rev 3833) +++ trunk/components-core/src/main/java/org/dllearner/core/AbstractAxiomLearningAlgorithm.java 2012-08-23 13:19:03 UTC (rev 3834) @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -37,6 +38,7 @@ import org.dllearner.core.owl.Axiom; import org.dllearner.core.owl.ClassHierarchy; import org.dllearner.core.owl.Description; +import org.dllearner.core.owl.Individual; import org.dllearner.core.owl.NamedClass; import org.dllearner.kb.LocalModelBasedSparqlEndpointKS; import org.dllearner.kb.SparqlEndpointKS; @@ -116,6 +118,11 @@ protected ParameterizedSparqlString iterativeQueryTemplate; + protected Model workingModel; + protected ParameterizedSparqlString posExamplesQueryTemplate; + protected ParameterizedSparqlString negExamplesQueryTemplate; + + public AbstractAxiomLearningAlgorithm() { existingAxioms = new TreeSet<Axiom>(new AxiomComparator()); } @@ -255,7 +262,7 @@ } - protected Model executeConstructQuery(String query) { + protected Model executeConstructQuery(String query) {System.out.println(query); logger.debug("Sending query\n{} ...", query); if(ks.isRemote()){ SparqlEndpoint endpoint = ((SparqlEndpointKS) ks).getEndpoint(); @@ -266,7 +273,12 @@ queryExecution.setNamedGraphURIs(endpoint.getNamedGraphURIs()); try { Model model = queryExecution.execConstruct(); + fetchedRows += model.size(); timeout = false; + if(model.size() == 0){ + fullDataLoaded = true; + } + return model; } catch (QueryExceptionHTTP e) { if(e.getCause() instanceof SocketTimeoutException){ @@ -277,8 +289,13 @@ return ModelFactory.createDefaultModel(); } } else { - QueryExecution qexec = QueryExecutionFactory.create(query, ((LocalModelBasedSparqlEndpointKS)ks).getModel()); - return qexec.execConstruct(); + QueryExecution queryExecution = QueryExecutionFactory.create(query, ((LocalModelBasedSparqlEndpointKS)ks).getModel()); + Model model = queryExecution.execConstruct(); + fetchedRows += model.size(); + if(model.size() == 0){ + fullDataLoaded = true; + } + return model; } } @@ -456,6 +473,67 @@ filterNamespaces.add(namespace); } + protected SortedSet<Individual> getPositiveExamples(EvaluatedAxiom axiom){ + if(workingModel != null){ + SortedSet<Individual> posExamples = new TreeSet<Individual>(); + + ResultSet rs = executeSelectQuery(posExamplesQueryTemplate.toString(), workingModel); + while(rs.hasNext()){ + posExamples.add(new Individual(rs.next().get("s").asResource().getURI())); + } + + return posExamples; + } else { + throw new UnsupportedOperationException("Getting positive examples is not possible."); + } + } + + protected SortedSet<Individual> getNegativeExamples(EvaluatedAxiom axiom){ + if(workingModel != null){ + SortedSet<Individual> negExamples = new TreeSet<Individual>(); + + ResultSet rs = executeSelectQuery(negExamplesQueryTemplate.toString(), workingModel); + while(rs.hasNext()){ + negExamples.add(new Individual(rs.next().get("s").asResource().getURI())); + } + + return negExamples; + } else { + throw new UnsupportedOperationException("Getting negative examples is not possible."); + } + } + + protected void explainScore(EvaluatedAxiom evAxiom){ + int posExampleCnt = getPositiveExamples(evAxiom).size(); + int negExampleCnt = getNegativeExamples(evAxiom).size(); + int total = posExampleCnt + negExampleCnt; + StringBuilder sb = new StringBuilder(); + String lb = "\n"; + sb.append("######################################").append(lb); + sb.append("Explanation:").append(lb); + sb.append("Score(").append(evAxiom.getAxiom()).append(") = ").append(evAxiom.getScore().getAccuracy()).append(lb); + sb.append("Total number of resources:\t").append(total).append(lb); + sb.append("Number of positive examples:\t").append(posExampleCnt).append(lb); + sb.append("Number of negative examples:\t").append(negExampleCnt).append(lb); + sb.append("Complete data processed:\t").append(fullDataLoaded).append(lb); + sb.append("######################################"); + System.out.println(sb.toString()); + } + + protected static <E> void printSubset(Collection<E> collection, int maxSize){ + StringBuffer sb = new StringBuffer(); + int i = 0; + Iterator<E> iter = collection.iterator(); + while(iter.hasNext() && i < maxSize){ + sb.append(iter.next().toString()).append(", "); + i++; + } + if(iter.hasNext()){ + sb.append("...(").append(collection.size()-i).append(" more)"); + } + System.out.println(sb.toString()); + } + protected <K,T extends Set<V>, V> void addToMap(Map<K, T> map, K key, V value ){ T values = map.get(key); if(values == null){ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |