查找(解析)树集合中最常见的子树

时间:2009-11-06 03:30:38

标签: algorithm tree subtree

我有一组树的节点被标记(但不是唯一的)。具体来说,树来自一组解析过的句子(见http://en.wikipedia.org/wiki/Treebank)。我希望从集合中提取最常见的子树 - 性能不是(还)一个问题。我要感谢算法(理想情况下是Java)或指向为树库执行此操作的工具的指针。请注意,子节点的顺序很重要。

编辑 @mjv。我们正在一个有限的领域(化学)工作,这个领域有一种程式化的语言,所以树木的数量并不大 - 可能与儿童的读者类似。 “猫坐在垫子上”的简单树。

<sentence>
  <nounPhrase>
    <article/>
    <noun/>
  </nounPhrase>
  <verbPhrase>
    <verb/>
    <prepositionPhrase>
      <preposition/>
      <nounPhrase>
        <article/>
        <noun/>
      </nounPhrase>
    </prepositionPhrase>
  </verbPhrase>
</sentence>

这里的句子包含两个相同的词性小树(实际的标记“cat”。“mat”在匹配时并不重要)。所以算法需要检测到这一点。请注意,并非所有nounPhrases都相同 - “大黑猫”可能是:

      <nounPhrase>
        <article/>
        <adjective/>
        <adjective/>
        <noun/>
      </nounPhrase>

句子的长度会更长 - 在15到30个节点之间。我希望从1000棵树中获得有用的结果。如果这不超过一天左右,那是可以接受的。

显然,树越短越频繁,因此名词Phhrase将非常普遍。

编辑如果要通过展平树来解决这个问题,那么我认为它与最长公共子串相关,而不是最长公共序列。但请注意,我不一定只想要最长的 - 我想要一个足够长的列表,以便“有趣”(标准尚未确定)。

4 个答案:

答案 0 :(得分:3)

我认为,虽然你说性能还不是问题,但这是一个NP难题,所以永远不可能让它变得快速。如果我理解正确,您可以将此视为Longest common subsequence问题的变体;如果你将你的树变成像

这样的直线序列
(nounphrase)(DOWN)(article:the)(adjective:big)(adjective:black)(noun:cat)(UP)

然后你的问题变成了LCS。

Wikibooks有一个LCS here

的java实现

答案 1 :(得分:3)

在集合中查找最常见的子树,创建子树的紧凑形式,然后迭代每个子树并使用哈希集来计算它们的出现次数。 30个节点对于完美的哈希来说太大了 - 每个节点只有大约一位,你需要那么多来表明它是兄弟姐妹还是孩子。

该问题不是LCS - 最常见的序列与最长的公共子序列无关。最常见的子树是发生最多的子树。

对于长度为L的N个树,最坏情况应为O(N L ^ 2)(假设测试包含L个节点的子树的相等性是O(L))。

答案 2 :(得分:2)

这是计算机科学中一个众所周知的问题,有效的解决方案。

以下是一些相关的参考资料:

Kenji Abe,Shinji Kawasoe,Tatsuya Asai,Hiroki Arimura,Setsuo Arikawa,半结构化数据的优化子结构发现,Proc。第六届欧洲数据库知识发现原理与实践会议(PKDD-2002),LNAI 2431,Springer-Verlag,2002年8月1日至14日。

Mohammed J. Zaki,在森林中有效挖掘频繁树木,第八届ACM SIGKDD知识发现和数据挖掘国际会议,2002年7月。

或者,如果您只想要快速代码,请转到此处: FREQT (将xml转换为S表达式不应该给你带来太多问题,并留给读者练习)

答案 3 :(得分:1)

在这种情况下,我发现名为gspan的工具非常有用。可在http://www.cs.ucsb.edu/~xyan/software/gSpan.htm免费下载。它的带有matlab接口的c ++版本位于http://www.nowozin.net/sebastian/gboost/