Я ищу алгоритм сходства строк, который дает лучшие результаты для строк переменной длины, чем те, которые обычно предлагаются (расстояние Левенштейна, Саундекс и т. Д.).
Например,
Заданная строка A: «Роберт»,
Затем строка B: «Эми Робертсон»
будет лучше, чем
Строка C: «Ричард»
Также, предпочтительно, этот алгоритм должен быть независимым от языка (также работает на языках, отличных от английского).
string-matching
ranking
similarity
fuzzy-search
Марзаган
источник
источник
Ответы:
Саймон Уайт из Catalysoft написал статью об очень умном алгоритме, который сравнивает смежные пары символов, который действительно хорошо подходит для моих целей:
http://www.catalysoft.com/articles/StrikeAMatch.html
У Саймона есть версия алгоритма на Java, и ниже я написал его версию на PL / Ruby (взято из простой рубиновой версии, сделанной в соответствующем комментарии к записи на форуме Марка Вонга-ВанХарена), чтобы я мог использовать его в своих запросах PostgreSQL:
Работает как шарм!
источник
string_similarity("vitamin B", "vitamin C") #=> 1
есть ли простой способ предотвратить такое поведение?Ответ Марзагао великолепен. Я преобразовал это в C #, таким образом я думал, что отправлю это здесь:
Pastebin Link
источник
(2.0 * intersection) / union
- я получаю Double.NaN при сравнении двух пустых строк.Вот еще одна версия ответа Марзагао , написанная на Python:
источник
Вот моя PHP-реализация предложенного алгоритма StrikeAMatch от Саймона Уайта. Преимущества (как сказано в ссылке):
Истинное отражение лексического сходства - строки с небольшими различиями следует признать сходными. В частности, значительное совпадение подстрок должно указывать на высокий уровень сходства между строками.
Устойчивость к изменениям порядка слов - две строки, которые содержат одинаковые слова, но в другом порядке, должны распознаваться как сходные. С другой стороны, если одна строка является просто случайной анаграммой символов, содержащихся в другой, то она должна (обычно) распознаваться как разнородная.
Независимость от языка - алгоритм должен работать не только на английском, но и на разных языках.
источник
Укороченная версия ответа Джона Ратледжа :
источник
intersection
переменная является пустой строкой.Это обсуждение было действительно полезным, спасибо. Я преобразовал алгоритм в VBA для использования с Excel и написал несколько версий функции рабочего листа, одну для простого сравнения пары строк, другую для сравнения одной строки с диапазоном / массивом строк. Версия strSimLookup возвращает либо последнее наилучшее совпадение в виде строки, индекса массива или показателя сходства.
Эта реализация приводит к тем же результатам, что и в примере Amazon на веб-сайте Саймона Уайта, с несколькими небольшими исключениями в матчах с низким баллом; Я не уверен, где возникает разница, может быть функция Split VBA, но я не исследовал, так как она отлично работает для моих целей.
источник
Извините, ответ не был придуман автором. Это хорошо известный алгоритм, который впервые был представлен корпорацией Digital Equipment Corporation, и его часто называют «дребезжащий».
http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-TN-1997-015.pdf
источник
Я перевел алгоритм Саймона Уайта на PL / pgSQL. Это мой вклад.
источник
Метрики сходства строк содержат обзор многих различных метрик, используемых при сравнении строк (в Википедии также есть обзор). Большая часть этих метрик реализована в библиотеке симметрик .
Еще одним примером метрики, не включенной в данный обзор, является, например, расстояние сжатия (попытка приблизиться к сложности Колмогорова ), которое можно использовать для более длинных текстов, чем тот, который вы представили.
Вы могли бы также рассмотреть более широкий предмет Обработки естественного языка . Эти пакеты R могут быстро начать работу (или, по крайней мере, дать некоторые идеи).
И последнее изменение - поиск других вопросов по этой теме в SO, есть довольно много связанных вопросов.
источник
Более быстрая версия алгоритма на PHP:
Для данных я имел (приблизительно 2300 сравнений) У меня было время работы 0.58sec с Игаль Алкон раствора по сравнению с 0.35sec с моим.
источник
Версия в красивой Scala:
источник
Вот версия R:
источник
POSTING ответ Марзагана в в C99, вдохновленный эти алгоритмы
Некоторые тесты, основанные на оригинальной статье :
источник
Основываясь на удивительной версии C # от Michael La Voie, согласно просьбе сделать это методом расширения, вот что я придумал. Основное преимущество такой работы заключается в том, что вы можете сортировать общий список по процентному совпадению. Например, предположим, что в вашем объекте есть строковое поле с именем «Город». Пользователь ищет "Честер", и вы хотите, чтобы результаты возвращались в порядке убывания соответствия. Например, вы хотите, чтобы буквальные совпадения Честера отображались до Рочестера. Для этого добавьте два новых свойства к вашему объекту:
Затем на каждом объекте установите SearchText на то, что искал пользователь. Затем вы можете легко отсортировать что-то вроде:
Вот небольшая модификация, чтобы сделать это методом расширения:
источник
Моя реализация JavaScript принимает строку или массив строк и необязательный этаж (этаж по умолчанию равен 0,5). Если вы передадите ей строку, она вернет истину или ложь в зависимости от того, будет ли показатель сходства строки больше или равен полу. Если вы передадите ему массив строк, он вернет массив тех строк, у которых показатель сходства больше или равен полу, отсортированный по счету.
Примеры:
Вот:
источник
for(var j = 0; j < pairs1.length; j++){
должно бытьfor(var j = 0; j < pairs2.length; j++){
Алгоритм коэффициента кости (ответ Саймона Уайта / Марзагао) реализован в Ruby в методе pair_distance_s Similar в геме amatch.
https://github.com/flori/amatch
Этот драгоценный камень также содержит реализации ряда приближенных алгоритмов сопоставления и сравнения строк: расстояние редактирования Левенштейна, расстояние редактирования продавцов, расстояние Хемминга, самая длинная длина общей подпоследовательности, самая длинная длина общей подстроки, метрика парного расстояния, метрика Яро-Винклера ,
источник
Версия на Haskell - не стесняйтесь предлагать правки, потому что я не много сделал на Haskell.
источник
Clojure:
источник
Как насчет расстояния Левенштейна, разделенного на длину первой строки (или, альтернативно, на мою минимальную / максимальную / среднюю длину обеих строк)? Это сработало для меня до сих пор.
источник
Эй, ребята, я попробовал это в javascript, но я новичок в этом, кто-нибудь знает более быстрые способы сделать это?
источник
x
иy
, и вы не должны проходить через циклы, используяfor..in..
цикл (используйтеfor(..;..;..)
вместо этого).Вот еще одна версия Сходства, основанная на индексе Серенсена – Дайса (ответ Марзагао), написанная на C ++ 11:
источник
Я искал чистую рубиновую реализацию алгоритма, обозначенную ответом @ marzagao. К сожалению, ссылка, указанная @marzagao, не работает. В @ s01ipsist ответ, он указал рубин драгоценный камень amatch , где реализация не является в чистом рубина. Так что я Searchd немного и нашел драгоценный камень fuzzy_match который имеет чистую реализацию рубиновый (хотя это использование драгоценных камней
amatch
) на здесь . Я надеюсь, что это поможет кому-то, как я.источник