У меня есть довольно большой набор строк (скажите 100), который имеет много подгрупп, характеризуемых их подобием. Я пытаюсь найти/разработать алгоритм, который нашел бы группы тезисов обоснованно эффективно.
Как пример скажем, входной список слева ниже, и выходные группы справа.
Input Output
----------------- -----------------
Jane Doe Mr Philip Roberts
Mr Philip Roberts Phil Roberts
Foo McBar Philip Roberts
David Jones
Phil Roberts Foo McBar
Davey Jones =>
John Smith David Jones
Philip Roberts Dave Jones
Dave Jones Davey Jones
Jonny Smith
Jane Doe
John Smith
Jonny Smith
Кто-либо знает о каких-либо способах решить это обоснованно эффективно?
Стандартный метод для нахождения подобных строк, кажется, расстояние Левенштейна, но я не вижу, как я могу хорошо использовать это здесь, не имея необходимость сравнивать каждую строку с любой строкой в списке и затем так или иначе выбирать порог различия для решения, если две строки находятся в той же группе или нет.
Альтернатива была бы алгоритмом, который хеширует строки вниз к целому числу, где подобные строки хешируют к целым числам, которые находятся близко друг к другу на числовой оси. Я понятия не имею, какой алгоритм, который был бы, хотя, если Вы даже существуете
У кого-либо есть какие-либо мысли/указатели?
ОБНОВЛЕНИЕ: @Will A: Возможно, имена не были столь же хорошим примером, как я сначала думал. Как начальная точка я думаю, что могу предположить, что в данных я буду работать с, небольшое изменение в строке не заставит их спрыгнуть с одной группы другому.
Другой популярный метод - ассоциировать строки по их индексу Жаккара. Начните с http://en.wikipedia.org/wiki/Jaccard_index.
Вот статья об использовании Jaccard-индекса (и пары других методов) для решения проблемы, подобной вашей:
Для приведенного вами примера, я считаю, что расстояние Левенштейна было бы неподходящим, поскольку «Бонни Смит» была бы «очень похожа» на «Джонни Смита» и почти наверняка попала бы в то же класс.
Я думаю, вам нужно подойти к этому (при работе с именами) с точки зрения некоторых имен, имеющих синонимы (например, «Джон», «Джон», «Джонни», «Джонни» и т. Д.) И соответствия на основе этих.
Проблема, которую вы пытаетесь решить, - это типичная проблема кластеризации .
Начните с простого алгоритма K-средних и используйте расстояние Левенштейна как функцию для вычисления расстояния между элементами и центрами кластеров.
Кстати, алгоритм вычисления расстояния Левенштейна реализован в Apache Commons StringUtils - StringUtils.getLevenshteinDistance
Основная проблема K-Means заключается в том, что вы должны указать количество кластеров (подгрупп в ваших терминах). Итак, у вас будет 2 варианта: улучшить K-средние с помощью некоторой эвристики или использовать другой алгоритм кластеризации, который не требует указания количества кластеров (но этот алгоритм может показать худшую производительность и может быть очень сложным в реализации, если вы решите его реализовать. себя).
Если мы говорим о реально произносимых словах, то сравнение (начала) их метафоры может быть полезным:
MRFLPRBRTS: Mr Philip Roberts
FLRBRTS: Phil Roberts
FLPRBRTS: Philip Roberts
FMKBR: Foo McBar
TFTJNS: David Jones
TFJNS: Dave Jones
TFJNS: Davey Jones
JNT: Jane Doe
JNSM0: John Smith
JNSM0: Jonny Smith