Determining shortest distance between ontology concepts using Jena OntTools


For something I was trying to do, I wanted to determine the shortest distance between two concepts in an ontology. In some forum I was reading someone had suggested to use Jena’s findShortestPath() method. Couldn’t really find a solid example as to how this works, so here’s something that worked for me. May be there’s a better/proper way to do this, so if anyone knows how to, I’m happy to get some feedback (although I’m no longer using Jena for my work).

First of all here’s a good tutorial that explains how to set up Eclipse to work with Jena. It’s basically a Jena Hello World example.

I was working with an OWL ontology created in Protégé OWL and one of the major issues I ran into was I kept getting the following error:

WARN [main] (RDFDefaultErrorHandler.java:36) – file:///C:/Users/ProjectName/(line 741 column 35): {W102} Unqualified property attributes are not allowed. Property treated as a relative URI.

Found a few forums where others had also run into the same issue, but with no proper solution. At the same time, in some other forum someone had mentioned that Jena needed the ontology to be in RDF format, so what I did was I saved my ontology as RDF/XML:

image

and that was it!

Now that I could create the Jena model, here’s the function that I used to determine the shortest distance between two OWL Classes.

public static void FindJenaDistance() {

        // Jena implementation 

        long startTime = System.currentTimeMillis();
        
        // this file needs to be created by doing "Save As.." and "RDF/XML" for a 'normal' OWL file. Otherwise we get Jena parse errors
        String inputFileName = "C:/Users/.../data/owlfile.owl";

        String ns = "http://www.ihtsdo.org/";

        OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
        InputStream in = FileManager.get().open(inputFileName);
        model.read(in, "");        
        
        System.out.format("Ontology load time: (%7.2f sec)%n%n", (System.currentTimeMillis() - startTime) / 1000.0);        

        OntClass fromSubClass = model.getOntClass("http://www.ihtsdo.org/SCT_372418009");        
        OntClass toSuperClass = model.getOntClass("http://www.ihtsdo.org/SCT_106582005");

        Path path = OntTools.findShortestPath(model, fromSubClass, toSuperClass, Filter.any);

        if (path != null){
            int superClasses = 0;
            for (Statement s: path) {
                if (s.getObject().toString().startsWith(ns)) {
                    // filter out OWL Classes
                    superClasses++;
                    System.out.println(s.getObject());
                }
            }
            System.out.println("Shortest distance from " + fromSubClass + " to " + toSuperClass + " = " + superClasses);
        }else if (fromSubClass == toSuperClass){
            System.out.println("Same node");
        }else {
            System.out.println("No path from " + fromSubClass + " to " + toSuperClass);
        }   

        System.out.format("\nProcessing time: (%7.2f sec)%n%n", (System.currentTimeMillis() - startTime) / 1000.0);

    }

Advertisements
This entry was posted in General and tagged , , , . Bookmark the permalink.

