Назад в библиотеку

Документация Owlready2

Автор: Jean-Baptiste Lamy

Автор перевода: Чайка В.А.
Источник: Официальный сайт документации pythonhosted.org/Owlready2/ [Ссылка]


Owlready2 - это модуль для онтолого-ориентированного программирования на Python. Он может загружать онтологии OWL 2.0 как объекты Python, изменять их, сохранять и выполнять рассуждения через HermiT (в комплекте). Owlready2 обеспечивает прозрачный доступ к онтологиям OWL (в отличие от обычного API на основе Java).

Owlready версии 2 включает оптимизированное хранилище триплетов/четверлетов, основанное на SQLite3. Этот четверлет оптимизирован как по производительности, так и по потреблению памяти. В отличие от версии 1, Owlready2 может работать с большими онтологиями.

Owlready2 был создан Жан-Батистом Лами в исследовательской лаборатории LIMICS, Университет Париж 13, Сорбонна Париж Сите, INSERM UMRS 1142, Университет Париж 6. Он был разработан в ходе исследовательского проекта VIIIP, финансируемого ANSM, Французским агентством по лекарствам; вот почему некоторые примеры в этой документации относятся к лекарствам;).

Owlready2 доступен под лицензией GNU LGPL v3. Форум / список рассылки для Owlready доступен на Nabble: http://owlready.8326.n8.nabble.com

Содержание

Вступление

Owlready2 - это модуль для управления онтологиями OWL 2.0 в Python. Он может загружать, изменять, сохранять онтологии и поддерживает рассуждения через HermiT (в комплекте). Owlready обеспечивает прозрачный доступ к онтологиям OWL.

Owlready2 может:

Краткий пример: Что я могу делать с Owlready?

Загрузите онтологию из локального репозитория или из Интернета:

>>> from owlready2 import *
>>> onto_path.append("/path/to/your/local/ontology/repository")
>>> onto = get_ontology("http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl")
>>> onto.load()

Создайте новые классы в онтологии, возможно, смешивая конструкции OWL и методы Python:

>>> class NonVegetarianPizza(onto.Pizza):
...   equivalent_to = [
...     onto.Pizza
...   & ( onto.has_topping.some(onto.MeatTopping)
...     | onto.has_topping.some(onto.FishTopping)
...     ) ]

...   def eat(self): print("Beurk! I'm vegetarian!")

Получите доступ к классам онтологии и создайте новые экземпляры / индивиды:

>>> onto.Pizza
pizza_onto.Pizza

>>> test_pizza = onto.Pizza("test_pizza_owl_identifier")
>>> test_pizza.has_topping = [ onto.CheeseTopping(),
...                            onto.TomatoTopping() ]

В Owlready2 практически любые списки можно изменять на месте, например, добавляя / удаляя элементы из списков. Owlready2 автоматически обновляет Quadstore RDF.

>> test_pizza.has_topping.append(onto.MeatTopping())

Проведите рассуждение и классифицируйте экземпляры и классы:

>>> test_pizza.__class__
onto.Pizza

>>> # Выполнить HermiT и переопределить Индивиды и Классы
>>> sync_reasoner()

>>> test_pizza.__class__
onto.NonVegetarianPizza
>>> test_pizza.eat()
Beurk! I'm vegetarian !

Экспортируйте в OWL файл:

>>> onto.save()

Архитектура

Owlready2 поддерживает четверлеты RDF в оптимизированной базе данных SQLite3, либо в памяти, либо на диске (см. Миры). Это обеспечивает высокоуровневый доступ к классам и объектам в онтологии (также известный как онтологически-ориентированное программирование). Классы и Индивиды загружаются динамически из четверлетов по мере необходимости, кэшируются в памяти и уничтожаются, когда больше не нужны.

Контакты и ссылки

Форум для Owlready доступен на Nabble: http://owlready.8326.n8.nabble.com

В случае возникновения проблем, напишите на форум или свяжитесь с Жан-Батистом Лами

LIMICS
University Paris 13, Sorbonne Paris Cite
Bureau 149
74 rue Marcel Cachin
93017 BOBIGNY
FRANCE

Owlready на BitBucket (репозиторий для разработки): https://bitbucket.org/jibalamy/owlready

Управление онтологиями

Создание онтологии

Новую пустую онтологию можно получить с помощью функции get_ontology(); она принимает единственный параметр - IRI онтологии. IRI - это своего рода URL-адрес; IRI используются в качестве идентификаторов онтологий.

>>> from owlready import *

>>> onto = get_ontology("http://test.org/onto.owl")

Если онтология уже была создана для того же IRI, она будет возвращена.

