Ontology,OWL,Sparql:建模"某些东西不在那里"和性能考虑因素

时间:2015-06-16 20:52:46

标签: performance sparql modeling ontology sesame

我们希望模拟那些"某些东西不在那里"而不是缺少信息,例如一个明确的陈述,即患者未接受化疗"或那个"患者没有呼吸困难"不同于关于患者是否患有呼吸困难的缺失信息。

我们考虑了几种方法,例如

  • 使用否定类:" No_Dyspnea"。但这似乎在语义上有问题,因为那个类会是什么类型的?它不能成为" Dyspnea"的后代。类。
  • 使用"不在那里"对象属性,例如"否认"或"确认不是"然后是呼吸困难根类的个体作为该三联的对象。
  • 使用空白节点描述个人属于没有呼吸困难的事物。 E.g:

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

我们觉得第三种选择是最本的"本体论正确的"表达这一点的方式。但是,在使用它时,我们在简单的场景中遇到了严重的性能问题。

我们将Sesame与OWLIM-Lite商店一起使用,并将NCI词库(280MB,约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词库并将所有空白节点与此进行比较?

如果我将此三元组放在单独的图形中并且只查询该图形,则查询会立即返回结果。

总结一下。两个基本问题是:

  • 第三种方法真的是最适合建模的吗?有些东西不存在"
  • 这是否会影响查询效果?

编辑1

我们讨论了提议的选项。它实际上帮助我们澄清了我们真正想要实现的目标:

  • 我们希望能够说明"患者有呼吸困难"或者"患者没有呼吸困难"在某一特定时间点。

  • 将来可能/将会有关于该患者的更多信息,例如他/她现在有呼吸困难。

  • 我们希望能够编写Sparql查询,要求"所有患有呼吸困难的患者"和#34;所有没有呼吸困难的患者"。

  • 我们希望Sparql尽可能简单直观。例如。只使用一个属性" has_finding"而不是必须知道两个属性(一个用于" has_exclusion")。或者必须了解一些复杂的空白节点构造。

我们玩了很多选项:

  • 否定属性断言:这听起来像是解决此问题的最佳解决方案,因为我们声明一个人与该属性上的另一个人无关。问题是我们必须创建一个呼吸困难的个体,以便拥有owl:targetIndividual的东西。而且我们找不到一种方法来轻松查询负面断言,然后遍历整个owl:sourceIndividualowl:targetIndividual链。这使得Sparql非常冗长,给编写查询的人带来了负担。
  • 有补充的空白节点:我们会说明我们不想陈述的内容。这将表明"患者1永远不会发现呼吸困难"。然而,我们想要声明"患者1现在没有发现呼吸困难(或在第X天)"。所以我们不应该使用这种方法。

  • 使用排除/包含类型(选项1和2):仔细查看Jeen的建议后,我们认为使用常规:Exclusion和{{ 1}}类以及仅一个属性:Inclusion并且给予呼吸困难个体包含/排除类型是最容易理解,查询并提供足够的推理能力。例如:

    has_finding

这样,编写Sparql查询的人只需要知道:

  • 有一个属性:Patient1 a :Patient . :Dyspnea1 a :Dyspnea . :Dyspnea1 a :Exclusion. :Patient1 ex:has_finding :Dyspnea1 .,它正确表示意图。因为"没有呼吸困难"在技​​术上也是一个发现。
  • 但仅使用has_finding查询将无法提供有关此人是否确实拥有该信息的充分信息。查询还需要包含关于呼吸困难个体是has_finding(或包含取决于查询目标)的三元组。
  • 虽然这给查询编写者带来了额外的负担,但它比负面的属性断言更容易理解。

我们非常感谢对这些结论的一些反馈!

2 个答案:

答案 0 :(得分:3)

如果您的疾病被表示为个体,那么您可以使用负面对象属性断言来逐字地说,例如,

¬hasFinding(john,Dyspnea)

NegativeObjectPropertyAssertion(hasFinding john Dyspnea)

当然,如果你有很多事情并非如此,那么这可能会涉及到一些问题。不过,这可能是最具语义正确性的。这也意味着您的查询可以直接与本体中的数据匹配,这可能会使结果更快。 (当然,当负面对象属性成立时,你仍然会遇到尝试推断的问题。)

但是,如果将疾病表示为类,则不起作用。如果疾病由类表​​示,那么您可以使用类表达式,类似于您的建议。例如,

(∀hasFinding.¬Dyspnea)(约翰)

ClassAssertion(ObjectAllValuesFrom(hasFinding ObjectComplementOf(Dyspnea))john)

这与您的第三个选项类似,但我想知道它是否会表现得更好。这似乎是一种更直接的方式来表达你想说的话(即,如果某人有疾病,那就不是这些疾病之一)。

我同意Jeen's answer;这里有很多主观性,并且很多让它“正确”的实际上只是找到一些合理的东西,对你来说表现得足够好,这似乎并不完全不自然。

答案 1 :(得分: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的构造在计算上都很重,但也许更重要的是,它可能会不捕捉你想要的东西。

OWL有一个开放的世界假设,(从广义上讲)意味着我们无法仅仅因为这个事实是未知的而决定某个事实是不真实的。您的complementOf构造在逻辑上将是一个空类,因为对于任何个人X,即使我们当前不知道X已被诊断为呼吸困难,也有的可能性在将来,这个事实将成为已知,因此X将不在补充类中。

修改

为了回应您的修改,使用单个:hasFinding属性的提案,我认为通常看起来不错,但我可能会略微修改它:

   :patient1 a :Patient;
             :hasFinding :dyspneaFinding1 .

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

现在,你已经将“发现”作为一个概念与一个发现 的症状/治疗分开了。此外,该发现是肯定的还是否定的是明确建模的(而不是暗示“排除的”属性或“排除”类型的存在/缺失)。

(顺便说一句:因为我们通过非打字关系(... :of :Dyspnea)将个人与班级联系起来,所以我们必须依靠OWL 2 punning使其在OWL DL中有效

查询有关呼吸困难的发现(无论是阳性还是阴性)的患者:

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

并查询已证实缺乏呼吸困难的患者:

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