Реальная проблема:
У меня есть данные о директорах многих фирм, но иногда «Джон Смит, директор XYZ» и «Джон Смит, директор ABC» — это одно и то же лицо, а иногда — разные. Также «Джон Дж. Смит, директор XYZ» и «Джон Смит, директор ABC» могут быть одним и тем же человеком, а могут и не быть. Часто изучение дополнительной информации (например, сравнение биографических данных о «Джоне Смите, директоре XYZ» и «Джоне Смите, директоре ABC») позволяет решить, относятся ли два наблюдения к одному и тому же человеку или нет.
Концептуальная версия проблемы:
В этом духе я собираю данные, которые позволят идентифицировать совпадающие пары. Например, предположим, что у меня есть следующие совпадающие пары: {(a, b), (b, c), (c, d), (d, e), (f, g)}
. Я хочу использовать свойство транзитивности отношения «это тот же человек, что и» для создания «связанных компонентов» {{a, b, c, d, e}, {f, g}}
. То есть {a, b, c, d, e}
— это один человек, а {f, g}
— другой. (В более ранней версии вопроса упоминались «клики», которые, по-видимому, являются чем-то другим; это объясняет, почему find_cliques
в networkx
давал «неправильные» результаты (для моих целей).
Следующий код Python выполняет эту работу. Но мне интересно: есть ли лучший (менее затратный в вычислительном отношении) подход (например, использование стандартных или доступных библиотек)?
Здесь и там есть примеры, которые кажутся связанными (например, Cliques в python), но они неполные, поэтому я не уверен, на какие библиотеки они ссылаются или как настроить мои данные для их использования.
Пример кода Python 2:
def get_cliques(pairs):
from sets import Set
set_list = [Set(pairs[0])]
for pair in pairs[1:]:
matched=False
for set in set_list:
if pair[0] in set or pair[1] in set:
set.update(pair)
matched=True
break
if not matched:
set_list.append(Set(pair))
return set_list
pairs = [('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('f', 'g')]
print(get_cliques(pairs))
Это дает желаемый результат: [Set(['a', 'c', 'b', 'e', 'd']), Set(['g', 'f'])]
.
Пример кода Python 3:
Это производит [set(['a', 'c', 'b', 'e', 'd']), set(['g', 'f'])]
):
def get_cliques(pairs):
set_list = [set(pairs[0])]
for pair in pairs[1:]:
matched=False
for a_set in set_list:
if pair[0] in a_set or pair[1] in a_set:
a_set.update(pair)
matched=True
break
if not matched:
set_list.append(set(pair))
return set_list
pairs = [('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('f', 'g')]
print(get_cliques(pairs))
if not matched
наelse
(else
в этом случае означает, что for достигло условия выхода) - person njzk2   schedule 15.01.2015a
иc
не связаны. - person njzk2   schedule 15.01.2015