В некоторых онтологиях используется символ # в IRI, чтобы отделить имя онтологии от имени сущностей, в то время как в других используется символ /. По умолчанию Owlready2 использует #, если вы хотите использовать /, IRI должен заканчиваться на /.

Примеры:

>>> onto = get_ontology("http://test.org/onto.owl") # => http://test.org/onto.owl#entity

>>> onto = get_ontology("http://test.org/onto") # => http://test.org/onto#entity

>>> onto = get_ontology("http://test.org/onto/") # => http://test.org/onto/entity

Загрузка онтологии из файлов OWL

Используйте метод онтологии .load () для ее загрузки.

Самый простой способ загрузить онтологию – загрузить локальную копию. В этом случае IRI – это локальное имя файла с префиксом «file: //», например:

>>> onto = get_ontology("file:///home/jiba/onto/pizza_onto.owl").load()

Если указан URL-адрес, Owlready2 сначала ищет локальную копию файла OWL и, если он не найден, пытается загрузить его из Интернета. Например:

>>> onto_path.append("/path/to/owlready/onto/")

>>> onto = get_ontology("http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl").load()

Глобальная переменная onto_path содержит список каталогов для поиска локальных копий онтологий. Она ведет себя аналогично sys.path (для модулей Python).

Функция get_ontology() возвращает онтологию указанную в IRI и при необходимости создает новую пустую онтологию.

Метод .load() загружает онтологию из локальной копии или из Интернета. Безопасно вызывать .load() несколько раз для одной и той же онтологии. Он будет загружен только один раз.

Owlready2 в настоящее время читает файлы следующих форматов: RDF / XML, OWL / XML, NTriples. Формат файла определяется автоматически.

NTriples – это очень простой формат, который изначально поддерживается Owlready2.

RDF / XML – наиболее распространенный формат; он также изначально поддерживается Owlready2 (начиная с версии 0.2).

OWL / XML поддерживается с помощью специального синтаксического анализатора, интегрированного в Owlready2. Этот синтаксический анализатор поддерживает большую часть OWL, но не является полным. Он был протестирован в основном с файлами OWL, созданными с помощью редактора Protege, или с самим Owlready. Следовательно, предпочтительными форматами являются RDF / XML и NTriples.

Доступ к содержанию онтологии

Вы можете получить доступ к содержимому онтологии, используя «точечную» нотацию, как обычно в Python или, в более общем смысле, в объектно-ориентированном программировании. Таким образом, вы можете получить доступ к классам, экземплярам, свойствам, свойствам аннотации ..., определенным в онтологии. Также допускается синтаксис [].

>>> print(onto.Pizza)
onto.Pizza

>>> print(onto["Pizza"])
onto.Pizza

Онтология имеет следующие атрибуты:

и следующие методы:

Многие методы возвращают генератор. Генераторы позволяют перебирать значения без создания списка, что может улучшить производительность. Однако они часто не очень удобны при изучении онтологии:

>>> onto.classes()
⟨generator object _GraphManager.classes at 0x7f854a677728⟩

Генератор можно преобразовать в список с помощью функции Python list ():

list(onto.classes())
[pizza_onto.CheeseTopping, pizza_onto.FishTopping, pizza_onto.MeatTopping,
pizza_onto.Pizza, pizza_onto.TomatoTopping, pizza_onto.Topping,
pizza_onto.NonVegetarianPizza]

Псевдо-словарь IRIS можно использовать для доступа к объекту из его полного IRI:

>>> IRIS["http://www.lesfleursdunormal.fr/static/_downloads/pizza_onto.owl#Pizza"]
pizza_onto.Pizza

Онтологии также могут определять объекты, расположенные в других пространствах имен, например, Gene Ontology (GO) имеет следующий IRI: 'http://purl.obolibrary.org/obo/go.owl', но IRI объектов GO имеют форму 'http://purl.obolibrary.org/obo/GO_entity' (обратите внимание на отсутствующий 'go.owl #'). См. Пространства имен, чтобы узнать, как получить доступ к таким объектам.

Простые запросы

Простые запросы могут выполняться с помощью метода онтологии .search(). Он ожидает один или несколько аргументов ключевого слова. Поддерживаемые ключевые слова:

Значение, связанное с каждым ключевым словом, может быть одним значением или списком из нескольких значений. Звездочка * может использоваться как шаблонный символ в строковых значениях.

Например, для поиска всех объектов с IRI, оканчивающимся на ‘Topping':

>>> onto.search(iri = "*Topping")
[pizza_onto.CheeseTopping, pizza_onto.FishTopping, pizza_onto.MeatTopping,
pizza_onto.TomatoTopping, pizza_onto.Topping]

