【问题标题】:Easiest way to find relevancy between two queries查找两个查询之间相关性的最简单方法
【发布时间】:2014-03-09 08:40:49
【问题描述】:

我需要找到给定两个查询之间的相关性,例如:

Q1(Query1) = Computing

Q2(Query2) = RAM

让我们假设相关路径是这样的:

计算->个人计算机->计算机硬件->计算机组件->随机存取存储器->RAM

结果应为 5。

现在的问题是大多数像FreeBase 这样的图形数据库不支持该功能。唯一的方法是递归地将一个查询与另一个查询进行比较。

问题:是否有一种简单快捷的方法可以做到这一点,或者是否有任何图形数据库支持此功能?

请注意:这不是算法问题,我知道理论上可以通过使用DFSBFS 轻松实现,但实际上可能存在一个具有1000 条边的节点(入口) ,我不想全部遍历。

【问题讨论】:

  • 你现在有什么样的图表?
  • @alvas 我没有,这就是我问的原因。

标签: nlp ontology graph-databases


【解决方案1】:

首先,要找到图之间的距离,只需计算从一个节点到另一个节点的边数,然后制定某种量化来找到距离。可以将 freebase 实体放入图中,然后计算两个节点之间的边数。

让我们从一个更简单的资源 WordNet 开始。为简单起见,让我们使用 NLTK 的 WordNet API (http://www.nltk.org/)。您可以像这样简单地量化路径相似性 (http://www.nltk.org/_modules/nltk/corpus/reader/wordnet.html):

>>> from nltk.corpus import wordnet
>>> from nltk.corpus import wordnet as wn
>>> wn.synsets('computing')
[Synset('computer_science.n.01'), Synset('calculation.n.01'), Synset('calculate.v.01')]
>>> wn.synsets('ram')
[Synset('random-access_memory.n.01'), Synset('aries.n.01'), Synset('aries.n.03'), Synset('ram.n.04'), Synset('ram.n.05'), Synset('ram.v.01'), Synset('force.v.06'), Synset('crash.v.03'), Synset('jam.v.06')]
>>> computing = wn.synsets('computing')[0]
>>> ram = wn.synsets('ram')[0]
>>> computing.path_similarity(ram)
0.058823529411764705

请注意,使用 Wordnet 可能会导致比解决问题更多的问题;P。见

【讨论】:

  • 我看了一下freebase,第一件事是我没有足够的容量和处理能力来使用他们的整个数据库(大约250GB)。使用他们的 API 也不是一个好主意,因为某些条目甚至可能有 1000 个传出条目。所以,如果我假设所有这些条目至少有 100 个传出条目,那么我需要为深度为 3 的树处理 1000*100 = 100,000 个条目。我知道 WordNet,但我更喜欢使用 API这将为我进行计算。
【解决方案2】:

您正在寻找的是图中两个节点之间的最短路径。如果您的图表未加权,则归结为breadth first search

我假设你的相关性边缘是加权的,所以你需要an algorithm like dijkstra。由于您很可能对所有对最短路径问题感兴趣,因为您可能希望稍后查询任意两个节点之间的最短路径,您可以使用floyd Warshall algorithm。这将创建一个矩阵,其中包含所有节点对之间的所有最短路径值。

如果您将图形导入neo4j,您可以使用their floyd warshall implementation. 请注意,此算法的实现在顶点数上是三次方。所以这真的取决于你的用例选择上述哪种算法。

我附上了一些示例代码(在 neo4j 1.4 中),它显示了它是多么容易:

        CostEvaluator<Double> costEvaluator = new CostEvaluator<Double>() {

        public Double getCost(Relationship relationship, Direction direction) {
            return -Math.log((Double) relationship.getProperty(Messages
                    .getString("RelProperty.Cost")));
        }

    };
    CostAccumulator<Double> costAccumulator = new CostAccumulator<Double>() {

        public Double addCosts(Double c1, Double c2) {
            // TODO Auto-generated method stub
            return c1 + c2;
        }
    };
    Comparator<Double> costComparator = new Comparator<Double>() {

        public int compare(Double o1, Double o2) {
            // TODO Auto-generated method stub
            return o1.compareTo(o2);
        }
    };
    FloydWarshall<Double> fw = new FloydWarshall<Double>(1.0,
            Double.MIN_VALUE, Direction.OUTGOING, costEvaluator,
            costAccumulator, costComparator, this.currencySet,
            this.tradeSet);

    fw.reset();
    fw.calculate();

然后您可以使用以下命令查询图形中的任意两个节点 node1 和 node2:

fw.getCost(node1, node2)

btw 广度优先搜索也可以在 neo4j 中轻松实现,使用遍历器框架或简单的cypher query 与您的查询完全匹配

【讨论】:

  • 谢谢你,但我并没有要求高效的算法来做到这一点。我想知道我可以使用哪些词法分析工具来满足我的需求。
猜你喜欢
  • 2016-11-06
  • 2011-07-31
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-03
  • 1970-01-01
  • 2011-05-01
相关资源
最近更新 更多