我们希望模拟那些"某些东西不在那里"而不是缺少信息,例如一个明确的陈述,即患者未接受化疗"或那个"患者没有呼吸困难"不同于关于患者是否患有呼吸困难的缺失信息。
我们考虑了几种方法,例如
使用空白节点描述个人属于没有呼吸困难的事物。 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:sourceIndividual
和owl: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
(或包含取决于查询目标)的三元组。我们非常感谢对这些结论的一些反馈!
答案 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
的构造在计算上都很重,但也许更重要的是,它可能会不捕捉你想要的东西。
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 ] .
}