Кроме того, специальное значение “*” может использоваться как подстановочный знак для любого объекта. Например, следующая строка выполняет поиск всех сущностей, которые связаны с другим с помощью отношения ‘has_topping’:

>>> onto.search(has_topping = "*")

Когда ожидается единственное возвращаемое значение, можно использовать метод .search_one(). Работает аналогично:

>>> onto.search_one(label = "my label")

Для более сложных запросов SQPARQL может быть использован с RDFlib (см. Раздел "Миры").

Импорт других онтологий

Онтология может импортировать другие онтологии, так же как модуль Python может импортировать другие модули.

Атрибут import_ontologies онтологии – это список импортируемой онтологии. Вы можете добавлять или удалять элементы в этом списке:

>>> onto.imported_ontologies.append(owlready_ontology)

Сохранение онтологии в файл OWL

Метод онтологии .save() может использоваться для ее сохранения. Он будет сохранен в первом каталоге в onto_path.

>>> onto.save()
>>> onto.save(file = "filename or fileobj", format = "rdfxml")

.save() принимает два необязательных параметра: 'file', объект файла или имя файла для сохранения онтологии, и ‘format’, формат файла (по умолчанию RDF / XML).

Owlready2 в настоящее время записывает файлы в следующем формате: «rdf / xml», «ntriples».

NTriples – это очень простой формат, который изначально поддерживается Owlready2.

RDF / XML – наиболее распространенный формат; он также изначально поддерживается Owlready2 (начиная с версии 0.2).

OWL / XML еще не поддерживается для записи.

Классы и Индивиды (Экземпляры)

Создание Класса

Новый класс может быть создан в онтологии, унаследовав класс owlready2.Thing.

Атрибут класса онтологии можно использовать для связывания вашего класса с данной онтологией. Если этот атрибут не указан, то он наследуется от родительского класса (в приведенном ниже примере родительский класс - это Thing, который определен в онтологии ‘owl’).

>>> from owlready2 import *

>>> onto = get_ontology("http://test.org/onto.owl")

>>> class Drug(Thing):
...     namespace = onto

Атрибут класса пространства имен используется для построения полного IRI класса и может быть онтологией или пространством имен (см. Пространство имен). Оператор ‘with' также может использоваться для предоставления онтологии (или пространства имен):

>>> onto = get_ontology("http://test.org/onto.owl")

>>> with onto:
>>>     class Drug(Thing):
...         pass

Атрибут .iri класса можно использовать для получения полного IRI класса.

>>> print(Drug.iri)
http://test.org/onto.owl#Drug

Атрибуты .name и .iri доступны для записи и могут быть изменены (это позволяет изменять IRI объекта, что иногда называют «рефакторингом»).

Создание и управление подклассами

Подклассы могут быть созданы путем наследования класса онтологии. Поддерживается множественное наследование.

>>> class DrugAssociation(Drug): # Преперат, сочетающий в себе неск. активных компонентов
...     pass

Owlready2 предоставляет атрибут .is_a для получения списка суперклассов (можно использовать __bases__, но с некоторыми ограничениями, описанными в конструкциях классов, ограничениях и логических операторах). Его также можно изменить для добавления или удаления суперклассов.

>>> print(DrugAssociation.is_a)
[onto.Drug]

Методы класса .descendants() и .ancestors() возвращают набор классов-потомков и предков (включая собственные, но исключая классы, не являющиеся сущностями, такие как ограничения).

>>> DrugAssociation.ancestors()
{onto.DrugAssociation, owl.Thing, onto.Drug}

Динамическое создание классов

Модуль Python ‘types’ можно использовать для динамического создания классов и подклассов:

>>> import types

>>> NewClass = types.new_class("NewClassName", (SuperClass,), kwds = { "namespace" : my_ontology })

Создание эквивалентных классов

Атрибут класса .equivalent_to - это список эквивалентных классов. Он ведет себя как .is_a.

Создание Индивидов

Индивиды - это экземпляры в онтологиях. Они создаются, как и любые другие экземпляры Python. Первый параметр - это имя (или идентификатор) Индивида; он соответствует атрибуту .name в Owlready2. Если он не указан, то имя автоматически генерируется из имени класса и номера.

>>> my_drug = Drug("my_drug")
>>> print(my_drug.name)
my_drug
>>> print(my_drug.iri)
http://test.org/onto.owl#my_drug

>>> unamed_drug = Drug()
>>> print(unamed_drug.name)
drug_1

Дополнительные параметры с помощью ключевых слова могут быть заданы при создании Индивида, и они будут связаны с соответствующими Свойствами (для получения дополнительной информации о свойствах см. Свойства).

