AWS 기술 블로그

아마존 넵튠에서 온톨로지를 사용한 모델 기반 지식 그래프 만들기

본 게시글은 AWS Database Blog에 게시된 Model-driven graphs using OWL in Amazon Neptune by Mike Havey을 한국어 번역 및 편집하였습니다.

Amazon Neptune은 비즈니스 객체 간의 관계를 지식 그래프로 구축하는 데 사용할 수 있는 AWS에서 제공하는 그래프 데이터베이스 서비스입니다. 지식 그래프를 구축할 때, 이러한 관계의 표현을 관리하기 위한 적합한 모델은 무엇일까요? 그래프를 즉석에서 구축하기보다는 우리를 안내할 모델을 갖추는 것이 좋을 것입니다. 이번 포스트에서는 Web Ontology Language(OWL, 웹 온톨로지 언어)를 해당 모델의 언어로 사용합니다. 현대 조직의 예를 사용하여 OWL로 설명된 조직 모델에서 가상 회사의 조직 그래프를 구축하고 검증하는 방법을 보여드립니다. 우리는 하향식, 모델 중심 접근 방식을 사용하여 모델로부터 인스턴스를 검증하고 새로운 인스턴스를 채우기 위한 템플릿을 생성합니다.

OWL은 Resource Description Framework(RDF, 자원 기술 프레임워크)SPARQL Protocol and RDF Query Language(SPARQL, 스파클)와 같은 시맨틱 레이어 의 일부이며 Neptune에서 사용하기에 적합합니다. 다음 그림에 표시된 레이어는 월드 와이드 웹 컨소시엄(W3C)의 연결 데이터 표준을 잘 알려주고 있는 시각화 예시입니다. RDF(그래프 데이터 표현으로서)와 SPARQL(쿼리 언어로서)은 Neptune에서 제공하는 중요한 개념입니다. 그림에서 OWL은 RDF 위에 위치하며, 이는 RDF 데이터 모델을 지원하는 그래프 데이터베이스에서 사용할 수 있음을 나타냅니다. 그림에서 OWL과 RDF 사이에는 RDF Schema(RDFS)가 있는데, 이는 RDF 그래프의 클래스와 속성을 정의하기 위한 기본 언어입니다. 온톨로지 언어인 OWL은 RDFS가 할 수 있는 그 이상을 수행할 수 있습니다.

온톨로지(ontology)는 데이터 모델과 유사하지만 미묘하게 다릅니다. 데이터 모델링에 사용되는 UML(Unified Modeling Language)은 클래스들과 각 클래스에 속하는 속성(또는 특성)의 엄격한 목록에 해당합니다. UML은 종종 관계형 데이터베이스의 스키마를 모델링하는 데 사용됩니다. 모델은 엄격하지만, 모델링하는 관계형 테이블도 마찬가지로 엄격합니다. 하지만 온톨로지는 목록이 아니라 그래프가 어떻게 배열될 수 있는지를 설명하는 논리적 제약 조건의 집합입니다. 이를 통해 임의의 복잡한 논리 표현을 사용하여 클래스를 정의하고, 명시적으로 언급되지 않았더라도 이미 알고 있는 것으로부터 새로운 관계를 유추할 수 있습니다. OWL은 자동화된 추론 도구로써 이러한 유추를 이끌어내는 데 사용되도록 설계되었습니다. 그래프는 관계를 정의하는 방식에 유연하고, 경로를 탐색할 때 유추된 관계로부터 이점을 얻을 수 있기 때문에 온톨로지는 그래프 모델링에 이상적입니다.

아래의 예제 온톨로지는 W3C 조직 온톨로지입니다. 다음 그림 [1]에서 보여주듯이, 조직은 하위 조직과 조직 단위를 가지고, 조직간의 협력에 참여하며, 여러 사업장에 위치하고, 변경 이벤트의 대상이 되며, 구성원, 직책, 역할을 가집니다. 또한 구성원들은 다른 구성원들에게 보고합니다. 온톨로지는 이러한 관계의 일반적인 구조를 OWL 언어로 설명합니다. 이 게시물을 통해 해당 표현의 일부분들을 심도 있게 연구해 보겠습니다.

먼저, 조직 온톨로지와 그 실례로 가상 회사인 Mega Group의 조직 그래프를 Neptune 데이터베이스에 로드합니다. OWL 온톨로지는 RDF로 표현되므로 그대로 로드할 수 있습니다. 여기서 중요한 점은, SPARQL로 온톨로지를 조회하여 클래스와 해당 속성들을 주관적 방식으로 도출할 수 있다는 점입니다.—“주관적” 방식이라고 하는 이유는 OWL이 광범위한 논리적 표현력을 가지고 있지만, 우리는 경계선을 그어 가장 일반적인 패턴만을 찾기 때문입니다. 이렇게 주관적인 모델을 도출한 후, 프로그래밍 방식으로 온톨로지와 Mega Group 예시를 비교하여 차이점을 기록합니다. 또한 클래스를 인스턴스화하고 인스턴스에 속성을 적용하는 상용구 RDF 모델을 생성하여 새 사례를 만들기 위한 템플릿을 만듭니다.

이 게시물에 동반되는 코드는 GitHub에서 오픈 소스 저장소로 제공됩니다.

솔루션 개요

다음 단계를 통해 솔루션을 구현합니다:

  1. Neptune 및 Neptune Workbench 노트북을 포함한 AWS 리소스를 설정합니다.
  2. Neptune 데이터베이스에 온톨로지(조직 온톨로지와 추가 엣지 케이스 온톨로지)와 샘플 데이터를 로드합니다.
  3. SPARQL을 사용하여 온톨로지와 샘플 데이터를 탐색합니다.
  4. 온톨로지에서 기존 인스턴스 데이터를 검증하고 새 인스턴스 데이터를 생성할 수 있는 모델을 구축합니다.
  5. 모델을 사용하여 Turtle 형식으로 표현된 새로운 인스턴스들을 생성합니다. Turtle은 Neptune에서 지원하는 표준 RDF 직렬화 형식입니다.
  6. 모델을 사용하여 기존 샘플 인스턴스를 검증합니다.
  7. AWS 리소스를 정리합니다.

