【问题标题】:Is wordnet path similarity commutative?wordnet 路径相似性是可交换的吗?
【发布时间】:2013-12-03 05:30:16
【问题描述】:

我正在使用来自 nltk 的 wordnet API。 当我将一个同义词集与另一个比较时,我得到了None,但是当我反过来比较它们时,我得到一个浮点值。

他们不应该给出相同的值吗? 有没有解释或者这是wordnet的错误?

例子:

wn.synset('car.n.01').path_similarity(wn.synset('automobile.v.01')) # None
wn.synset('automobile.v.01').path_similarity(wn.synset('car.n.01')) # 0.06666666666666667

【问题讨论】:

    标签: python nlp nltk wordnet


    【解决方案1】:

    我不认为这是 wordnet 本身的错误。在您的情况下,汽车被指定为动词,汽车被指定为名词,因此您需要查看同义词集以查看图表的外观并确定网络是否正确标记。

    A = 'car.n.01'
    B = 'automobile.v.01'
    C = 'automobile.n.01'
    
    
    wn.synset(A).path_similarity(wn.synset(B)) 
    wn.synset(B).path_similarity(wn.synset(A)) 
    
    
    wn.synset(A).path_similarity(wn.synset(C)) # is 1
    wn.synset(C).path_similarity(wn.synset(A)) # is also 1
    

    【讨论】:

    • 在path_similarity中有一个默认变量simulate_root=True,它在分类树中创建一个虚拟根,因此动词和名词可以相互连接,因此函数应该总是返回一个值。如果我们不创建虚拟词根,那么动词和名词总是不会相互连接,例如wn.synset(A).path_similarity(wn.synset(B), simulation_root=False)) # 无
    • 同样path_similarity的定义方式没有考虑边的方向,它是:1/(1+length_of_shortest_path(A,B))
    • 感谢您的这些cmets。我会相应地更新我的答案
    • 其实wn.synset('car.n.01')和wn.synset('automobile.n.01')指的是同一个synset。这就是为什么它们的路径相似度为1。尝试:>>> wn.synsets('automobile'),您会看到它。
    【解决方案2】:

    从技术上讲,如果没有虚拟根,carautomobile 同义词集将没有相互链接:

    >>> from nltk.corpus import wordnet as wn
    >>> x = wn.synset('car.n.01')
    >>> y = wn.synset('automobile.v.01')
    >>> print x.shortest_path_distance(y)
    None
    >>> print y.shortest_path_distance(x)
    None
    

    现在,让我们仔细看看虚拟根问题。首先,NLTK 中有一个简洁的函数可以说明同义词集是否需要虚拟根:

    >>> x._needs_root()
    False
    >>> y._needs_root()
    True
    

    接下来,当你查看path_similarity代码(http://nltk.googlecode.com/svn-/trunk/doc/api/nltk.corpus.reader.wordnet-pysrc.html#Synset.path_similarity)时,你可以看到:

    def path_similarity(self, other, verbose=False, simulate_root=True):
      distance = self.shortest_path_distance(other, \
                   simulate_root=simulate_root and self._needs_root())
    
      if distance is None or distance < 0:
        return None
      return 1.0 / (distance + 1)
    

    所以对于automobile synset,当您尝试y.path_similarity(x) 时,此参数simulate_root=simulate_root and self._needs_root() 将始终为True,而当您尝试x.path_similarity(y) 时,它将始终为False,因为x._needs_root()False

    >>> True and y._needs_root()
    True
    >>> True and x._needs_root()
    False
    

    现在当path_similarity() 传递给shortest_path_distance() (https://nltk.googlecode.com/svn/trunk/doc/api/nltk.corpus.reader.wordnet-pysrc.html#Synset.shortest_path_distance) 然后传递给hypernym_distances() 时,它将尝试调用上位词列表来检查它们的距离,没有simulate_root = Trueautomobile synset 不会连接到car,反之亦然:

    >>> y.hypernym_distances(simulate_root=True)
    set([(Synset('automobile.v.01'), 0), (Synset('*ROOT*'), 2), (Synset('travel.v.01'), 1)])
    >>> y.hypernym_distances()
    set([(Synset('automobile.v.01'), 0), (Synset('travel.v.01'), 1)])
    >>> x.hypernym_distances()
    set([(Synset('object.n.01'), 8), (Synset('self-propelled_vehicle.n.01'), 2), (Synset('whole.n.02'), 8), (Synset('artifact.n.01'), 7), (Synset('physical_entity.n.01'), 10), (Synset('entity.n.01'), 11), (Synset('object.n.01'), 9), (Synset('instrumentality.n.03'), 5), (Synset('motor_vehicle.n.01'), 1), (Synset('vehicle.n.01'), 4), (Synset('entity.n.01'), 10), (Synset('physical_entity.n.01'), 9), (Synset('whole.n.02'), 7), (Synset('conveyance.n.03'), 5), (Synset('wheeled_vehicle.n.01'), 3), (Synset('artifact.n.01'), 6), (Synset('car.n.01'), 0), (Synset('container.n.01'), 4), (Synset('instrumentality.n.03'), 6)])
    

    所以理论上,正确的path_similarity是0 / None,但是因为simulate_root=simulate_root and self._needs_root()参数,

    NLTK API 中的nltk.corpus.wordnet.path_similarity() 不可交换。

    但是代码也没有错误/错误,因为通过根来比较任何同义词集距离将一直很远,因为虚拟*ROOT* 的位置永远不会改变,所以最好的做法是这样做计算路径相似度:

    >>> from nltk.corpus import wordnet as wn
    >>> x = wn.synset('car.n.01')
    >>> y = wn.synset('automobile.v.01')
    
    # When you NEVER want a non-zero value, since going to 
    # the *ROOT* will always get you some sort of distance 
    # from synset x to synset y
    >>> max(wn.path_similarity(x,y), wn.path_similarity(y,x))
    
    # when you can allow None in synset similarity comparison
    >>> min(wn.path_similarity(x,y), wn.path_similarity(y,x))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-04
      • 1970-01-01
      • 2013-03-25
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 2016-09-14
      相关资源
      最近更新 更多