my_drug = Drug("my_drug2", namespace = onto, has_for_active_principle = [],...)

Экземпляры/Индивиды сразу доступны в онтологии:

>>> print(onto.drug_1)
onto.drug_1

Метод .instances() класса может использоваться для перебора всех Индивидов Класса (включая его подклассы). Он возвращает генератор.

>>> for i in Drug.instances(): print(i)

У Индивидов также есть атрибут .equivalent_to

Многоклассовые/Мультиклассовые индивиды

В онтологиях Индивид может принадлежать более чем к одному Классу. Это поддерживается в Owlready2.

У Индивидов есть атрибут .is_a, который ведет себя аналогично атрибуту .is_a Класса, но с Классами Индивида. Чтобы создать многоклассовый Индивид, вам необходимо сначала создать Индивид как экземпляр одного класса, а затем добавить другой Класс(ы) в его атрибут .is_a:

>>> class BloodBasedProduct(Thing):
...     ontology = onto
>>> a_blood_based_drug = Drug()
>>> a_blood_based_drug.is_a.append(BloodBasedProduct)

Owlready2 автоматически создаст скрытый Класс, наследующий как от Drug, так и от BloodBasedProduct. Этот скрытый класс виден в a_blood_based_drug .__ class__, но не в a_blood_based_drug.is_a.

Уничтожение сущностей

Глобальная функция destroy_entity() может использоваться для уничтожения сущности, то есть для удаления ее из онтологии и хранилища квадрлетов. Owlready2 ведет себя аналогично Protege4 при уничтожении сущностей: все отношения, включающие уничтоженную сущность, также уничтожаются, а также все конструкции классов и пустые узлы, которые ссылаются на нее.

>>> destroy_entity(individual)
>>> destroy_entity(Klass)
>>> destroy_entity(Property)

Свойства

Создание нового класса свойства

Новое свойство можно создать, создав подкласс класса ObjectProperty или DataProperty. Свойства ‘domain’ и 'range' могут использоваться для указания домена и диапазона свойства. Домен и диапазон должны быть указаны в списке, так как OWL позволяет указать несколько доменов или диапазонов для данного свойства (если указано несколько доменов или диапазонов, домен или диапазон являются их пересечением, т. Е. Элементы в списке объединяются логическим оператором И).

В следующем примере создаются два класса, лекарство и ингредиент, а затем свойство ObjectProperty, которое их связывает.

>>> from owlready2 import *

>>> onto = get_ontology("http://test.org/onto.owl")

>>> with onto:
...     class Drug(Thing):
...         pass
...     class Ingredient(Thing):
...         pass
...     class has_for_ingredient(ObjectProperty):
...         domain    = [Drug]
...         range     = [Ingredient]

Кроме того, при создании свойства можно использовать синтаксис 'domain' >> ’range’. Он заменяет родительский Класс ObjectProperty или DataProperty следующим образом:

>>> with onto:
...     class has_for_ingredient(Drug >> Ingredient):
...         pass