이제 솔루션을 단계 별로 살펴보면서, AWS 계정에 테스트 환경을 만든 다음 노트북을 따라가며 온톨로지를 로드, 검사 및 사용해 보겠습니다.

사전 요구 사항

이 예제를 실행하려면 Neptune 클러스터와 같은 리소스를 생성할 수 있는 권한이 있는 AWS 계정이 필요합니다.

리소스 생성

AWS 계정에서 이 포스트를 따라하려면 Neptune 데이터베이스, 온톨로지 모델 탐색 기능이 포함된 Neptune 노트북 및 기타 리소스가 필요합니다. 아래의 설정 지침 섹션을 참조하여 이러한 리소스를 설정하세요. 설정을 완료하면 브라우저에서 Neptune 노트북을 엽니다. 남은 단계에서는 노트북을 사용합니다.

설정 지침

이러한 리소스를 계정에 생성하기 위한 AWS CloudFormation 템플릿을 공유합니다. CloudFormation을 사용하여 이러한 리소스를 프로비저닝하려면, 먼저 CloudFormation 템플릿의 사본을 다운로드하세요. 그런 다음 다음 단계를 완료하세요:

  1. AWS CloudFormation 콘솔에서 스택 생성을 선택합니다.
  2. 새 리소스 사용(표준)을 선택합니다.
  3. 템플릿 파일 업로드를 선택합니다.
  4. 파일 선택을 선택하여 다운로드한 템플릿의 로컬 사본을 업로드합니다. 파일 이름은 neptune-ontology-main.yml입니다.
  5. 다음을 선택합니다.
  6. 원하는 스택 이름을 입력합니다.
  7. 다음을 선택합니다.
  8. 나머지 섹션을 계속 진행합니다.
  9. 기능 섹션에서 체크박스를 읽고 선택합니다.
  10. 전송을 선택합니다.
  11. 스택 생성이 완료되면(약 15분 소요), 스택의 출력 탭에서 NeptuneSageMakerNotebook과 S3Bucket 값을 찾습니다.
  12. 브라우저에서 NeptuneSageMakerNotebook에 제공된 URL로 이동합니다.다음 스크린샷과 같이 Jupyter 노트북 인스턴스에 접속하게 됩니다.
  13. 이 게시물에 사용된 코드가 포함된 노트북을 열려면 Neptune_Ontology_Example.ipynb를 선택합니다.다음 그림은 이 CloudFormation 스택에서 생성된 리소스를 보여줍니다.

CloudFormation 스택은 Neptune 기본 인스턴스와 선택적으로 읽기 복제본 역할과 기본 인스턴스 장애 시 장애 조치 대상 역할을 모두 수행하는 복제본 인스턴스를 설치합니다. 이들은 Neptune 클러스터를 형성하며, 애플리케이션이 클러스터에 액세스하는 데 사용하는 DNS 엔드포인트를 제공합니다. 이 게시물에서 해당 애플리케이션은 Neptune_Ontology_Example 노트북으로, 온톨로지 및 인스턴스 데이터를 엔드포인트를 통하여 Neptune 인스턴스에 로드한 다음 쿼리합니다. 사용자인 조직 그래프 SME는 브라우저를 통해 해당 노트북에 접근하여 조직 온톨로지와 그래프를 분석합니다. 이 블로그에서 여러분이 해당 역할을 수행했습니다.

Neptune 인스턴스와 노트북은 Amazon Virtual Private Cloud(Amazon VPC)를 사용하여 구축한 가상 프라이빗 클라우드(VPC)의 프라이빗 서브넷에 위치합니다. VPC는 해당 리전의 두 가용 영역에 걸쳐 있습니다.

이 스택은 또한 Amazon Simple Storage Service(Amazon S3)를 사용하여 온톨로지와 샘플 데이터가 포함된 버킷을 생성합니다. 우리는 노트북을 사용하여 이 데이터를 Neptune 인스턴스에 로드합니다. 스택은 Neptune이 AWS 네트워크를 통해 Amazon S3에 연결하여 로드할 데이터를 수집할 수 있도록 VPC 엔드포인트를 생성합니다.

온톨로지 및 RDF 샘플 데이터 로드

다음으로, 소스 데이터를 Neptune 데이터베이스에 로드합니다. 소스 데이터는 리소스 프로비저닝의 일부로 생성한 S3 버킷에 있습니다. 버킷에는 Turtle 표현 형식의 세 가지 RDF 객체가 포함되어 있습니다:

  • org.ttl – W3C 조직 온톨로지. 리소스 프로비저닝 중에 W3C 웹사이트에서 버킷으로 다운로드됩니다. 자세한 내용은 W3C 문서를 참조하세요.
  • example_org.ttl – 예제 조직 및 그 구성원.
  • tester_ontology.ttl – 일반적인 OWL 모델링 패턴을 다루는 온톨로지와 예제 인스턴스.

