Онтологии, OWL, Sparql: моделирование того, что "чего-то нет" и соображения производительности

мы хотим моделировать, что "чего-то нет" в отличие от отсутствующей информации, например, явное утверждение о том, что "пациент не получил химиотерапию" или что "у пациента нет одышки" отличается от отсутствующей информации о том, есть ли у пациента одышка.

мы подумали о нескольких подходах, например

  • использование класса отрицания: "No_Dyspnea". Но это кажется семантически проблематичным, так как какой тип будет этим классом? Она не может быть потомком класса "одышка".
  • использование свойств объекта "не существует", например" отрицает "или" does_not_have", а затем индивидуум корневого класса одышки в качестве объекта этой тройки.
  • использование пустых узлов, которые описывают, что человек принадлежит к группе вещей, которые не имеют одышки. Например:

    dat:PatientW2 a [ rdf:type owl:Class;
                  owl:complementOf [
                    rdf:type owl:Restriction ;
                        owl:onProperty roo:has_finding;
                        owl:someValuesFrom nci:Dyspnea;
                  ]
                ] .
    

мы считаем, что 3-й вариант является наиболее "онтологически правильным" способом выражения этого. Однако, играя с ним, мы столкнулись с серьезными проблемами производительности в простых сценариях.

мы используем Сезам с магазином OWLIM-Lite и импортировали тезаурус NCI (280 МБ, около 80 000 концепций) и другую очень маленькую онтологию в магазин и добавили двух человек, один из которых имеет этот класс дополнения/ограничения.

следующий запрос занял вечность, чтобы выполнить, и я прекратил его через 15 минут:

select *
where {
  ?s a [ rdf:type owl:Class;
                      owl:complementOf [
                        rdf:type owl:Restriction ;
                        owl:onProperty roo:has_finding;
                        owl:someValuesFrom nci:Dyspnea;
                  ]
                ] .
} Limit 100

кто-нибудь знает почему? Я предположим, что этот подход создает много пустых узлов, и механизм запросов должен пройти через весь тезаурус NCI и сравнить все пустые узлы с этим?

если я помещаю эту тройку в отдельный график и только запрашиваю этот график, запрос возвращает результат мгновенно.

подводя итоги. Два основных вопроса:--13-->

  • является ли третий подход действительно лучшим для моделирования "чего-то нет"
  • Is это повлияет на производительность запросов?

правка 1

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

  • мы хотим иметь возможность заявить ,что" у пациента есть одышка "или" у пациента нет одышки " в определенный момент времени.

  • в будущем может/будет больше информации об этом пациенте, например, что теперь у него одышка.

  • мы хотим иметь возможность писать запросы Sparql, которые запрашивают "всех пациентов, у которых есть одышка" и "всех пациентов, у которых нет одышки".

  • мы хотим сохранить Sparql как можно более простым и интуитивно понятным. Например. используйте только одно свойство "has_finding", а не знать о двух свойствах (один для"has_exclusion"). Или знать о каком-то сложном пустом узле строить.

мы играли с вариантами:

  • Отрицательные Утверждения О Свойствах: это звучало как лучшее решение этой проблемы, так как мы заявляем, что один человек не связан с другим человеком на этой собственности. Проблемы в том, что мы должны создать человека одышки ради того, чтобы иметь что-то как owl:targetIndividual. И мы не можем найти способ легко запросить отрицательное утверждение, а затем пойти через все owl:sourceIndividual и owl:targetIndividual цепи. Что делает Sparql довольно длинным и накладывает бремя на человека, пишущего запрос, чтобы узнать об этом.
  • пустой узел с complementOf: мы хотели бы заявить что-то с этим, что мы не хотим заявлять. Это было бы утверждать, что "Patient1 не можете найти диспноэ". Если мы хотим, чтобы государство "Patient1 нет одышки найти сейчас (или на дату Х)". Поэтому мы не должны использовать это подход.

  • использование типов исключения / включения (Вариант 1 и 2): после более близкого взгляда предложение Джина мы считаем, что с помощью general :Exclusion и :Inclusion классы вместе только с одним свойством has_finding и предоставление человеку с одышкой типа включения/исключения является самым простым для понимания, запроса и обеспечивает достаточные способности рассуждения. Пример:

    :Patient1 a :Patient . :Dyspnea1 a :Dyspnea . :Dyspnea1 a :Exclusion. :Patient1 ex:has_finding :Dyspnea1 .