Кроме того, доступны следующие подклассы Property: FunctionalProperty, InverseFunctionalProperty, TransitiveProperty, SymmetricProperty, AsymmetricProperty, ReflexiveProperty, IrreflexiveProperty. Их следует использовать в дополнение к ObjectProperty или DataProperty (или синтаксису 'domain >> range’).

Создание отношений

Отношение - это тройка вида(субъект, свойство, объект), где свойство - это класс Property, а субъект и объект - это экземпляры (или литералы, такие как строка или числа), которые являются подклассами домена и диапазона, определенного для класса свойств. Отношение может быть получено или установлено с использованием атрибута Python субъекта, имя атрибута такое же, как имя класса свойств:

>>> my_drug = Drug("my_drug")

>>> acetaminophen = Ingredient("acetaminophen")

>>> my_drug.has_for_ingredient = [acetaminophen]

Атрибут содержит список субъектов:

>>> print(my_drug.has_for_ingredient)
[onto.acetaminophen]

Этот список можно изменить “на месте” (прим. - сразу) или задать новое значение; Owlready2 автоматически добавит или удалит тройки RDF в хранилище четверлетов по мере необходимости:

>>> codeine = Ingredient("codeine")

>>> my_drug.has_for_ingredient.append(codeine)

>>> print(my_drug.has_for_ingredient)
[onto.acetaminophen, onto.codeine]

Data Property – свойство данных

Свойства данных - это свойства с типом данных в их диапазоне. В настоящее время Owlready2 поддерживает следующие типы данных:

Ниже показан пример строкового свойства данных:

>>> with onto:
...     class has_for_synonym(DataProperty):
...         range = [str]

>>> acetaminophen.has_for_synonym = ["acetaminophen", "paracetamol"]

Также имеется возможность использовать ‘domain >> range’ синтаксис:

>>> with onto:
...     class has_for_synonym(Thing >> str):
...         pass

Inverse Properties – обратные свойства

Два свойства являются обратными, если они выражают одно и то же значение, но в обратном порядке. Например, свойство «is_ingredient_of» (является ингредиентом) является обратным свойству «has_for_ingredient» (имеет ингредиент), созданному выше: выражение «лекарство A имеет ингредиент B» эквивалентно «B является ингредиентом лекарства A».

В Owlready2 обратные свойства определяются с помощью атрибута inverse_property.

>>> with onto:
...     class is_ingredient_of(ObjectProperty):
...         domain           = [Ingredient]
...         range            = [Drug]
...         inverse_property = has_for_ingredient

Owlready автоматически обрабатывает обратные свойства. Он автоматически установит has_for_ingredient.inverse_property и автоматически обновит отношения при изменении обратного отношения.

>>> my_drug2 = Drug("my_drug2")

>>> aspirin = Ingredient("aspirin")

>>> my_drug2.has_for_ingredient.append(aspirin)

>>> print(my_drug2.has_for_ingredient)
[onto.aspirin]

>>> print(aspirin.is_ingredient_of)
[onto.my_drug2]

>>> aspirin.is_ingredient_of = []

>>> print(my_drug2.has_for_ingredient)
[]

Это не сработает для препарата, созданного ранее, потому что мы создали обратное свойство после того, как создали связь между my_drug и aspirin

Functional and Inverse Functional properties – функциональные и обратно-функциональные свойства

Функциональное свойство – это свойство, которое имеет единственное значение для данного экземпляра. Функциональные свойства создаются путем наследования класса FunctionalProperty.

>>> with onto:
...     class has_for_cost(DataProperty, FunctionalProperty): # Каждое лекарство имеет единственную цену
...         domain    = [Drug]
...         range     = [float]

>>> my_drug.has_for_cost = 4.2

>>> print(my_drug.has_for_cost)
4.2

В отличие от других свойств, функциональное свойство возвращает одно значение вместо списка значений. Если значение не определено, возвращается None.

>>> print(my_drug2.has_for_cost)
None

Owlready2 также может угадывать, когда Свойство функционально по отношению к данному классу. В следующем примере свойство ‘prop' не задано функциональным, но предполагается, что для Индивидов класса B может быть только одно значение данного свойства. Следовательно, Owlready2 считает 'prop' функциональным свойством для класса B.

>>> with onto:
...     class prop(ObjectProperty): pass
...     class A(Thing): pass
...     class B(Thing):
...         is_a = [ prop.max(1) ]

>>> A().prop
[]
>>> B().prop
None

Обратное функциональное свойство – это свойство, обратное свойство которого является функциональным. Они создаются путем наследования класса InverseFunctionalProperty.

Создание подсвойств

Подсвойство может быть создано путем создания подкласса класса Property.

>>> with onto:
...     class ActivePrinciple(Ingredient):
...         pass
...     class has_for_active_principle(has_for_ingredient):
...         domain    = [Drug]
...         range     = [ActivePrinciple]

Owlready2 в настоящее время не обновляет автоматически родительские свойства при определении дочернего свойства. Однако это может быть добавлено в будущей версии.

Связывание имени псевдонима Python со свойствами

В онтологиях свойствам обычно даются длинные имена, например «has_for_ingredient», тогда как в языках программирования, таких как Python, более распространены более короткие имена атрибутов, например «Ингредиенты» (обратите внимание также на использование формы множественного числа, поскольку на самом деле это список из нескольких ингредиентов).

Owlready2 позволяет переименовывать свойства с более точными именами Pythonic через аннотацию python_name (определенную в онтологии Owlready):

>>> has_for_ingredient.python_name = "ingredients"

>>> my_drug3 = Drug()

>>> cetirizin = Ingredient("cetirizin")

>>> my_drug3.ingredients = [cetirizin]

Класс Property по прежнему обозначается как ‘has_for_ingredient’, например он по прежнему доступен как ‘onto.has_for_ingredient’, но не как ‘onto.ingredients’.

Для получения дополнительной информации об использовании аннотаций см. Аннотации.

Аннотации «python_name» также могут быть определены в редакторах онтологий, таких как Protege, путем импорта онтологии Owlready (файл «owlready2 / owlready_ontology.owl» в источниках Owlready2).

Для получения полной версии документации на русском языке обратитесь по адресу: valera_chaika@mail.ru