Neptune 데이터베이스에 이를 로드하려면 다음 단계를 완료하세요:

  1. 노트북에서 Loading the Ontology and Examples into Neptune 제목으로 이동합니다.이 섹션에는 실행할 세 가지 로드 매직 명령어가 포함되어 있습니다. 각각은 자체 셀에 있으며 %load 텍스트로 시작합니다. 예를 들어, 조직 온톨로지를 로드하는 매직 명령어는 다음과 같습니다:
    %load -s s3://neptuneforblog-s3workingbucket-1mk8x5dqln2j5/org.ttl -f turtle

    여기서 neptuneforblog-s3workingbucket-1mk8x5dqln2j5는 저희 환경에 생성된 S3 버킷을 가리킵니다. 여러분의 것은 다를 수 있습니다. 리소스를 프로비저닝할 때 생성한 버킷 이름과 정확히 일치해야 합니다. 일치하지 않는 경우 수동으로 편집하시기 바랍니다.

  2. 첫 번째 셀을 실행합니다.로드 세부 정보를 확인하는 양식이 표시됩니다. 양식 필드의 값은 미리 채워져 있으며 편집할 필요가 없습니다.
  3. Submit을 선택합니다.
  4. 다른 두 매직 명령어에 대해서도 반복합니다
     

    %load -s s3://<YOUR BUCKET>/example_org.ttl -f turtle
    %load -s s3://<YOUR BUCKET>/tester_ontology.ttl -f turtle
  5. 각 명령을 실행한 후, 셀의 출력에 Load Completed 메시지가 표시되는지 확인하세요.

온톨로지 및 샘플 데이터 쿼리하기

이제 Neptune 데이터베이스에 온톨로지와 샘플 데이터가 로드되었습니다. 이 데이터의 구조를 이해하기 위해 쿼리를 실행해 보겠습니다.

  1. 노트북에서 Querying Org Ontology 제목으로 이동하세요.첫 번째 쿼리는 %%sparql 매직 명령어를 사용하여 OWL 클래스 목록(rdf:typeowl:Class인 주체)을 가져옵니다. 각 클래스에 대해 동등한 클래스들(owl:equivalentClass), 하위 클래스인 클래스들(rdfs:subClassOf), 그리고 키들(owl:hasKeyrdf:firstrdf:rest 로 구성된 연결 리스트 형태로)을 찾습니다. 다음 코드를 참조하세요:
    %%sparql
    
    # You will notice some of the classes or related classes are blank nodes. 
    # We need to drill down and see that they include.
    # Not here, though.
    
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    
    select ?class 
        (GROUP_CONCAT(distinct ?subOf;SEPARATOR=",") AS ?subsOf)
        (GROUP_CONCAT(distinct ?equiv;SEPARATOR=",") AS ?equivs)
        (GROUP_CONCAT(distinct ?key;SEPARATOR=",") AS ?keys) where { 
    
        ?class rdf:type owl:Class .
        OPTIONAL { ?class rdfs:subClassOf ?subOf . } .
        OPTIONAL { ?class owl:equivalentClass ?equiv . } .
        OPTIONAL { ?class owl:hasKey ?keylist . 
                   ?keylist rdf:rest*/rdf:first ?key . } .
    } group by ?class
    order by ?class
  2. 첫 번째 쿼리가 포함된 셀을 실행합니다.결과는 표 형식으로 표시됩니다. 다음 스크린샷은 발췌본을 보여줍니다.

    쿼리에서 반환된 클래스는 다음 세 가지 범주로 나뉩니다:

    • 접두사 http://www.w3.org/ns/org# 를 가진 조직 클래스. 여기에는 ChangeEvent, FormalOrganization, Membership, Organization, OrganizationalCollaboration, OrganizationalUnit, Post, Role, Site가 포함됩니다.
    • Example 클래스들로, http://amazonaws.com/db/neptune/examples/ontology/tester# 접두사를 가집니다. 이 중에는 Father, Mother, Grandpa가 있습니다. 이 포스트의 후반부에서 이러한 클래스들을 사용하여 모델을 테스트하겠습니다.
    • b로 시작하는 빈 노드(Blank nodes)들도 있습니다. 이러한 클래스들의 목적을 이해하기 위해서는 더 깊이 살펴봐야 합니다. 다음 섹션에서 모델을 구축할 때, 이러한 클래스들의 역할이 명확해질 것입니다.

    다음 쿼리는 클래스의 속성들을 찾습니다. 더 정확히 말하면, 클래스가 속성의 도메인(rdfs:domain)인 클래스들을 찾습니다:

    %%sparql  
    
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    
    select ?class ?prop ?range 
    (GROUP_CONCAT(distinct ?propType;SEPARATOR=",") AS ?propTypes)  where { 
        ?class rdf:type owl:Class .
        ?prop rdfs:domain ?class .
        ?prop rdf:type ?propType .
        OPTIONAL {?prop rdfs:range ?range } .
    } 
    group by ?class ?prop ?range
    order by ?class ?prop
  3. 앞의 쿼리를 실행하세요.결과 중에서, Organization의 속성에는 org:hasSite, org:hasSubOrganization, org:hasMember가 포함되어 있음을 확인할 수 있습니다. FormalOrganizationorg:hasRegisteredSiteorg:hasUnit 속성을 가지고 있습니다.

  4. 계속해서 Querying Example Data 제목으로 이동하면, Mega Group이라는 가상 조직을 발견할 수 있습니다.이 섹션에는 여섯 개의 쿼리가 포함되어 있습니다. 이 쿼리들은 데이터를 찾기 위해 조직 온톨로지(ontology)의 구조를 가정하고 있습니다.

    예를 들어, 첫 번째 쿼리는 rdf:typeorg:Organization인 주체를 검색하여 조직을 찾습니다. 각 조직에 대해, org:hasSubOrganization, org:hasUnit, org:hasSite 속성을 확인하여 하위 조직, 단위 및 사이트를 찾습니다. 이 쿼리는 온톨로지에 대한 우리의 이해를 바탕으로 합니다: org:Organization이 클래스이고 org:hasSubOrganization, org:hasUnit, org:hasSite 속성들이 org:Organization을 도메인으로 가진다는 것을 확인했습니다. (이것은 완전히 정확하지는 않습니다! 이후 섹션에서 이를 검증하고 어디서 오류가 발생했는지 확인할 것입니다.)

    %%sparql
    
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
    PREFIX org: <http://www.w3.org/ns/org#> 
    
    select ?orgName ?subName ?unitName ?siteName where {
        ?org rdf:type org:Organization .
        ?org rdfs:label ?orgName .
        OPTIONAL { ?org org:hasSubOrganization/rdfs:label ?subName } .
        OPTIONAL { ?org org:hasUnit/rdfs:label ?unitName . } .
        OPTIONAL { ?org org:hasSite/rdfs:label ?siteName . }
    } order by ?orgName
  5. 앞의 쿼리를 실행하세요.Mega Group에는 두 개의 하위 조직이 있음을 확인할 수 있습니다: MegaSystemsMegaFinancial입니다. MegaSystems에는 SalesR&D의 두 개의 부서가 있습니다.


    다른 쿼리는 org:memberOforg:reportsTo 관계를 사용하여 MegaFinancial의 보고 구조를 검토합니다:

    %%sparql
    
    PREFIX org: <http://www.w3.org/ns/org#> 
    PREFIX ex: <http://amazonaws.com/db/neptune/examples/ontology/org/> 
    
    select ?personName ?boss (GROUP_CONCAT(?superiorName;SEPARATOR=",") AS ?superiors) where {
        ?person org:memberOf ex:Org-MegaFinancial .
        ?person rdfs:label ?personName .
        OPTIONAL {
            ?person org:reportsTo/rdfs:label ?boss .
            ?person org:reportsTo+ ?superior .
            ?superior rdfs:label ?superiorName .
        } .
    } group by ?personName ?boss
  6. 앞의 쿼리를 실행하세요.결과 중에서 Bonnibelle Valenta는 상사로 Andromache Laborda를 두고 있으며, 그녀의 전체 상급자 라인은 Ilyssa Sylett, Andromache Laborda임을 확인할 수 있습니다.

