Эта проблема известна как кластеризация и является частью более крупной проблемы дедупликации (где вы решаете, какой элемент кластера является «правильным»), а также известный как слияние-продувка .
Однажды я прочитал несколько научных статей именно на эту тему (имена приведены ниже), и в основном авторы использовали скользящее окно ограниченного размера над отсортированным списком строк. Они будут только сравнивать (используя алгоритм расстояние редактирования ) N * N строк внутри окна, тем самым уменьшая сложность вычислений. Если какие-либо две строки выглядели одинаково, они объединялись в cluster (путем вставки записи в отдельную таблицу кластеров).
За первым проходом по списку последовал второй проход , где строки были перевернуты перед сортировкой. Таким образом, струны с различными головками имели еще один шанс подойти достаточно близко, чтобы быть оцененными как часть одного и того же окна. На этом втором проходе, если строка выглядела достаточно близко к двум (или более) строкам в окне, и эти строки уже были частями их собственных кластеров (найденных при первом проходе), тогда эти два кластера будут объединены (путем обновления таблицы кластеров) и текущая строка будет добавлена во вновь объединенный кластер. Этот подход к кластеризации известен как алгоритм union-find .
Затем они улучшили алгоритм, заменив окно списком лучших X по существу уникальных прототипов . Каждая новая строка будет сравниваться с каждым из лучших X прототипов. Если строка выглядит достаточно близко к одному из прототипов, она будет добавлена в кластер прототипа . Если бы ни один из прототипов не выглядел достаточно похожим, строка стала бы новым прототипом, выталкивая самый старый прототип из верхнего списка X. (Существовала эвристическая логика, используемая для определения, какую из строк в кластере прототипа следует использовать в качестве нового прототипа, представляющего весь кластер). Опять же, если строка выглядит похожей на несколько прототипов, все их кластеры будут объединены.
Однажды я реализовал этот алгоритм для дедупликации записей имен / адресов с размерами списков, составляющих около 10-50 миллионов записей, и он работал чертовски быстро (и тоже нашел дубликаты).
В целом для таких проблем самая сложная часть, конечно, заключается в поиске правильного значения порога сходства . Идея состоит в том, чтобы запечатлеть все ошибки без получения слишком большого числа ложных срабатываний . Данные с разными характеристиками, как правило, требуют разных пороговых значений. Выбор алгоритма расстояния редактирования также важен, так как некоторые алгоритмы лучше для ошибок OCR, другие лучше для опечаток, а другие лучше для фонетических ошибок (например, при получении имени по телефону).
После того, как алгоритм кластеризации реализован, хорошим способом его тестирования является получение списка уникальных выборок и искусственное изменение каждой выборки для создания его вариаций, сохраняя при этом тот факт, что все вариации были получены от того же родителя. Этот список затем перемешивается и подается в алгоритм. Сравнение исходной кластеризации с кластеризацией, произведенной алгоритмом дедупликации, даст вам показатель эффективности .
Библиография:
Эрнандес М., 1995, Проблема слияния / очистки для больших баз данных.
Монж А. 1997, Эффективный независимый от домена алгоритм обнаружения приблизительно дублированных записей базы данных.