Reasoners and rule engines: Jena, 온톨로지 추론기능 구현

     



Jena API의 기능중에 하나인 Inference(추론) 기능에 대한 설명입니다. 공식 메뉴얼은 아래 링크.


http://jena.apache.org/documentation/inference/index.html





RDF사용시 추론기능을 자바로 구현하는 내용이 담겨있습니다. 참고로 온톨로지 API를 사용한다면 (OntModel을 사용한다면) 자동적으로 추론모델이 포함되어 있기때문에 사용할 필요가 없습니다. 단지 RDF에서만 추론기능이 가능한 InfModel을 제공합니다. 사실 추론기능은 툴로 사용이 가능하기때문에 그다지 쓰지는 않을 것 같지만, 온톨로지를 자동적으로 구성해주는 프로그램을 제작할 경우 필요할 것 같습니다.


일단 Jena에서 사용가능한 추론은 다음과 같습니다.

  • 이행성 추론기: Transitive를 추론해줍니다. Transitive란 B가 A의 서브클래스이고 C가 B의 서브클래스이면 C는 A에 서브클래스가 되는 속성입니다.
  • RDFS rule 추론기: RDF 스키마 설정에 따른 추론을 해줍니다.
  • OWL,OWL Mini, OWL Micro Reasoners: OWL/Lite에 대한 추론을 해줍니다.
  • Generic rule 추론기: 유저가 정한 룰을 참고로 추론을 해줍니다.

역시나 그 다음 쭈욱 읽어보니 글로만 읽기에는 힘든 내용이였습니다. 추론기능을 jena API를 통해 자바로 구현하려는 내용인데 예제가 너무 없고 이론 설명만 너무 많군요. 이론이 중요하지 않은 것은 아니지만.. 이해가 안되는것은 어쩔 수 없네요. 간단히 추론 기능을 넣은 예제를 실행해보고 코드를 분석해보면서 이해해 보도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.util.Iterator;
 
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ValidityReport;
import com.hp.hpl.jena.reasoner.ValidityReport.Report;
import com.hp.hpl.jena.reasoner.rulesys.RDFSRuleReasonerFactory;
 
 
public class Main {
    
    public static void main(String[] args){
    
        OntModel m =  ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null );
        m.read("file:c:/test1.owl");
        
        Reasoner reasoner = RDFSRuleReasonerFactory.theInstance().create(null);
        InfModel infmodel = ModelFactory.createInfModel(reasoner, m);
        
        ValidityReport validity = infmodel.validate();
    
        
        if(validity.isValid()){
            System.out.println("OK");
        }else{
            System.out.println("Conflicts");
            for(Iterator<Report> j = validity.getReports(); j.hasNext();){
                System.out.println(" - "+j.next());
            }
        }
    }
}
 


test1과 test2의 owl은 제가 만든 스마트폰에 관련된 온톨로지입니다. 1은 잘못된 것이 없는 온톨로지이지만 2의 경우는 hasDisplay라는 datatype 속성 하나가 범위를 벗어난 값을 가지고 있습니다. 원래는 float형태의 값을 가지고 있어야하지만 iPhone3라는 객체에서 3이라는 string형태의 값을 가지도록 저장했습니다. 


모델을 read할때 test1과 test2를 번갈아가면서 실행할 경우 1의 경우는 "OK"가 출력되고 2의 경우는 "Conflicts"와 함게 에러가 나오게 됩니다. 추론을 했는데 잘못된 부분이 발견된 것이라고 볼 수 있습니다. 


코드를 보시면 Reasoner를 선언하고 InfModel을 선언하여 인자값으로 Reasoner와 모델 m을 입력합니다. 이렇게되면 추론기능이 있는 새로운 모델 infmodel이 만들어집니다. (m과는 별개) 새로만든 모델의 valid를 확인하기 위해 ValidityReport 클래스를 만들고 infmodel.validate()메소드를 호출합니다. 이렇게되면 추론된 결과를 ValidityReport 클래스에서 저장하고 있고 isValid()메소드를 통해 확인할 수 있습니다. if문을 사용해 모델이 이상없으면 OK를 출력하고 이상이 있으면 Conflicts를 출력하고 이상있는 부분을 iterator로 반환합니다.


이번에는 OntModel에 바로 추론기를 붙여보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.util.Iterator;
 
import com.hp.hpl.jena.ontology.Individual;
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.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ValidityReport;
import com.hp.hpl.jena.reasoner.ValidityReport.Report;
import com.hp.hpl.jena.reasoner.rulesys.RDFSRuleReasonerFactory;
 
 
public class Main {
    
    public static void main(String[] args){
            OntModelSpec oms= new OntModelSpec(OntModelSpec.OWL_MEM_RDFS_INF);
 
        OntModel m =  ModelFactory.createOntologyModel( oms, null );
        m.read("file:c:/test.owl");
 
        ValidityReport validity = m.validate();
        
        if(validity.isValid()){
            System.out.println("OK");
        }else{
            System.out.println("Conflicts");
            for(Iterator<Report> j = validity.getReports(); j.hasNext();){
                System.out.println(" - "+j.next());
            }
        }
    }
}
 


단지 OntModelSpec에 추론기능이 있는 인자값을 사용하기만 하면 자동적으로 추론기능이 생기게 됩니다. 만약 추론기능이 없는 OntModelSpec을 사용한경우, validate()메소드 호출시 에러가 발생합니다


OntModelSpec에서 추론기능을 추가할경우 여러가지가 있는데 이는 지난 OWL 포스팅에서 OntModelSpec부분에 첨부한 표를 보면 쉽게 이해할 수 있다. 가장 좋은 것은 OWL_MEM_RULE_INF인것 같다. OWL/FULL을 지원하기때문에 어떤 OWL언어에서도 지원이 될 것이고, 위에 코드를 OWL_MEM_RULE_INF로 바꿔서 실행할 경우 안보였던 추론까지 나오게 된다. 즉 더 강력한 추론기인 셈이다.






간단하게 jena에서 제공하는 추론기능을 java로 구현해 보았다. 홈페이지 메뉴얼에 비하면 아주 적은 양으로도 구현해 봤지만 홈페이지에는 더 자세한 내용이 나오게 된다. RDF와 OWL의 추론의 차이점이나 새로운 룰을 추가하는 방법. 룰을 표기하는 언어 등. 상당히 자세하게 나오지만 아직은 필요하지 않은 것 같아서 그냥 훑어보고 넘어갔다. 아마 sparQL까지 보고난후 실제적으로 프로그램을 만들때 참고하는 정도로 필요할 것 같다.



반응형

댓글

Designed by JB FACTORY