모델 구축하기

다음으로, 온톨로지를 쿼리하여 클래스와 해당 속성에 대한 주관적인 모델을 생성합니다. 이 모델의 목표는 두 가지입니다:

  • 인스턴스 검증 – 인스턴스가 온톨로지에서 기대하는 속성을 가지고 있는지 확인합니다. 속성의 제약 조건(범위, 다중성, 제한)을 준수하는지 확인합니다.
  • 인스턴스 생성 – 클래스의 인스턴스를 생성하고 속성을 사용하여 다른 인스턴스와의 관계를 설정하는 Turtle 형식의 RDF를 생성합니다.

이후 단계에서 검증 및 생성에 대해 살펴보겠습니다. 이 단계에서는 Build the Model 제목 아래의 Python 코드를 실행하여 모델을 구축합니다. 주요 함수는 build_model로, SPARQL 쿼리를 실행하여 클래스, 속성 및 제한 사항에 대한 충분한 세부 정보를 수집한 다음 쿼리 결과를 클래스 및 관련 속성 목록으로 결합합니다.

논리적으로 알고리즘은 다음과 같이 작동합니다. (이것을 노트북에 구현된 코드와 비교해 보세요. 이 코드는 Neptune 매직 명령어를 사용하여 쿼리를 실행하고 일반 Python으로 결과를 해석합니다. 여기서는 사용되지 않았지만 RDF 처리를 위한 또 다른 유용한 Python 라이브러리는 RDFLib입니다.)

  • SPARQL을 사용하여 rdfs:subClassOf, owl:equivalentClass, owl:hasKey, owl:intersectionOf와 같은 술어를 사용하여 모든 클래스(owl:Class)를 수집합니다.
  • SPARQL을 사용하여 rdfs:subPropertyOf, rdfs:domain, rdfs:range와 같은 술어를 사용하여 모든 속성(owl:ObjectProperty, owl:DatatypeProperty 또는 rdf:Property)을 수집합니다.
  • SPARQL을 사용하여 owl:onProperty, owl:hasValue, owl;allValuesFrom, owl:someValuesFrom과 같은 술어를 사용하는 모든 제약 조건(owl:Restriction)을 수집합니다.
  • 그런 다음 각 클래스를 살펴보며 속성을 찾습니다. 각 클래스 C에 대해:
    • 도메인이 C 또는 C를 포함하는 클래스들의 합집합인 속성 P가 있다면 P를 C의 속성으로 간주합니다.
    • 만약 P가 다른 속성 P1의 하위 속성이라면, P1을 C의 속성으로 간주합니다. (이 섹션에서 보여드리는 것처럼, 조직 단위를 갖는 것은 하위 조직을 갖는 것의 하위 속성입니다. 따라서, 조직 단위 속성을 가진 클래스는 하위 조직 속성도 가져야 합니다.)
    • 만약 C가 클래스 C1의 하위 클래스라면, C가 C1의 모든 속성을 가지고 있다고 간주합니다. 이는 모든 상위 클래스에도 적용됩니다. C가 C1의 하위 클래스이고 C1이 C2의 하위 클래스라면, C는 C1과 C2의 속성을 가지고 있다고 간주합니다.
    • 만약 C가 클래스 C1, C2, C3, … 의 교집합이라면, C는 C1, C2, C3, …의 속성을 가지고 있다고 간주합니다. (직관적으로, 만약 MotherPersonParent의 교집합이라면, 다음 표에서 논의하는 것처럼 MotherPersonParent 모두의 속성을 가질 수 있습니다. 이 규칙은 합집합에는 적용되지 않습니다. 만약 PersonManWoman의 합집합이라면, 한 사람이 ManWoman 모두의 속성을 가지지는 않습니다.)
    • 만약 C가 속성 P에 대한 제한과 동등하거나 그 하위 클래스라면, C는 속성 P를 가지고 있다고 간주합니다.

코드 셀을 실행하면 모델의 요약 정보를 볼 수 있습니다. 다음은 발췌한 내용입니다:

