앞서 정리하였던 From human experts to machines: An LLM supported approach to ontology and knowledge graph construction의 후속 논문이다. 이전 논문은 v1.0을 기준으로 작성되었고, 해당 논문은 v2.0을 기준이다. 현재 깃헙의 코드 역시 v2.0 기준으로 정리되어 있다.
목적이나 전체적인 방법론은 이전과 유사하지만, Methods부분에서 일부 수정과 개선을 진행한 것 같다. 이 글은 Methods 파트를 중심으로 차이점에 초점을 두고 정리하며, 깃헙의 코드를 기반으로 실험의 재현가능성을 확인해보려 한다.
깃헙에 사용한 데이터를 공개하고 있다.
방법은 v1.0과 동일하고 대상 논문의 수가 5개에서 30개로 늘어났다.
v1.0에서는 CQ를 생성하는 과정에서 ChatGPT-3.5를 사용한반면, v2.0에서는 두 명의 도메인 전문가가 28개의 질문을 직접 생성했다고 한다.
또한 질문은 다음 7가지 유형(Ontology Requirement Specification Document, ORSD)에 따라 생성했다고 한다. 이 유형 중 6번 Ontology Requirements의 Functional Requirements에서 총 28개의 질문을 생성한 것이다.
✅ ORSD란?
ORSD(Ontology Requirement Specification Document)를 처음 들어봐서 찾아보니, 온톨로지를 구축하기 전에 '온톨로지를 구축하는 이유, 의도된 용도, 최종 사용자가 누구인지, 온톨로지가 충족해야 하는 요구 사항'등을 명시하기 위해 만드는 기본적인 문서 정도인 것 같다. ORS를 어떻게 작성해야 하는지에 관한 설명을 하는 논문들이 몇 개 있는 것 같은데 참고할 수 있을 것 같다
생성한 CQ를 기반으로 온톨로지를 구축하는데, 이때는 Mixtral 8x22B Instruct v0.1, GPT-4o, GPT-3.5, Gemini 이렇게 4개의 모델을 사용한다. 이때 모두 동일한 프롬프트를 사용하여 모델 성능만 비교할 수 있도록 한다.
생성 과정은 v0.1과 동일하게 2-step이다.
각 문서당 1개의 ttl 파일이 생성되므로, 4개의 모델을 통해 생성되는 총 파일 수, 즉 온톨로지는 120개이다.
깃헙의 코드를 살펴보니, mixtral을 사용한 경우의 전체 코드만 있고, 나머지 모델을 프롬프트만 제공하는 것 같다. mixtral 22B 모델을 돌릴만한 리소스를 갖고 있지 않으므로, 모든 코드를 OpenAI API를 사용하는 코드로 바꿔서 테스트 해봤다. 사용한 파일들은 다음과 같다.
helper_functions.py
: 각종 모듈을 정의한 파일Concepts_relations_generate.py
: CQs에서 PROV-O를 참고해서 concept, relatioships, data properties, inverse properties를 뽑는 코드. concept_relation_data_inverse.txt 생성Ontology_creation.py
: 위에서 생성한 파일과 PROV-O를 참고해서 owl파일로 변환하는 코드. orig_datapropsandinver_v1.owl 생성28개의 CQs에 대하여 30개의 논문을 기반으로 RAG를 활용한 답변을 생성하는 과정이다. 이 과정에서 비용적 측면솨 오픈소스인 모델을 사용하기 위해 Mixtral만 사용했다고 한다.
논문만 봤을 때는 28개의 질문에 28개의 답변만 생성하는 줄 알았는데, 각 문서별로 28개의 질문에 답변을 생성하게 하고, 모르겠거나 해당 내용이 없는 경우에는 모르겠다고 답하도록 한다. 아래와 같은 instruction을 줬다.
Use the provided pieces of context to answer the query. If you don't know the answer, just say that you don't know, don't try to make up an answer.
따라서 생성된 답변은 30*28 = 840개가 되어야 한다. (깃헙에 확인해보면, 840개가 아닌것 같은데 누락된 건지 잘 모르겠음)
이후 형식을 맞춰주거나 중복되는 문장들을 삭제하는 약간의 후처리를 진행한다.
사용한 파일들은 다음과 같다.
helper_functions.py
: 각종 모듈을 정의한 파일RAG_CQ_answering_with_LLMs.py
: 답변을 생성하는 파일Process_CQ_ans.py
: 후처리를 진행하는 파일위에서 구축한 CQ와 답변, 온톨로지를 기반으로 최종적으로 KG를 생성한다. 각 문서에 28개의 CQ에 대한 모든 답변이 존재하진 않으므로, 공통적인 답변을 도출할 수 있는 13개의 질문만 선택했다고 한다. 13개의 질문은 데이터 전처리, 모델 아키텍쳐, 학습 절차와 평가지표 등과 같은 DL과 관련된 필수적인 측면을 다룬다.
NER작업은 각 문서별로 13개의 답변에서 중요한 개체들을 추출하는 과정이다. 이때 뽑는 개체는 앞서 추출했던 Concepts 리스트 중에서 카테고리를 선택하고, 해당하는 값을 넣는다. NER.py
코드에서 지시 프롬프트를 보면 알 수 있다.
%INSTRUCTIONS:
Your task is to do Named Entity Recognition. You extract named entities from the provided competency question answers.
Use provided concepts to understand which named entities to extract from competency answers.
Concepts: Method, RawData, DataFormat, DataAnnotationTechnique, DataAugmentationTechnique, Dataset, PreprocessingStep, DataSplitCriteria, CodeRepository, DataRepository, CodeRepositoryLink, DataRepositoryLink, DeepLearningModel, Hyperparameter, HyperparameterOptimization, OptimizationTechnique, TrainingCompletionCriteria, RegularizationMethod, ModelPerformanceMonitoringStrategy, Framework, HardwareResource, PostprocessingStep, PerformanceMetric, GeneralizabilityMeasure, RandomnessStrategy, ModelPurpose, DataBiasTechnique, ModelDeploymentProcess, DeploymentPlatform.
Example: DeepLearningModel(CNN, RNN, Transformer), Framework(TensorFlow, PyTorch), PerformanceMetric(Accuracy, mean IoU)
위 프롬프트를 보면 'Concepts:' 부분에서 카테고리에 해당하는 값들을 주고, 실제 인스턴스는 괄호 안에 표기하도록 하고 있다. 이를 통한 최종 NER 출력값은 다음과 같다. 한 문서당 13개의 카테고리에 따른 개체들이 출력되어 하나의 파일에 저장되는 형식이다.
Named Entities:
DataFormat(Audio, Image, Environmental Sensor Data),
Dataset(Project-specific labeled datasets for biodiversity monitoring),
PreprocessingStep(Data exploration, Filtering, Data labeling),
DataAugmentationTechnique(),
DeepLearningModel(CNN, DNN),
OptimizationTechnique(Stochastic Gradient Descent),
Hyperparameter(),
PerformanceMetric(),
RegularizationMethod(),
Framework(),
HardwareResource(),
CodeRepository(),
ModelPurpose(Classification, Detection)
이후, create_kg.py
파일에서는 추출한 NE와 구축한 온톨로지를 기준으로 맵핑하는 작업을 진행한다. 우선, read_named_entities()
함수로 NER의 결과가 저장된 txt를 불러온 뒤, 다음과 같이 structure한 형태로 변환해준다.
named_entities: {'DataFormat': ['Audio', 'WAV', 'Image', 'PNG)', ''], 'RawData': ['Audio recordings)', ''], 'PreprocessingStep': ['Audio Clipping and Standardization', 'File Formatting', 'Spectrogram Generation', 'Oscillogram Parameters', 'Image Saving)', ''], 'Dataset': ['Spectrogram images generated from audio recordings of frog calls', 'Custom datasets of spectrograms derived from bioacoustic recordings', 'Recordings sourced from Cornell Lab of Ornithology Macaulay Library', 'Recordings from recent field surveys)', ''], 'DataAnnotationTechnique': ['Manual selection of high-quality single notes)', ''], 'DataAugmentationTechnique': [')', ''], 'DeepLearningModel': ['CNN', 'Inception v3)', ''], 'Framework': ['TensorFlow)', ''], 'PerformanceMetric': ['Correct identification rate', 'Accuracy', 'Average certainty rate)', ''], 'ModelPurpose': ['Classification']}
이후 create_kg()
함수에서는 rdflib을 활용해서 그래프로 변환하는데, 이때 네임스페이스는 'dlprov'를 사용한다. 또한 Concept을 object로 두고 각 인스턴스를 subject로 둔 뒤 a(rdf:type)관계를 명시한 ttl 파일을 생성하는 코드가 있다.
코드 상에서는 해당 문서에 질문에 답할 수 없는 내용이 있으면 'Net mentioned'라고 표기되어 있어야 건너뛰고 진행되는데, 실제로 코드를 돌려보면 빈 괄호로 표시된다. 이 부분에 대한 예외 처리가 없어서 생성된 ttl 파일에 오류가 생기므로 프롬프트에 다음과 같은 내용을 추가해줬다.
'If there are no entities found for a specific concept, please write "Not mentioned" instead of leaving empty parentheses.'
❓ 다만 여기서 궁금한 건, type 속성만 사용된다는 것이다. 논문에서는 나오는 생성된 온톨로지의 properties는 아래와 같이 많은데, 실제로 KG를 생성하는데 사용되진 않는걸까? (아닐거 같은데, 코드 상으로는 해당 부분을 찾을 수 없다)
to be continued...