查找两个查询之间的相关性的最简单方法

时间:2014-03-09 08:40:50

标签: nlp ontology graph-databases

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

Q1(Query1) = Computing

Q2(Query2) = RAM

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

  

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

结果应为5。

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

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

请注意:这不是一个算法问题,我知道在理论上使用DFSBFS可以轻松实现这一点,但是当涉及到现实时,可能会有一个节点(条目)有1000条边,我不想遍历它。

2 个答案:

答案 0 :(得分:0)

首先,为了找到图之间的距离,只需计算从一个节点到另一个节点的边数,然后制定某种量化来找到距离。可以将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.见

答案 1 :(得分:0)

您要查找的是图表中两个节点之间的最短路径。如果您的图表未加权,则归结为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)
通过使用遍历框架或简单的cypher query

,btw广度优先搜索也可以在neo4j中轻松实现与您的查询完全匹配