Class http://www.w3.org/ns/org#Organization
	keys ['http://www.w3.org/ns/org#identifier']
	Prop http://www.w3.org/ns/prov#wasGeneratedBy
	Prop http://www.w3.org/ns/org#hasSite
		type ObjectProperty
		functional False
		inverses ['http://www.w3.org/ns/org#siteOf']
		range ['http://www.w3.org/ns/org#Site']
		rangeUnionOf []
	Prop http://www.w3.org/ns/org#hasSubOrganization
		type ObjectProperty
		functional False
		inverses ['http://www.w3.org/ns/org#subOrganizationOf']
		range ['http://www.w3.org/ns/org#Organization']
		rangeUnionOf []
	Prop http://www.w3.org/2004/02/skos/core#notation
	Prop http://www.w3.org/ns/org#identifier
		type DatatypeProperty
		functional False
		inverses []
		range []
		rangeUnionOf []

우리의 모델은 주관적입니다. 온톨로지의 관례적인 모델링 패턴 사용을 기반으로 속성을 클래스와 연결합니다. 우리의 알고리즘이 바로 이런 부분을 찾아 냅니다. OWL은 표현력이 풍부하며, OWL 온톨로지에서 클래스와 속성을 정의하는 방법은 우리 알고리즘이 살펴보지 않는 것도 수없이 많습니다. 그럼에도 불구하고 알고리즘은 단지 코드일 뿐이며, 충분히 변경 가능합니다. 조정하는 것은 노트북 셀의 코드를 수정하는 것만큼 간단합니다. (또한 앞서 언급했듯이, 이 게시물과 함께 제공되는 전체 소스 코드는 오픈 소스 GitHub 저장소 이용할 수 있습니다.)

이제부터 아래에서 각 패턴에 대해 논의해 보겠습니다. 다음 섹션에서는 각 패턴의 이름을 지정하고, 조직 또는 테스트 온톨로지에서의 사용 예시를 제공하며, 인스턴스가 해당 패턴을 어떻게 사용하는지 보여줍니다. 인스턴스 예시들이 특이하게 생성된 것처럼 보일 수 있습니다. 해당 부분들은 우리 모델에 의해 생성된 것입니다! 다음 섹션에서 생성에 대해 살펴보겠습니다.

Mother 예제는 OWL Primer에서 가져왔습니다. RedWine, RedThing, RealArtist 예제는 OWL Restrictions에서 가져왔습니다.

패턴 1: 키(Key)

온톨로지 예제:

org:Organization a owl:Class;
    owl:hasKey (org:identifier) ;

인스턴스 예제:

ex:Organization-sample-1 <http://www.w3.org/ns/org#identifier> "sample value" . 

패턴 2: 서브클래스(Subclass)

온톨로지 예제:

org:FormalOrganization a owl:Class;
    rdfs:subClassOf  org:Organization, foaf:Organization

인스턴스 예제:

ex:FormalOrganization-sample-23 <http://www.w3.org/ns/org#hasRegisteredSite> ex:Site-sample-24 .

ex:Site-sample-24 rdf:type <http://www.w3.org/ns/org#Site>  .

FormalOrganization 인스턴스가 org:hasSite 속성을 가지고 있으며, 이 속성의 도메인은 Organization입니다. 그러나 FormalOrganizationOrganization의 서브클래스입니다. 이로 인해 나중 섹션에서 볼 수 있듯이 유효성 검사 중에 발견 사항이 생깁니다.

패턴 3: 도메인이 클래스인 객체 속성(Object Property)

온톨로지 예제:

org:hasUnit a owl:ObjectProperty, rdf:Property;
    rdfs:domain org:FormalOrganization;
    rdfs:range  org:OrganizationalUnit;

인스턴스 예제:

ex:FormalOrganization-sample-23 <http://www.w3.org/ns/org#hasUnit> ex:OrganizationalUnit-sample-35 .

ex:OrganizationalUnit-sample-35 rdf:type <http://www.w3.org/ns/org#OrganizationalUnit>  .

패턴 4: 도메인이 클래스인 데이터 타입 속성

온톨로지 예제:

org:identifier a owl:DatatypeProperty, rdf:Property;
    rdfs:domain org:Organization;
    rdfs:subPropertyOf skos:notation;

인스턴스 예제:

ex:Organization-sample-1 <http://www.w3.org/ns/org#identifier> "sample value" .

패턴 5: 도메인이 클래스인 일반 속성

온톨로지 예제:

org:purpose a rdf:Property;
    rdfs:domain org:Organization;

인스턴스 예제:

ex:OrganizationalUnit-sample-37 <http://www.w3.org/ns/org#purpose> "sample value" .

패턴 6: 도메인이 합집합(Union)인 속성

온톨로지 예제:

org:reportsTo a owl:ObjectProperty, rdf:Property;
    rdfs:domain [a owl:Class; owl:unionOf (foaf:Agent org:Post)];
    rdfs:range  [a owl:Class; owl:unionOf (foaf:Agent org:Post)];

인스턴스 예제:

ex:Post-sample-50 <http://www.w3.org/ns/org#reportsTo> ex:Post-sample-52 .

ex:Post-sample-52 rdf:type <http://www.w3.org/ns/org#Post>  .

Post 인스턴스가 org:reportsTo 속성을 가지고 있음을 주목하세요. Post는 org:reportsTo의 도메인 합집합에 포함됩니다.

패턴 7: 하위 속성

온톨로지 예제:

org:hasUnit a owl:ObjectProperty, rdf:Property;
    rdfs:subPropertyOf org:hasSubOrganization

인스턴스 예제:

ex:FormalOrganization-sample-23 <http://www.w3.org/ns/org#hasUnit> ex:OrganizationalUnit-sample-35 .

ex:OrganizationalUnit-sample-35 rdf:type <http://www.w3.org/ns/org#OrganizationalUnit>  

패턴 8: 기능적 속성(Functional property)

온톨로지 예제:

org:member a owl:ObjectProperty, rdf:Property, owl:FunctionalProperty;
    rdfs:domain org:Membership;
    rdfs:range  foaf:Agent;

인스턴스 예제:

