Я делаю некоторые исследования алгоритмов ранжирования и хотел бы, учитывая отсортированный список и некоторую перестановку этого списка, вычислить некоторое расстояние между двумя перестановками. Для случая расстояния Левенштейна это соответствует вычислению расстояния между последовательностью и отсортированной копией этой последовательности. Существует также, например, "расстояние инверсии", алгоритм с линейным временем которого подробно описан здесь, над которым я работаю над внедрением.
Знает ли кто-нибудь о существующем внедрении python расстояния инверсии и/или оптимизации расстояния Левенштейна? Я вычисляю это на последовательности от 50 000 до 200 000 элементов, поэтому O (n ^ 2) слишком медленна, но O (n log (n)) или лучше должно быть достаточным.
Также будут оценены другие метрики для сходства подстановок.
Изменить для людей из будущего:
На основе ответа Раймонда Хеттингера; это не Левенштейн или расстояние от инверсии, а скорее "сопоставление гештальт-шаблонов": P
from difflib import SequenceMatcher
import random
ratings = [random.gauss(1200, 200) for i in range(100000)]
SequenceMatcher(None, ratings, sorted(ratings)).ratio()
работает на ~ 6 секунд на страшном рабочем столе.
Edit2: Если вы можете принудить свою последовательность к перестановке [1.. n], то вариация манхэттенской метрики чрезвычайно быстра и имеет некоторые интересные результаты.
manhattan = lambda l: sum(abs(a - i) for i, a in enumerate(l)) / (0.5 * len(l) ** 2)
rankings = list(range(100000))
random.shuffle(rankings)
manhattan(rankings) # ~ 0.6665, < 1 second
Нормализующий коэффициент технически является приближением; это правильно для даже размерных списков, но должно быть (0.5 * (len(l) ** 2 - 1))
для списков нечетного размера.
Edit3: Существует несколько других алгоритмов для проверки сходства списков! коэффициент рейтинга Кендалла Тау и Spearman коэффициент ранжирования. Реализации их доступны в библиотеке SciPy как scipy.stats.kendalltau
и scipy.stats.rspearman
и возвращают ранги вместе с ассоциированным p -величины.