2

我正在将我的数据加载到 TDB 模型中,并使用 Jena 编写了一些规则以应用于 TDB。然后我将推断的数据存储到一个新的 TDB 中。

我在一个约 200kb 的小数据集中应用了上面的案例,并且措辞很好。但是,我的实际 TDB 是 2.7G,计算机已经运行了大约一周,实际上它仍在运行。

这是正常的,还是我做错了什么?耶拿规则引擎的替代品是什么?

这是一小段代码:

public class Ruleset {
  private List<Rule> rules = null; 
  private GenericRuleReasoner reasoner = null;

  public Ruleset (String rulesSource){
    this.rules = Rule.rulesFromURL(rulesSource);
    this.reasoner = new GenericRuleReasoner(rules);
    reasoner.setOWLTranslation(true);           
    reasoner.setTransitiveClosureCaching(true);
  }

  public InfModel applyto(Model mode){
    return ModelFactory.createInfModel(reasoner, mode);
  }

  public static void main(String[] args) {
    System.out.println(" ... Running the Rule Engine ...");
    String rulepath = "src/schemaRules.osr";
    Ruleset rule = new Ruleset (rulepath);
    InfModel infedModel = rule.applyto(data.tdb);
    infdata.close();
  }
}
4

2 回答 2

2

持久存储中的大型数据集与 Jena 的规则系统不匹配。基本问题是RETE 引擎会在规则传播过程中对图进行许多小查询。正如您所发现的,对任何持久性存储(包括 TDB)进行这些查询的开销往往会使执行时间长得令人无法接受。

根据您使用推理的目标,您可能有一些选择:

  • 将数据加载到足够大的内存图中,然后将推理闭包(基本图加上蕴含)保存到单个事务中的 TDB 存储中。此后,您可以查询商店而不会产生规则系统的开销。显然,更新可能是这种方法的一个问题。

  • 像现在一样将您的数据保存在 TDB 中,但将一个子集动态加载到内存模型中,以便与推理一起使用。使更新更容易(只要您同时更新内存副本和持久存储),但需要您对数据进行分区。

如果您只想要一些基本的推理,例如rdfs:subClassOf层次结构的闭包,您可以使用infer命令行工具生成一个推理闭包,您可以将其加载到 TDB 中:

$ infer -h
infer --rdfs=vocab FILE ...
General
  -v   --verbose         Verbose
  -q   --quiet           Run with minimal output
  --debug                Output information for debugging
  --help
  --version              Version information

Infer 可以更高效,因为它不需要大内存模型。但是,它受限于它将计算的推论。

如果这些都不适合您,您可能需要考虑商业推理引擎,例如OWLIMStardog

于 2013-07-12T08:50:27.330 回答
0

谢谢伊恩。

我实际上能够按照 DAVE 的建议通过 SPARQL 更新来完成这项工作,并且只用了 10 分钟就完成了这项工作。

以下是代码示例:

System.out.println(" ... Load rules ...");
    data.startQuery();
    String query = data.loadQuery("src/sparqlUpdatesRules.tql");
    data.endQuery();

    System.out.println(" ... Inserting rules ...");
    UpdateAction.parseExecute(query, inferredData.tdb);

    System.out.println(" ... Printing RDF ...");
    inferredData.exportRDF();

    System.out.println(" ... closeing  ...");
    inferredData.close();

这是 SPARQL 更新的示例:

INSERT {
   ?w ddids:carries ?p .
} WHERE {
   ?p ddids:is_in ?w .
}; 

谢谢你的回答

于 2013-07-16T21:07:36.913 回答