# Add prop in domain - This is functional: only one 
ex:Membership-sample-15 <http://www.w3.org/ns/org#member> ex:Agent-sample-16 .

ex:Agent-sample-16 rdf:type <http://xmlns.com/foaf/0.1/Agent>  .

패턴 9: 클래스 교집합으로서의 클래스

온톨로지 예제:

tst:Mother a owl:Class ;
    owl:equivalentClass
        [ 
            a owl:Class;
            owl:intersectionOf (
                tst:Woman
                tst:Parent
            )
        ]

인스턴스 예제:

ex:Mother-sample-77 rdf:type <http://amazonaws.com/db/neptune/examples/ontology/tester#Mother> .

ex:Mother-sample-77 <http://amazonaws.com/db/neptune/examples/ontology/tester#womanliness> "sample value" .

ex:Mother-sample-77 <http://amazonaws.com/db/neptune/examples/ontology/tester#thatParentalQuality> "sample value" .

ex:Mother-sample-77 <http://amazonaws.com/db/neptune/examples/ontology/tester#motherliness> "sample value" .

Mother가 두 교차 클래스의 속성을 모두 가져오는 방식을 확인하세요: Woman에서 womanliness, Parent에서 thatParentQuality를 가져옵니다.

패턴 10: 서브클래스 제약 조건(값에 대한 제약 조건도 포함)

온톨로지 예제:

tst:RedWine
  a owl:Class ;
  rdfs:subClassOf
    [ a owl:Restriction ;
      owl:onProperty tst:color ;
      owl:hasValue "red"
    ]

인스턴스 예제:

ex:RedWine-sample-79 <http://amazonaws.com/db/neptune/examples/ontology/tester#color> "red" .

패턴 11: 동등 제약 조건

온톨로지 예제:

tst:RedThing
  a owl:Class ;
  owl:equivalentClass
    [ a owl:Restriction ;
      owl:onProperty tst:color ;
      owl:hasValue "red"
    ]

인스턴스 예제:

ex:RedThing-sample-80 <http://amazonaws.com/db/neptune/examples/ontology/tester#color> "red" .

패턴12: 제약 조건(일부 값)

온톨로지 예제:

tst:RealArtist
  a owl:Class ;
  owl:equivalentClass
  [ a owl:Class ;
    owl:intersectionOf 
      ( tst:Person 
        [ a owl:Restriction ;
          owl:onProperty tst:creatorOf ;
          owl:someValuesFrom tst:ArtObject
        ])
  ] .

인스턴스 예제:

# Add a restriction - restricted: some values from
ex:Artist-sample-81 <http://amazonaws.com/db/neptune/examples/ontology/tester#creatorOf> <ArtObject-sample-82> .

<ArtObject-sample-82> rdf:type <http://amazonaws.com/db/neptune/examples/ontology/tester#ArtObject> .

패턴13: 제한(모든 값)

온톨로지 예제:

tst:Vegetarian 
    a owl:Class; 
    owl:equivalentClass  
      [
        a owl:Restriction ;
            owl:onProperty tst:eats ;
            owl:allValuesFrom tst:NonMeat
      ] 

인스턴스 예제:

# Add a restriction - restricted: all values from
ex:Vegetarian-sample-85 <http://amazonaws.com/db/neptune/examples/ontology/tester#eats> <NonMeat-sample-86> .

<NonMeat-sample-86> rdf:type <http://amazonaws.com/db/neptune/examples/ontology/tester#NonMeat> .

모델에서 인스턴스 생성하기

노트북에서 Generation 제목으로 이동하세요. 코드 셀에는 온톨로지의 클래스들의 인스턴스들을 포함하는 Turtle 표기법의 RDF를 출력하는 Python 코드가 있습니다. 이 코드는 간단합니다. 각 클래스를 반복하면서 인스턴스화하고 각 속성에 값을 부여합니다.

코드를 실행하세요. 다음은 출력의 일부입니다:

@base <http://amazonaws.com/db/neptune/examples/ontology/gensample/>  .
@prefix ex: <http://amazonaws.com/db/neptune/examples/ontology/gensample/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .


#
# Sample for class http://www.w3.org/ns/org#Organization
# 

# Instantiate
ex:Organization-sample-1 rdf:type <http://www.w3.org/ns/org#Organization> .
    
# Add key - Multiple values allowed
ex:Organization-sample-1 <http://www.w3.org/ns/org#identifier> "sample value" .
# actual ranges []
                    
# Add prop in domain - Multiple values allowed
ex:Organization-sample-1 <http://www.w3.org/ns/org#resultedFrom> ex:ChangeEvent-sample-2 .
ex:ChangeEvent-sample-2 rdf:type <http://www.w3.org/ns/org#ChangeEvent>  .
# ... and fill in the details of ex:ChangeEvent-sample-2 
# all ranges ['http://www.w3.org/ns/org#ChangeEvent']

앞 섹션에서는 우리의 주관적 모델이 사용하는 온톨로지 패턴에 대해 논의했습니다. 그 논의에서 패턴을 따를 때 인스턴스 코드가 어떻게 보이는지에 대한 예시를 제공했습니다. 이러한 예시들은 방금 실행한 생성된 인스턴스에서 가져온 것입니다! 이 단계에서 보는 출력과 그러한 예시들을 비교해보세요.

모델 검증하기

마지막 단계로, 노트북에서 Validation 제목으로 이동하세요. validate_instances 함수는 SPARQL 쿼리를 실행하여 인스턴스를 가져옵니다. 그런 다음 인스턴스를 모델과 비교하고, 여러 검증 규칙을 적용한 후 결과를 보고합니다. 해당 코드가 포함된 셀을 실행하세요.

출력을 이해하기 위해 주요 규칙, 발견 사항 및 위반 사례를 자세히 살펴보겠습니다. 우리는 규칙 위반을 오류가 아닌 발견 사항으로 보고합니다. 발견 사항이 반드시 문제가 되는 것은 아닙니다. 단지 인스턴스가 클래스와 다른 경우를 강조하여 인스턴스에 실수가 있는지 확인하고자 합니다.

