2

我有一个 RDF 图,所有类之间只有一个关系(RDFS.subClassOf 或 is-a)。

每个类的“大小”等于其子类的总数。每个 RDFS.subClassOf 属性的“大小”如果从子类总数较少的类连接,则为 0.5;如果从子类总数较多的类连接到子类总数较少的类,则为 1。

我想使用 Jena RDF/Ontology API 对路径中每个语义组件(类/关系)的所有大小进行算术总和。

例如,给定相机本体 ( http://protege.cim3.net/file/pub/ontologies/camera/camera.owl ) 路径之一是: Thing - PurchaseableItem - Lens :其总和为 (5 + 0.5 + 3 + 0.5 + 0) = 9。

4

1 回答 1

1

假设这建立在您之前关于构建您在问题中提到的路径类型的问题的答案之上,您可以使用:

public static int classSize( final Resource klass ) {
    return klass.getModel().listSubjectsWithProperty( RDFS.subClassOf, klass ).toList().size();
}

public static double pathSize( final List<Resource> path ) {
    int prevSize = classSize( path.get( 0 )); 
    double pathSum = prevSize;
    for ( int i = 1; i < path.size(); i++ ) {
        int currSize = classSize( path.get( i ));
        double linkWeight = currSize < prevSize ? 0.5 : 1.0;
        pathSum += linkWeight + currSize;
        prevSize = currSize;
    }
    return pathSum;
}

然后我们得到以下路径的总和。完整的代码遵循此输出。请注意,owl:Thing这里的大小为四,而不是您在问题中给出的五。如果这个想法是计算一个类作为对象出现在三元组中的次数,那么您链接到的 OWL 文件rdfs:subClassOf中只有四个三元组something rdfs:subClassOf owl:Thing,所以它的大小似乎应该是四个,而不是五。考虑到这一点,请注意“Thing-PurchaseableItem-Lens”路径的权重为 8,正如预期的那样(比 9 少一个,正如您在问题中提到的)。

4.0 [http://www.w3.org/2002/07/owl#Thing]
7.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem]
4.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Window]
4.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Range]
4.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Money]
10.0 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera]
8.0 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Lens]
8.0 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Body]
10.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Digital]
10.5 [http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Large-Format]

完整代码:

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

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.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDFS;

public class BFSInRDFWithJena {

    public static List<List<Resource>> BFS( final Model model, final Queue<List<Resource>> queue, final int depth ) {
        final List<List<Resource>> results = new ArrayList<>();
        while ( !queue.isEmpty() ) {
            final List<Resource> path = queue.poll();
            results.add( path );
            if ( path.size() < depth ) {
                final Resource last = path.get( path.size() - 1 );
                final StmtIterator stmt = model.listStatements( null, RDFS.subClassOf, last );
                while ( stmt.hasNext() ) {
                    final List<Resource> extPath = new ArrayList<>( path );
                    extPath.add( stmt.next().getSubject().asResource() );
                    queue.offer( extPath );
                }
            }
        }
        return results;
    }

    public static int classSize( final Resource klass ) {
        return klass.getModel().listSubjectsWithProperty( RDFS.subClassOf, klass ).toList().size();
    }

    public static double pathSize( final List<Resource> path ) {
        int prevSize = classSize( path.get( 0 )); 
        double pathSum = prevSize;
        for ( int i = 1; i < path.size(); i++ ) {
            int currSize = classSize( path.get( i ));
            double linkWeight = currSize < prevSize ? 0.5 : 1.0;
            pathSum += linkWeight + currSize;
            prevSize = currSize;
        }
        return pathSum;
    }

    public static void main( final String[] args ) throws IOException {
        final Model model = ModelFactory.createDefaultModel();
        try ( final InputStream in = BFSInRDFWithJena.class.getClassLoader().getResourceAsStream( "camera.owl" ) ) {
            model.read( in, null );
        }

        // setup the initial queue
        final Queue<List<Resource>> queue = new LinkedList<>();
        final List<Resource> thingPath = new ArrayList<>();
        thingPath.add( OWL.Thing.inModel( model ));
        queue.offer( thingPath );

        // Get the paths, and display them
        final List<List<Resource>> paths = BFS( model, queue, 4 );
        for ( List<Resource> path : paths ) {
            System.out.println( pathSize( path ) + " " + path );
        }
    }
}
于 2013-07-26T00:23:49.930 回答