![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Продолжение серии постов об онтологиях.
Кажется, я обещал в этот раз написать о конкретных языках для описания онтологий? Увы, я вас обманул. Перед тем, как углубиться в перечисление языков и их свойств, надо сначала рассказать, что эти свойства из себя представляют и что они означают на практике. Другими словами, как в итоге происходит работа с разными видами онтологических моделей. Основной упор в этой (а может и следующей) части я сделаю на две вещи:
Предположим, у нас есть класс "млекопитающее" с подклассами "человек" и "собака". В классе "человек" мы создали инстанции "Иван" и "Данила", а в классе "собака" - инстанции "Белка" и "Стрелка" (подразумевается наличие свойства "имя" в этих классах). Теперь представим себе, что к нашей онтологии приложена программа-интерфейс, позволяющая нам слать в базу знаний запросы (аналогично SQL-интерфейсу баз данных). Пошлем запрос: выдать значение свойства "имя" всех инстанций класса "млекопитающее", где это значение заканчивается на "а". Поскольку все наши инстанции в конечном итоге привязаны к классу "млекопитающее" мы ожидаем получить множество {"Данила", "Белка", "Стрелка"}. Для этого наша программа обработки запросов (query engine) должна "понимать", что свойство "подкласс" транзитивно, т. е. из высказываний "B подкласс A" и "C подкласс B" следует факт "C подкласс A". Аналогично это должно работать с любым другим транзитивным свойством, а также, например, с рефлексивными свойствами (когда из "A * B" следует "B * A", где звездочкой обозначена наша реляция). Есть еще другие случаи, когда для обработки запроса требуется предварительная логическая обработка, но они сейчас неважны, по той простой причине, что наиболее распространённые query engines все равно ничего этого не умеют. То, какой мы результат получим, зависит от еще одной важной компоненты, о которой я до сих пор не упоминал.
Зачем нужна эта новая компонента, если можно доработать программу обработки запросов? Этому есть сразу две причины. Во-первых, если query engine будет разбираться в логических хитросплетениях нашей модели, то обработка запроса может длиться довольно долго (а если наш язык не имеет нужных органичений, то вообще бесконечно). Во-вторых, разработчики стремились к стандарту для языка и для обработки запросов, который бы работал с целым спектром языков описания онтологий. А каждый из этих языков имеет свои особенности, свойства и ограничения. И как раз определения транзитивности поддерживают не все из них. Поэтому задача делать логические выводы на основе модели традиционно передют особой компоненте, именуемой "reasoner". Reasoner "знает" свойства конкретного языка и занимается тем, что автоматически дополняет нашу модель фактами, выводимыми из имеющихся данных. Эти новые факты маркируются термином "inferred" и составляют особый слой в модели. А программа обработки запросов просто работает на основе всех имеющихся фактов. Для нашего примера он добавит факты:
Таким образом reasoner выводит на поверхность всю ту информацию, которая косвенно заложена в модели и позволяет получить из базы знаний действительно больше данных, чем мы внесли в нее напрямую. Более того, если мы случайно заложили в модель противоречия, reasoner имеет неплохой шанс их обнаружить. Без этой активой компоненты онтология служит скорее для упорядочивания какой-то информации (подобно моделям UML) а не как источник фактов, автоматически выведенных из сложных моделей.
Результат будет сильно зависеть от контекста данных в модели, поэтому как раз reasoner и проявляет разницу в логических концепциях того или иного языка. И особенно сильно это видно при обработке языков, использующих концепции закрытости или открытости моделируемого мира. Однако же, это будет темой уже для следующей части, иначе я рискую раздуть этот пост до совсем неприличных размеров.
Кажется, я обещал в этот раз написать о конкретных языках для описания онтологий? Увы, я вас обманул. Перед тем, как углубиться в перечисление языков и их свойств, надо сначала рассказать, что эти свойства из себя представляют и что они означают на практике. Другими словами, как в итоге происходит работа с разными видами онтологических моделей. Основной упор в этой (а может и следующей) части я сделаю на две вещи:
- Как вытащить из модели больше информации, чем мы заложили в нее напрямую?
- Что означают концепции замкнутости и открытости мира для создания моделей?
Предположим, у нас есть класс "млекопитающее" с подклассами "человек" и "собака". В классе "человек" мы создали инстанции "Иван" и "Данила", а в классе "собака" - инстанции "Белка" и "Стрелка" (подразумевается наличие свойства "имя" в этих классах). Теперь представим себе, что к нашей онтологии приложена программа-интерфейс, позволяющая нам слать в базу знаний запросы (аналогично SQL-интерфейсу баз данных). Пошлем запрос: выдать значение свойства "имя" всех инстанций класса "млекопитающее", где это значение заканчивается на "а". Поскольку все наши инстанции в конечном итоге привязаны к классу "млекопитающее" мы ожидаем получить множество {"Данила", "Белка", "Стрелка"}. Для этого наша программа обработки запросов (query engine) должна "понимать", что свойство "подкласс" транзитивно, т. е. из высказываний "B подкласс A" и "C подкласс B" следует факт "C подкласс A". Аналогично это должно работать с любым другим транзитивным свойством, а также, например, с рефлексивными свойствами (когда из "A * B" следует "B * A", где звездочкой обозначена наша реляция). Есть еще другие случаи, когда для обработки запроса требуется предварительная логическая обработка, но они сейчас неважны, по той простой причине, что наиболее распространённые query engines все равно ничего этого не умеют. То, какой мы результат получим, зависит от еще одной важной компоненты, о которой я до сих пор не упоминал.
Зачем нужна эта новая компонента, если можно доработать программу обработки запросов? Этому есть сразу две причины. Во-первых, если query engine будет разбираться в логических хитросплетениях нашей модели, то обработка запроса может длиться довольно долго (а если наш язык не имеет нужных органичений, то вообще бесконечно). Во-вторых, разработчики стремились к стандарту для языка и для обработки запросов, который бы работал с целым спектром языков описания онтологий. А каждый из этих языков имеет свои особенности, свойства и ограничения. И как раз определения транзитивности поддерживают не все из них. Поэтому задача делать логические выводы на основе модели традиционно передют особой компоненте, именуемой "reasoner". Reasoner "знает" свойства конкретного языка и занимается тем, что автоматически дополняет нашу модель фактами, выводимыми из имеющихся данных. Эти новые факты маркируются термином "inferred" и составляют особый слой в модели. А программа обработки запросов просто работает на основе всех имеющихся фактов. Для нашего примера он добавит факты:
- "Данила" (inferred) инстанция класса "млекопитающее"
- "Иван" (inferred) инстанция класса "млекопитающее"
- "Белка" (inferred) инстанция класса "млекопитающее"
- "Стрелка" (inferred) инстанция класса "млекопитающее"
Таким образом reasoner выводит на поверхность всю ту информацию, которая косвенно заложена в модели и позволяет получить из базы знаний действительно больше данных, чем мы внесли в нее напрямую. Более того, если мы случайно заложили в модель противоречия, reasoner имеет неплохой шанс их обнаружить. Без этой активой компоненты онтология служит скорее для упорядочивания какой-то информации (подобно моделям UML) а не как источник фактов, автоматически выведенных из сложных моделей.
Результат будет сильно зависеть от контекста данных в модели, поэтому как раз reasoner и проявляет разницу в логических концепциях того или иного языка. И особенно сильно это видно при обработке языков, использующих концепции закрытости или открытости моделируемого мира. Однако же, это будет темой уже для следующей части, иначе я рискую раздуть этот пост до совсем неприличных размеров.