규칙1: 누락된 키

온톨로지에서 클래스에 키가 있습니다. 그러나 인스턴스에 해당 키가 없거나, 인스턴스에 키에 대한 여러 값이 있습니다.

발견 사항:

Finding in class: http://www.w3.org/ns/org#Organization 
Instance: http://amazonaws.com/db/neptune/examples/ontology/org/Org-MegaSystems.
Prop assignment: None
Finding: Key property http://www.w3.org/ns/org#identifier appears 0 times. Should be once.

예시:

ex:Org-MegaSystems
   rdf:type org:Organization ;
   rdfs:label "MegaSystems" ;

어디에도 ex:Org-MegaSystems에 대한 org:identifier를 제공하지 않았습니다.

규칙2: 인식되지 않는 속성

인스턴스에 모델에 없는 속성이 있습니다.

발견 사항:

Finding in class: http://www.w3.org/ns/org#Organization 
Instance: http://amazonaws.com/db/neptune/examples/ontology/org/Org-MegaSystems.
Prop assignment: {'prop': 'http://www.w3.org/ns/org#hasUnit', 'object': 'http://amazonaws.com/db/neptune/examples/ontology/org/Org-MegaSystems-Sales', 'objectType': 'http://www.w3.org/ns/org#OrganizationalUnit', 'literal': False}
Finding: Unrecognized prop

예시:

ex:Org-MegaSystems
   rdf:type org:Organization ;
   rdfs:label "MegaSystems" ;
   org:subOrganizationOf ex:Org-MegaGroup ;
   # validation - hasUnit for formalorg only
   org:hasUnit ex:Org-MegaSystems-RD;
   org:hasUnit ex:Org-MegaSystems-Sales;

앞서 논의했듯이, hasUnitOrganization이 아닌 FormalOrganization의 속성입니다. 이것이 발견된 문제의 이유입니다.

규칙3: 속성의 리터럴/객체 불일치

인스턴스에서 속성의 값은 리터럴이지만, 온톨로지에서는 해당 속성이 객체 속성입니다. 또는 그 반대로: 인스턴스의 값은 객체이지만, 온톨로지에서는 해당 속성이 데이터 타입 속성입니다.

발견 사항:

Finding in class: http://www.w3.org/ns/org#ChangeEvent 
Instance: http://amazonaws.com/db/neptune/examples/ontology/org/Org-AnInvalidEvent.
Prop assignment: {'prop': 'http://www.w3.org/ns/org#originalOrganization', 'object': 'an org of some sort', 'objectType': '', 'literal': True}
Finding: Prop type is ObjectProperty but object is literal

예시:

ex:Org-AnInvalidEvent
   rdf:type org:ChangeEvent;
   # validation - literal but object expected
   org:originalOrganization "an org of some sort";

규칙4: 예상치 못한 속성 타입

인스턴스 속성의 값이 타입 S이지만, S는 온톨로지에서 정의된 속성의 범위에 포함되지 않습니다.

발견 사항:

Finding in class: http://www.w3.org/ns/org#Site 
Instance: http://amazonaws.com/db/neptune/examples/ontology/org/Site-Pembroke.
Prop assignment: {'prop': 'http://www.w3.org/ns/org#siteOf', 'object': 'http://amazonaws.com/db/neptune/examples/ontology/org/AnnualFiddleWeek', 'objectType': 'http://amazonaws.com/db/neptune/examples/ontology/org/SmallTownEvent', 'literal': False}
Finding: Prop ranges are ['http://www.w3.org/ns/org#Organization'] but object type is not among these

예시:

ex:Site-Pembroke
   rdf:type org:Site;
   org:siteOf ex:AnnualFiddleWeek;
.
ex:AnnualFiddleWeek rdf:type ex:SmallTownEvent .

우리의 검증 규칙은 범위(range)를 org:siteOf의 값에 대한 제약 조건으로 간주합니다. 이는 엄격한 검증 모델에서는 적절합니다. 실제로 범위는 제한적이지 않고 생성적입니다. 인스턴스가 어떤 속성을 가지면, 추론기는 해당 지정된 범위를 가지는 속성 타입을 추론할 수 있습니다.

규칙5: 기능적 속성의 다중 값

인스턴스가 하나의 속성에 대해 여러 값을 제공하지만, 온톨로지에서는 해당 속성이 기능적(functional)입니다.

발견 사항:

Finding in class: http://www.w3.org/ns/org#Membership 
Instance: http://amazonaws.com/db/neptune/examples/ontology/org/Membership-Tech-President.
Prop assignment: None
Finding: Functional property http://www.w3.org/ns/org#member appears 2 times. Should be once.

ra

예시:

ex:Membership-Tech-President
   rdf:type org:Membership;
   org:member ex:Person-Michel-Urban;
   # validation issue - second member
   org:member ex:Person-ImposterOf-Michel-Urban;

규칙6: 제한에 대한 예상치 못한 값

인스턴스에 제한된 속성이 있지만, 해당 속성의 값이 온톨로지의 제한 사항에 있는 hasValue의 값과 일치하지 않습니다.

발견 사항:

Finding in class: http://amazonaws.com/db/neptune/examples/ontology/tester#RedThing 
Instance: http://amazonaws.com/db/neptune/examples/ontology/tester#PhonyRedThing.
Prop assignment: {'prop': 'http://amazonaws.com/db/neptune/examples/ontology/tester#color', 'object': 'blue', 'objectType': '', 'literal': True}
Finding: Restriction requires literal value ['red'] but obj not among these

예시:

tst:PhonyRedThing 
    a tst:RedThing;
    tst:color "blue"

규칙7: 제한 값이 owl:allValuesFrom에 위배됨

