# # dualloop # # File: preprocessing.py # # Authors: Deleted for purposes of anonymity # # Proprietor: Deleted for purposes of anonymity --- PROPRIETARY INFORMATION # # The software and its source code contain valuable trade secrets and shall be maintained in # confidence and treated as confidential information. The software may only be used for # evaluation and/or testing purposes, unless otherwise explicitly stated in the terms of a # license agreement or nondisclosure agreement with the proprietor of the software. # Any unauthorized publication, transfer to third parties, or duplication of the object or # source code---either totally or in part---is strictly prohibited. # # Copyright (c) 2019 Proprietor: Deleted for purposes of anonymity # All Rights Reserved. # # THE PROPRIETOR DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS FOR A PARTICULAR PURPOSE AND THE WARRANTY AGAINST LATENT # DEFECTS, WITH RESPECT TO THE PROGRAM AND ANY ACCOMPANYING DOCUMENTATION. # # NO LIABILITY FOR CONSEQUENTIAL DAMAGES: # IN NO EVENT SHALL THE PROPRIETOR OR ANY OF ITS SUBSIDIARIES BE # LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES # FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF INFORMATION, OR # OTHER PECUNIARY LOSS AND INDIRECT, CONSEQUENTIAL, INCIDENTAL, # ECONOMIC OR PUNITIVE DAMAGES) ARISING OUT OF THE USE OF OR INABILITY # TO USE THIS PROGRAM, EVEN IF the proprietor HAS BEEN ADVISED OF # THE POSSIBILITY OF SUCH DAMAGES. # # For purposes of anonymity, the identity of the proprietor is not given herewith. # The identity of the proprietor will be given once the review of the # conference submission is completed. # # THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. # import json import multiprocessing from SPARQLWrapper import SPARQLWrapper, JSON import spacy nlp = spacy.load('en_core_web_lg') import wordsegment wordsegment.load() import re import numpy as np import rdflib from rdflib import Graph # from rdf2vec import graph # from rdf2vec import rdf2vec from sentence_transformers import SentenceTransformer sbert = SentenceTransformer('sentence-transformers/paraphrase-MiniLM-L6-v2') from nltk.stem import PorterStemmer porter = PorterStemmer() from nltk.corpus import wordnet cfg = None def query_ontology(): sparql = SPARQLWrapper(cfg.RDF4J_SERVER + "/rdf4j-server/repositories") sparql.setReturnFormat(JSON) results = sparql.query().convert() ontology_list = [] for repository in results['results']['bindings']: #print(repository) ontology = {} ontology['id'] = repository['id']['value'] ontology['title'] = repository['title']['value'] ontology['uri'] = repository['uri']['value'] ontology_list.append(ontology) return ontology_list def query_class(ontology): print(ontology) sparql = SPARQLWrapper(ontology) sparql.setQuery( """ PREFIX owl: <http://www.w3.org/2002/07/owl#> SELECT ?class WHERE { ?class rdf:type owl:Class. FILTER (!isBlank(?class)) } """ ) sparql.setReturnFormat(JSON) results = sparql.query().convert() class_list = [] for v in results["results"]["bindings"]: class_list.append(v["class"]["value"]) return class_list def get_subclasses(ontology, class_prefix, class_name): sparql = SPARQLWrapper(ontology) queryStatement = """ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX pre: <%(class_prefix)s> SELECT ?subclass WHERE { ?subclass rdfs:subClassOf pre:%(class_name)s . } """ % {"class_prefix": class_prefix, "class_name" : class_name} #print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() class_list = [] for result in results["results"]["bindings"]: subclass = result['subclass']['value'] class_list.append(subclass) return class_list def get_superclasses(ontology, class_prefix, class_name): sparql = SPARQLWrapper(ontology) queryStatement = """ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX pre: <%(class_prefix)s> SELECT ?superclass WHERE { pre:%(class_name)s rdfs:subClassOf ?superclass . } """ % {"class_prefix": class_prefix, "class_name" : class_name} #print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() class_list = [] for result in results["results"]["bindings"]: subclass = result['superclass']['value'] class_list.append(subclass) return class_list def split_prefix_class_name(uri): tmp = uri.split("#",1) if len(tmp) == 2: class_prefix = uri.split("#",1)[0] + "#" class_name = uri.split("#",1)[1] else: tmp = uri.split("/",-1) class_prefix = "/".join(tmp[:-1]) + "/" class_name = tmp[-1:][0] return class_prefix, class_name def get_equivalent_classes(sparql_endpoint, class_prefix, class_name): sparql = SPARQLWrapper(sparql_endpoint) queryStatement = """ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX pre: <%(class_prefix)s> select distinct ?property where { pre:%(class_name)s owl:equivalentClass ?obj . ?obj owl:unionOf ?c . ?c rdf:rest*/rdf:first ?property } """ % {"class_prefix": class_prefix, "class_name" : class_name} print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() results = results["results"]["bindings"] results_clean = [] if not results: return results_clean for i in results: _, v = split_prefix_class_name(i["property"]["value"]) results_clean.append(v) return results_clean def get_label(ontology, class_prefix, class_name): sparql = SPARQLWrapper(ontology) queryStatement = """ PREFIX pre: <%(class_prefix)s> select ?label where { pre:%(class_name)s rdfs:label ?label . } """ % {"class_prefix": class_prefix, "class_name" : class_name} #print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() items = results["results"]["bindings"] for item in items: return item['label']['value'] return "" def get_definition(ontology, class_prefix, class_name): sparql = SPARQLWrapper(ontology) queryStatement = """ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX obo-term: <http://purl.obolibrary.org/obo/> PREFIX pre: <%(class_prefix)s> select distinct ?definition where { pre:%(class_name)s obo-term:IAO_0000115 ?definition . } """ % {"class_prefix": class_prefix, "class_name" : class_name} # print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() definitions = results["results"]["bindings"] for definition in definitions: return definition['definition']['value'] return "" def get_comment(ontology, class_prefix, class_name): sparql = SPARQLWrapper(ontology) queryStatement = """ PREFIX pre: <%(class_prefix)s> select ?comment where { pre:%(class_name)s rdfs:comment ?comment . } """ % {"class_prefix": class_prefix, "class_name" : class_name} #print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() comments = results["results"]["bindings"] for comment in comments: return comment['comment']['value'] return "" def get_relevant_synonyms(ontology, class_prefix, class_name): sparql = SPARQLWrapper(ontology) queryStatement = """ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX pre: <%(class_prefix)s> SELECT ?label WHERE { pre:%(class_name)s oboInOwl:hasRelatedSynonym ?o . ?o rdfs:label ?label . } """ % {"class_prefix": class_prefix, "class_name" : class_name} #print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() synonyms_list = [] for result in results["results"]["bindings"]: subclass = result['label']['value'] synonyms_list.append(subclass) return synonyms_list def get_properties(ontology, class_prefix, class_name): sparql = SPARQLWrapper(ontology) queryStatement = """ PREFIX pre: <%(class_prefix)s> select distinct ?property where { ?property rdfs:domain pre:%(class_name)s . } """ % {"class_prefix": class_prefix, "class_name" : class_name} #print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() properties = [] for result in results["results"]["bindings"]: full_uri = result['property']['value'] prop = full_uri.split("#",1)[1] properties.append(prop) return properties def get_groundtruth(file, fix_uri): g=rdflib.Graph() print(file) g.parse(file) qres = g.query( """ SELECT ?from ?to ?m WHERE { ?a a <http://knowledgeweb.semanticweb.org/heterogeneity/alignment#Cell>; <http://knowledgeweb.semanticweb.org/heterogeneity/alignment#measure> ?m ; <http://knowledgeweb.semanticweb.org/heterogeneity/alignment#entity1> ?from ; <http://knowledgeweb.semanticweb.org/heterogeneity/alignment#entity2> ?to. } """ ) if len(qres) == 0: qres = g.query( """ SELECT ?from ?to ?m WHERE { ?a a <http://knowledgeweb.semanticweb.org/heterogeneity/alignmentCell>; <http://knowledgeweb.semanticweb.org/heterogeneity/alignmentmeasure> ?m ; <http://knowledgeweb.semanticweb.org/heterogeneity/alignmententity1> ?from ; <http://knowledgeweb.semanticweb.org/heterogeneity/alignmententity2> ?to. } """ ) matches = [] for row in qres: match = {} source_class = row[0] target_class = row[1] if fix_uri == True: match['source_class'] = source_class.strip().replace("#", "/#") match['target_class'] = target_class.strip().replace("#", "/#") else: match['source_class'] = source_class.strip() match['target_class'] = target_class.strip() matches.append(match) return matches def get_groundtruth_from_rdf4j(repository): sparql = SPARQLWrapper(repository) queryStatement = """ SELECT ?entity1 ?entity2 WHERE { ?a a <http://knowledgeweb.semanticweb.org/heterogeneity/alignment#Cell>; <http://knowledgeweb.semanticweb.org/heterogeneity/alignment#entity1> ?entity1 ; <http://knowledgeweb.semanticweb.org/heterogeneity/alignment#entity2> ?entity2. } """ #print(queryStatement) sparql.setQuery(queryStatement) sparql.setReturnFormat(JSON) results = sparql.query().convert() #print(results) matches = [] for result in results["results"]["bindings"]: match = {} source_class = result['entity1']['value'] target_class = result['entity2']['value'] match['source_class'] = source_class match['target_class'] = target_class matches.append(match) return matches def split_name(n): sub_names = re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', n)).split() return sub_names def find_root_noun(spay_tokens): for token in spay_tokens: if token.dep_ == 'ROOT': return str(token) return None class AlignmentProfile: def __init__(self): self.ontology_name = None self.uri = None self.class_prefix = None self.class_name = None self.class_name_words = None self.class_name_stemmed = None self.class_name_root = None self.acronym = None self.synonyms = None self.label = None self.label_words = None # self.definition = None self.comment = None self.subclasses = None self.superclasses = None self.properties = None # properties for the anatomy dataset # self.equivalent_classes = [] # self.relevant_synonyms = [] # produced embeddings # self.class_name_embedding = None # self.class_name_words_embedding = None # self.class_long_name_embedding = None # self.class_name_sbert_embedding = None # self.label_embedding = None # self.label_sbert_embedding = None # self.comment_embedding = None # self.comment_sbert_embedding = None # self.walk_embedding = None def build_class_alignment_profile(ontology_name, class_uri, with_embedding): ap = AlignmentProfile() ap.ontology_name = ontology_name ap.uri = class_uri ap.class_prefix = class_uri.split("#",1)[0]+"#" ap.class_name = class_uri.split("#",1)[1] name_in_words = wordsegment.segment(ap.class_name) ap.class_name_words = ' '.join([str(elem) for elem in name_in_words]) ap.class_name_stemmed = porter.stem(ap.class_name) ap.class_name_root = find_root_noun(nlp(ap.class_name)) ap.acronym = ''.join([s[0] for s in re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', ap.class_name)).split()]) synonyms = [] for syn in wordnet.synsets(ap.class_name): for lm in syn.lemmas(): synonyms.append(lm.name()) ap.synonyms = synonyms ap.label = get_label(ap.ontology_name, ap.class_prefix, ap.class_name) label_words = wordsegment.segment(ap.label) ap.label_words = ' '.join([str(elem) for elem in label_words]) ap.comment = get_comment(ap.ontology_name, ap.class_prefix, ap.class_name) ap.subclasses = get_subclasses(ap.ontology_name, ap.class_prefix, ap.class_name) ap.superclasses = get_superclasses(ap.ontology_name, ap.class_prefix, ap.class_name) ap.properties = get_properties(ap.ontology_name, ap.class_prefix, ap.class_name) # ap.definition = get_definition(ap.ontology_name, ap.class_prefix, ap.class_name) # ap.equivalent_classes = get_equivalent_classes(ap.ontology_name, ap.class_prefix, ap.class_name) # ap.relevant_synonyms = get_relevant_synonyms(ap.ontology_name, ap.class_prefix, ap.class_name) # embedding feature # if with_embedding: # ap.class_name_embedding = nlp(ap.class_name_words).vector # ap.label_embedding = nlp(ap.label_words).vector # ap.comment_embedding = nlp(ap.comment).vector # # ap.class_name_sbert_embedding = sbert.encode(ap.class_long_name) # ap.label_sbert_embedding = sbert.encode(ap.label) # ap.comment_sbert_embedding = sbert.encode(ap.comment) return ap def build_rdf2vec(ontology_name, classes): endpoint = ontology_name + "/statements" g = Graph() g.parse(endpoint) kg = graph.rdflib_to_kg(g, label_predicates=[]) transformer = rdf2vec.RDF2VecTransformer(wl=False, max_path_depth=2, sg=1) walk_embeddings = transformer.fit_transform(kg, classes) print(len(walk_embeddings)) return walk_embeddings def build_alignment_profile(ontology_name, with_embedding): class_list = query_class(ontology_name) #print(class_list) # build the graph embedding for rdf tripes in the ontology #rdf_embeddings = build_rdf2vec(ontology_name, class_list) # # for each class profiles = [] for index, class_uri in enumerate(class_list): #print(class_uri) profile = build_class_alignment_profile(ontology_name, class_uri, with_embedding) # query the rdf2vec embedding for this class #profile.walk_embedding = rdf_embeddings[index] profiles.append(profile) return profiles