таким образом, человек написание запроса Sparql должно только знать, что:

  • есть одно свойство has_finding, который представляет намерения должным образом. Поскольку" нет одышки " технически также является находкой.
  • но просто запрос с помощью has_finding не даст достаточной информации о том, действительно ли человек имеет его или нет. Запрос также должен содержать тройку о том, является ли человек с одышкой a :Exclusion (или включения в зависимости от цели запрашивать.)
  • хотя это накладывает некоторую дополнительную нагрузку на средство записи запросов, это меньше, чем отрицательные утверждения свойств и легче понять.

мы были бы очень признательны за некоторые отзывы об этих выводах!

2 ответов


что касается вопроса моделирования, я хотел бы предложить четвертую альтернативу, которая, по сути, представляет собой сочетание ваших вариантов 1 и 2: ввести отдельный класс (иерархию) для этих "исключенных/отсутствующих" симптомов, заболеваний или методов лечения и иметь конкретные исключения в качестве примеров:

 :Exclusion a owl:Class .
 :ExcludedSymptom rdfs:subClassOf :Exclusion .
 :ExcludedTreatment rdfs:subClassOf :Exclusion .

 :excludedDyspnea a :ExcludedSymptom .
 :excludedChemo a :ExcludedTreatment .

 :Patient a owl:Class ;
          owl:equivalentClass [ a owl:Restriction ;
                                owl:onProperty :excluded ;
                                owl:allValuesFrom :Exclusion ] .

 // john is a patient without Dyspnea 
 :john a :Patient ;
       :excluded :excludedDyspnea .

дополнительно, вы можете связать экземпляры исключения семантически с лечением / симптомом / заболеваниями:

  :excludedDyspnea :ofSymptom :Dyspnea . 

на мой взгляд, это так же " онтологически правильно" (такого рода вещи довольно субъективны, чтобы быть честным), как и ваши другие варианты, и, возможно, намного проще поддерживать, запрашивать и действительно рассуждать.

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

сова имеет открытый мир предположения ,который (в широком смысле термины) означает, что мы не можем решить, что определенный факт неверен просто потому, что этот факт в настоящее время неизвестен. Ваш complementOf конструкция логически будет пустым классом, потому что для любого человека X, даже если мы в настоящее время не знаем, что X был поставлен диагноз одышка, есть вероятность, что в будущем этот факт станет известен, и поэтому X не будет в классе дополнение.

редактировать

In ответ на ваше редактирование, с предложением, используя один :hasFinding свойство, я думаю, что в целом выглядит хорошо, хотя я бы, возможно, немного изменил его:

   :patient1 a :Patient;
             :hasFinding :dyspneaFinding1 .

   :dyspneaFinding1 a :Finding ;
                    :of :Dyspnea ;
                    :conclusion false .

теперь вы отделили "нахождение" как понятие немного более чисто от симптома/лечения, что это нахождение of. Кроме того, является ли вывод положительным или отрицательным, явно моделируется (а не подразумевается наличием/отсутствием "исключенного" свойства или типа "исключения").

(в стороне: поскольку мы связываем человека с классом здесь через отношение без ввода (... :of :Dyspnea) мы должны полагаться на сова 2 каламбур чтобы сделать это действительным в OWL DL)

чтобы запросить пациента с находкой (положительной или отрицательной) о одышке:

 SELECT ?x 
 WHERE {
    ?x a :Patient; 
       :hasFinding [ :of :Dyspnea ] .
 }

и запросить пациентов с подтвержденным отсутствием одышки:

 SELECT ?x 
 WHERE {
    ?x a :Patient; 
       :hasFinding [ :of :Dyspnea ;
                     :conclusion false ] .
 }

Если ваши болезни представлены как личности, то вы можете использовать отрицательные утверждения свойств объекта, чтобы буквально сказать, например,

hasFinding (Джон,одышка)

NegativeObjectPropertyAssertion (hasFinding Джон одышка)

конечно, если у вас есть много вещей, которые не так, то это может быть немного вовлечено. Хотя, возможно, это наиболее семантически правильно. Это также означает, что ваш запрос может совпадать непосредственно с данные в онтологии, которые могут привести к более быстрым результатам. (Конечно, у вас все равно будут проблемы с попыткой вывод когда свойство отрицательного объекта выполняется.)

Это не работает, если болезни представлены в виде классов, хотя. Если болезни представлены классами, то можно использовать выражения классов, подобные тому, что вы предлагаете. Е. Г.,

(∀ hasFinding.Одышка) (Иоанн)

ClassAssertion (ObjectAllValuesFrom(Hasfinding ObjectComplementOf (одышка)) Джон)

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

Я согласен с ответ Джин, хотя; здесь много субъективности, и очень много "правильно"." на самом деле это просто вопрос поиска чего-то, с чем разумно работать, достаточно хорошо работает для вас, и это кажется не совсем неестественным.