인스턴스에 S 유형의 값을 가진 제한된 속성이 있습니다. 온톨로지에서 제한된 속성은 owl:allValuesFrom = T를 지정합니다.

발견 사항:

Finding in class: http://amazonaws.com/db/neptune/examples/ontology/tester#Vegetarian 
Instance: http://amazonaws.com/db/neptune/examples/ontology/tester#TheVegNot.
Prop assignment: {'prop': 'http://amazonaws.com/db/neptune/examples/ontology/tester#eats', 'object': 'http://amazonaws.com/db/neptune/examples/ontology/tester#bacon', 'objectType': '', 'literal': False}
Finding: Restriction requires all values from ['http://amazonaws.com/db/neptune/examples/ontology/tester#NonMeat'] but obj type is not among these

예시:

tst:TheVegNot 
    a tst:Vegetarian;
    tst:eats tst:bacon;

규칙8: owl:someValuesFrom이 있는 제한에 값 누락

온톨로지에서 클래스는 속성이 owl:someValuesFrom 클래스를 가지는 제한을 가집니다. 인스턴스는 이에 대한 값을 가지고 있지 않습니다.

발견 사항:

Finding in class: http://amazonaws.com/db/neptune/examples/ontology/tester#Artist 
Instance: http://amazonaws.com/db/neptune/examples/ontology/tester#TheSoonToBeArtist.
Prop assignment: None
Finding: Restriction on property http://amazonaws.com/db/neptune/examples/ontology/tester#creatorOf having some values from http://amazonaws.com/db/neptune/examples/ontology/tester#ArtObject not met.

예시:

tst:TheSoonToBeArtist a tst:Artist.
tst:TheSoonToBeArtist tst:creatorOf tst:pizzaOrder1 . 
tst:TheSoonToBeArtist tst:creatorOf tst:pacingAroundTheRoom1 .
tst:TheSoonToBeArtist tst:creatorOf tst:bingeWatching1 .
tst:pizzaOrder1 a tst:WastefulActivity .
tst:pacingAroundTheRoom1 a tst:WastefulActivity .
tst:bingeWatching1 a tst:WastefulActivity .

문제는 최소한 하나의 tst:creatorOftst:ArtObject여야 한다는 것입니다. 그러나 인스턴스 tst:TheSoonToBeArtist의 모든 tst:creatorOftst:WastefulActivity입니다.

발견사항에 대한 분석

이 예제에서는 ex:Person-ImposterOf-Michel-Urban이 기술 대표 역할의 구성원인 것이 데이터 문제일 가능성이 높습니다. 이 발견은 문제를 밝히는데 도움이 됩니다; 이 경우에는 데이터를 수정해야 합니다. 그러나 ex:AnnualFiddleWeek를 사이트와 연결하는 것과 관련된 문제는 없을 수 있습니다. 사실, 온톨로지는 org:siteOf의 범위가 조직이어야 한다고 예상하고, 우리의 인스턴스 데이터는 ex:AnnualFiddleWeek의 유형을 ex:SmallTownEvent로 제공합니다. 하지만 ex:AnnualFiddleWeek가 실제로 조직이기도 하고, 우리가 인스턴스에서 그것을 명시하는 것을 잊었을 수도 있습니다. OWL에서는 열린 세계 가정(open-world assumption)이 적용됩니다: 우리가 명시하지 않았다고 해서 그것이 거짓이라는 의미는 아닙니다. 실제로, 그것이 조직이라고 추론할 수 있습니다.

정리

Neptune에서 온톨로지 실험을 마치고 향후 요금이 발생하지 않도록 하려면 Neptune 데이터베이스와 노트북을 삭제하세요. 이를 위해 AWS CloudFormation 콘솔로 이동하여 이전에 생성한 스택을 삭제하세요. AWS CloudFormation이 Neptune 및 관련 리소스를 제거합니다.

결론

이 게시물의 목적은 OWL 온톨로지를 사용하여 Neptune에서 RDF 데이터를 검증하고 생성하기 위한 데이터 모델을 도출하는 것입니다. OWL 자체가 RDF로 표현되기 때문에, 잘 알려진 조직 온톨로지를 Neptune 데이터베이스에 로드하고 SPARQL을 사용하여 쿼리함으로써 검증 및 데이터 생성 로직을 구축할 수 있었습니다. 우리는 온톨로지를 RDF로 표현된 샘플 조직 데이터와 비교했습니다. 모든 단계를 진행하기 위해 노트북을 사용했습니다. 우리의 모델은 온톨로지를 검사하여 유효한 지식 그래프를 구성하는 요소를 결정할 때, 단순화를 위해 기존 OWL 모델링 패턴을 가정한다는 점에서 주관적입니다. 만약 여러분의 패턴이 다르다면, 노트북의 코드를 수정하여 모델 도출을 개선하시기 바랍니다.

Amazon Neptune에 대해 더 알아보려면 웹사이트를 방문하거나 댓글로 질문을 남겨주세요.

참고 자료

[1] https://www.w3.org/TR/vocab-org/에서 파생된 이미지. Copyright 2012-2014 W3C (MIT, ERCIM, Keio, Beihang), All Rights Reserved

Joonyong Park

Joonyong Park

박준용 파트너 솔루션스 아키텍트는 파트너 역량강화를 위하여 AWS Ambassador, BlackBelt, APN Immersion Day, JetPack 등의 프로그램을 수행하고 있으며 파트너사에 Data Analytics와 Machine Learning 분야 Enablement를 준비 및 제공하고 있습니다.

Suji Lee

Suji Lee

이수지 솔루션즈 아키텍트는 10여년간의 솔루션 개발과 아키텍트 경험을 바탕으로 디지털 고객을 대상으로 클라우드 도입을 도와주는 역할을 하고 있습니다. 최근 AI/ML 분야에 있어 고객의 서비스를 위한 최적의 아키텍처를 설계하는 데 큰 도움을 주고 있습니다.