17 Responses to Determining shortest distance between ontology concepts using Jena OntTools

  1. Anonymous says:

    It’s help me a lot. Thanks.

  2. Menaga says:

    can i have the source code for finding shortest distance between ontology concepts

  3. Najwa says:

    hi I am working with an OWL ontology created in Protégé OWL. I need to extract all parents(diret and indirect) of a concept(is an individual). this concept is related to his parents using relations« est contenu dans » or « est un sous concept de » (object properties) how can i do it please?

  4. Samira says:

    I run this code(in top of this page),,i use NetBeans and Jena and both of them work correct,,i try another program…….. but for this code or another code that use “findShortestPath”… my output is null!!!
    can you help me that why my code return “null” for path in findShortestPath function.
    I exactly code in this page…

    • Well, unfortunately I don’t know where exactly things are breaking, but did you make sure you saved the ontology in rdf/xml format as shown here? Also, did you debug the different lines in your program to figure out where exactly things are breaking..perhaps by printing out some message? Do you know if your Jena model is being created? If everything fails, I suggest you visit http://protege.stanford.edu/support.php and post your question there to the Protege-OWL/Jena experts. It’s been a few years since I used Protege last..sorry.
      Good luck!

  5. Samira says:

    I have another code that it must return shortest path from two node,,, but it return “null” for path,too…
    my code is:
    **************************************************************************

    package importskeleton;

    import com.hp.hpl.jena.graph.Node;
    import com.hp.hpl.jena.ontology.OntClass;
    import com.hp.hpl.jena.ontology.OntModel;
    import com.hp.hpl.jena.ontology.OntModelSpec;
    import com.hp.hpl.jena.ontology.OntTools;
    import com.hp.hpl.jena.ontology.OntTools.Path;
    import static com.hp.hpl.jena.ontology.OntTools.findShortestPath;
    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.util.FileManager;
    import com.hp.hpl.jena.util.iterator.Filter;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;

    public class FindShortestPath {
    static String inputFileName=”C:\\Users\\Samira\\Documents\\NetBeansProjects\\ImportSkeleton\\src\\main\\resources\\ka.owl”;

    public static void main (String[] args){
    // create an empty model
    OntModel model = ModelFactory.createOntologyModel();
    //OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
    // use the FileManager to find the input file
    InputStream in = FileManager.get().open( inputFileName );
    if (in == null) {
    throw new IllegalArgumentException(“File: ” + inputFileName + ” not found”);
    }

    // read the RDF/XML file
    model.read(in, “”);

    // find Shortest Path

    String ns = “”;

    OntClass superklas=model.createClass(ns+”Product”);
    OntClass ankklas=model.createClass(ns+”Book”);

    Path jalur = OntTools.findShortestPath(model, superklas, ankklas, Filter.any);
    //OntTools.Path jalur = findShortestPath(model, superklas, ankklas, Filter.any);
    System.out.println(“path: “+ jalur);
    int superkelas=0;

    if (jalur!=null){
    for(Statement s : jalur){
    if(s.getObject().toString().startsWith(ns)){
    superkelas++;
    System.out.println(s.getObject());
    }
    }
    System.out.println(“shortest path from “+ankklas+” to “+superklas+” = “+superkelas);
    }
    else if (ankklas==superklas){
    System.out.println(“Node yang sama”);
    }
    else if(jalur==null){
    System.out.println(“Nothing happened”);
    }
    else{
    jalur = OntTools.findShortestPath(model, ankklas, superklas, Filter.any);
    if (jalur != null){
    for (com.hp.hpl.jena.rdf.model.Statement s: jalur) {
    if (s.getObject().toString().startsWith(ns)) {
    superkelas++;
    System.out.println(s.getObject());
    }
    }
    superkelas++;
    }
    }
    //list of all paths that add of other site
    OntTools.Path path = findShortestPath(model, ankklas, superklas.getSuperClass(), Filter.any);
    List resources = new ArrayList();
    for (Statement s: path) {
    resources.add( s.getResource() );
    }
    }}

  6. Najwa says:

    i have this code to calculate distance between all individuals in the ontology but it doesn’t work help me please
    import com.hp.hpl.jena.ontology.OntModelSpec;
    import com.hp.hpl.jena.query.Query;
    import com.hp.hpl.jena.query.QueryExecution;
    import com.hp.hpl.jena.query.QueryExecutionFactory;
    import com.hp.hpl.jena.query.QueryFactory;
    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.Resource;
    import com.hp.hpl.jena.reasoner.ReasonerRegistry;
    import com.hp.hpl.jena.util.FileManager;
    import java.util.ArrayList;
    /**
    *
    * @author DELL
    */
    public class Main {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args)
    {
    // TODO code application logic here

    ArrayList synonymeList=new ArrayList();
    String URI= ” PREFIX Ontologiegeneriq: “;
    String NomFich= “C:\\SL0720\\Ontologie\\ontf2.owl” ;
    String Prefixe=”PREFIX rdf: ” ;
    Model model;
    model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RDFS_INF);
    FileManager.get().readModel( model, NomFich );
    FileManager.get().readModel( model, NomFich );
    System.out.println(ReasonerRegistry.getOWLReasoner());
    String queryString3 =Prefixe + URI+
    “select ?super ?sub (count(?mid) as ?distance) { ” +
    “?super :est_contenu_dans* ?mid.” +
    ” ?mid :est_contenu_dans+ ?sub .}”;
    Query query3 = QueryFactory.create(queryString3) ;
    QueryExecution qexec3 = QueryExecutionFactory.create(query3, model);
    ResultSet resultset3 = qexec3.execSelect() ;
    //Affichage du resultat
    int i=0;
    while(resultset3.hasNext())
    {
    QuerySolution row = resultset3.nextSolution();
    Resource as = (Resource) row.getResource(“super” + “sub”);
    String cs=as.getLocalName();
    cs=cs.replace(“_”, ” “);
    synonymeList.add(cs);
    System.out.println(“synonymeList[“+i+”]”+synonymeList.get(i));
    i++;
    }

    }

    }

    • Well, when you say “it doesn’t work”, I’m not sure if you can’t run it at all, or if you’re not getting the result you want. Either way, it has been about 3 years since I last worked with Jena/OWL, so unfortunately I’m not in a position to help you much. As mentioned in the post, did you save the .owl file in RDF/XML format first?

  7. Najwa says:

    yes i save it in RDF/XML format and it gives no result

    • Have you checked where exactly things are failing? What I would suggest is to see if the model is being created first before trying anything else. In other words, set a few breakpoints after the following lines:

      String inputFileName = “C:/Users/…/data/owlfile.owl”;
      String ns = “http://www.ihtsdo.org/”;
      OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
      InputStream in = FileManager.get().open(inputFileName);
      model.read(in, “”);

      and see if your model is correct (e.g., you can try to print out a few classes from your ontology). Is things are working fine, then you know it’s an issue with OntTools.findShortestPath().

  8. Anonymous says:

    Hi, thank you for this example is very helpful. But, Have you any idea how could we compute distance (not the path) between two classes in an ontology by considering relations (hierarchical or semantic) as indirect links ?? As far as I know the method findShortestPath() provided by jena api considers relations as directional links.

    • I’m a bit confused by your actual requirement. For hierarchical relationships, I think you should be able to use findShortestPath() method without any issues. You might want to check who the parent (or child) is first and then pass the parameters in the right order to findShortestPath(). I don’t think there is any easy way to determine the distance along non-hierarchical relations though. What I would suggest is to find an algorithm that determines all paths along all relations and then try to determine the shortest path for 2 given nodes. Might not be scalable though if you’re talking about a large ontology.

  9. hicham says:

    I run this code(in top of this page),,i use NetBeans and Jena and both of them work correct,,i try another program, but my output is null!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    can you help me that why my code return “null” f plzzzzzzzzzz

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s