kgdiff 如何区分各种变化
在说出一个节点被改名、移动还是合并之前,kgdiff 先要确定新版本里的每个节点对应旧版本里的哪个节点。差异结果里的大多数意外都来自这一步配对。本页逐一回答审阅者最常问的问题,说明 kgdiff 在每种情况下怎么做。每个例子都用命令行实际跑过;精确的规则见 Algorithms(英文)。
配对是怎么做的
- id 相同的节点先配对(
--match id和默认的auto)。 - 替代声明把一个节点和替代它的节点配成一对:OBO 的
replaced_by和alt_id,RDF 的IAO:0100001,kgdiff JSON 的replacedBy/replaces。 - 相似度为剩下的节点配对(
auto),或者为全部节点配对(--match similarity,适用于每次运行 id 都会变的图)。得分里名称的权重最大(55%),其次是已经配上的邻居(25%)、类型(10%)和属性(10%)。一对节点要达到--threshold(默认 0.82),并且比每个竞争者至少高 0.05,才会被接受。
配对是一对一的。没有配上的节点会被报告为删除或新增。差一点配上的一对,即得分在 0.6 和阈值之间、或者和竞争者不相上下,会作为可能的匹配列出:在终端摘要和 Markdown 摘要的最后,以及查看器的详情面板里。
是改名,还是删除加新增?
两次抽取把同一家公司分别叫作“Saudi Aramco”和“Aramco”,id 是新生成的,四个邻居相同。两个名称只有一个词相同,所以这一对得分 0.80,刚好低于阈值:
删除 1
− 删除「Saudi Aramco」及 3 条关系 删除 · 类型 Organization · 原关联 …
…
新增 1
+ 新增「Aramco」及 3 条关系 新增 · 类型 Organization · 关联 …
可能的匹配 1
≈ 「Saudi Aramco」→「Aramco」 80% · 低于阈值 82% · 名称 67% · 邻居 100%kgdiff 不会去猜:它只报告能确定的结论,把这一对留给审阅者判断。下面任意一种做法都能让它成为改名(~ 「Saudi Aramco」改名为「Aramco」):
- 新版本把旧名称保留为别名(
aliases、skos:altLabel、OBO 的synonym); - 用替代声明指向旧节点;
- 调低
--threshold,这里是0.79。它对所有节点对都生效,调低时要谨慎。
是改名,还是合并?
改名是标签发生变化的一对节点。合并需要的不只是共享邻居。要么有替代声明明确指出合并目标,要么同时满足两点:旧节点的名称与目标的名称几乎相同,或者被保留为目标的别名;并且旧节点至少一半的关系现在连到了目标上。这些证据的置信度必须达到 0.75;更弱的情况会列出来交给审阅者,而不会报告为合并。
同一次修改里既改名又移动
id 稳定时,一个节点同时改了名称和上级,会显示为一处变化:
~ 「Customer Support」改名为「Customer Success」 内容 · 移至「Sales」下如果 id 也是新生成的,而名称和邻居又都变了,就没有任何证据表明它还是同一个节点,因此会被报告为删除加新增。保持 id 稳定,或者写上替代声明,才能让这样的变化保持可读。
同名的不同事物
两个版本里都有“Apple”公司和“Apple”水果时,类型和邻居会把它们区分开:各自和自己的对应节点配对;之后删掉水果,也不会把它当成并入了公司。
如果每个版本只有一个“Mercury”,变更前是行星、变更后是化学元素,两者名称相同、类型却不一致。kgdiff 不会只凭名称就把它们配成一对,而是等它们的邻居配好之后再判断;使用 --match similarity、所有节点都从零开始配对时也是如此。两者的邻居同样不一致(行星绕太阳运行,元素的符号是 Hg),所以这一对只会成为可能的匹配。因为名称相同,两侧都附上了各自的 id:
≈ 「Mercury」(m1)→「Mercury」(x1) 61% · 低于阈值 82% · 名称 100% · 邻居 0%邻居能印证的类型变化仍然算作一处变化:一个仍然绕太阳运行、只是类型改了名的“Mercury”,会显示为 ~ 修改「Mercury」的类型。
对称的图
名称重复、结构又对称时,几种配对方式一样好。kgdiff 拒绝从中挑一个。六个都叫“C”的原子,在一个版本里连成一个环,在另一个版本里连成两个三角形,id 是新生成的:每一对候选都不相上下,因此一对也不接受。环被报告为删除,两个三角形被报告为新增,这些不相上下的节点对则作为“与其他候选过于接近”的可能的匹配列出。
移动和含义的变化
- 层级中的移动是单独的一类变化:结构调整,使用结构的颜色,排在其他修改之前。改名和属性修改属于内容。哪些关系算作层级由
--hierarchy决定(默认包括subClassOf、is_a、skos:broader等)。 - 改写后的定义是一次属性变化。摘要会把它标记为 ⚑ 优先审查(
内容 · ⚑ 定义 · 属性 ~1),查看器则在节点的详情面板里把它显示为字符级的差异。用--watch-attr可以指定其他需要标记的属性。 - kgdiff 不判断含义是否发生了偏移。它让这类修改清楚可见,把判断留给审阅者。