本体,OWL,Sparql:建模"某些东西不存在"和性能考虑因素

Wol*_*ang 6 performance modeling sesame ontology sparql

我们想模拟"某些东西不在那里",而不是缺少信息,例如"患者未接受化疗"或"患者没有呼吸困难"的明确陈述与缺少患者是否有患者的信息不同呼吸困难.

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

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

    dat:PatientW2 a [ rdf:type owl:Class;
                  owl:complementOf [
                    rdf:type owl:Restriction ;
                        owl:onProperty roo:has_finding;
                        owl:someValuesFrom nci:Dyspnea;
                  ]
                ] .
    
    Run Code Online (Sandbox Code Playgroud)

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

我们将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
Run Code Online (Sandbox Code Playgroud)

有人知道为什么吗?我会假设这种方法会创建大量空白节点,并且查询引擎必须通过整个NCI词库并将所有空白节点与此进行比较?

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

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

  • 第三种方法真的是最好的建模"有些东西不存在"
  • 这会影响查询性能吗?

编辑1

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

  • 我们希望能够在特定时间点陈述"患者有呼吸困难"或"患者没有呼吸困难".

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

  • 我们希望能够编写Sparql查询,询问"所有患有呼吸困难的患者"和"所有没有呼吸困难的患者".

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

我们玩弄了各种选择:

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

  • 使用排除/包含类型(选项1和2):仔细观察Jeen的建议后,我们认为使用一般: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(或包含取决于查询目标)的三元组.
  • 虽然这给查询编写器带来了一些额外的负担,但它比负面的属性断言更容易理解.

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

Jee*_*tra 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 .
Run Code Online (Sandbox Code Playgroud)

或者,您可以将排除实例与治疗/症状/疾病进行语义链接:

  :excludedDyspnea :ofSymptom :Dyspnea . 
Run Code Online (Sandbox Code Playgroud)

在我看来,这与您的其他选择一样“本体论上正确”(老实说,这种事情相当主观),并且可能更容易维护、查询和推理。

至于你的第二个问题:虽然我不能说出你正在使用的特定推理器的行为,但一般来说,任何涉及的构造在complementOf计算上都非常繁重,但也许更重要的是,它可能无法捕获你的意图。

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

编辑

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

   :patient1 a :Patient;
             :hasFinding :dyspneaFinding1 .

   :dyspneaFinding1 a :Finding ;
                    :of :Dyspnea ;
                    :conclusion false .
Run Code Online (Sandbox Code Playgroud)

您现在已经将“发现”作为一个概念与它所发现的症状/治疗更加清晰地分开了。此外,无论结果是肯定的还是否定的,都会明确建模(而不是通过“排除”属性或“排除”类型的存在/不存在来暗示)。

(顺便说一句:由于我们通过非类型关系 ( ... :of :Dyspnea) 将个体与类链接在一起,因此我们必须依靠OWL 2 双关语才能使其在 OWL DL 中有效)

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

 SELECT ?x 
 WHERE {
    ?x a :Patient; 
       :hasFinding [ :of :Dyspnea ] .
 }
Run Code Online (Sandbox Code Playgroud)

并查询确认无呼吸困难的患者:

 SELECT ?x 
 WHERE {
    ?x a :Patient; 
       :hasFinding [ :of :Dyspnea ;
                     :conclusion false ] .
 }
Run Code Online (Sandbox Code Playgroud)