Является ли совпадение маршрута в текстовом режиме коммутативным?

Я использую API-интерфейс wordnet от nltk. Когда я сравниваю один synset с другим, я получил None, но когда я сравниваю их, я получаю значение float.

Разве они не должны давать одинаковое значение? Есть ли объяснение или это ошибка в 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

Ответы

Ответ 1

Технически без фиктивного корня оба синтаксиса car и automobile не имеют никакой связи друг с другом:

>>> 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 есть аккуратная функция, которая говорит, нужен ли synset фиктивный корень:

>>> 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 этот параметр simulate_root=simulate_root and self._needs_root() всегда будет True при попытке y.path_similarity(x), и при попытке 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 = True, синхронизация automobile не будет подключаться к 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.corpus.wordnet.path_similarity() в API NLTK не является коммутативным.

НО код также не ошибочен/прослушивается, так как сравнение любого расстояния между синхронизацией путем прохождения корня будет постоянно далеким, так как положение манекена *ROOT* никогда не изменится, поэтому лучше всего это сделать для вычисления path_similarity:

>>> 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))

Ответ 2

Я не думаю, что это ошибка в 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