Методы поиска близлежащих дубликатов записей
Я пытаюсь очистить базу данных, которая за эти годы приобрела много повторяющихся записей с немного разными именами. Например, в таблице компаний есть такие имена, как "Some Company Limited" и "НЕКОТОРЫЕ КОМПАНИИ LTD!".
Мой план заключался в том, чтобы экспортировать таблички с нарушениями в R, преобразовать имена в нижний регистр, заменить обычные синонимы (например, "limited" → "ltd" ), вырезать неалфавитные символы, а затем использовать agrep
, чтобы увидеть, что выглядит аналогичным.
Моя первая проблема заключается в том, что agrep
принимает только один шаблон, который соответствует, и циклическое совпадение над каждым именем компании для соответствия другим является медленным. (Некоторые таблицы для очистки будут иметь десятки, возможно, сотни тысяч имен для проверки.)
Я очень кратко рассмотрел пакет tm
(статью JSS), и он кажется очень мощным, но предназначен для анализа больших фрагментов текста, а не просто имена.
У меня есть несколько связанных вопросов:
-
Является ли пакет tm
подходящим для такого рода задач?
-
Есть ли более быстрая альтернатива agrep
? (Указанная функция использует
Левенштейн отредактировал расстояние, которое является анекдотически медленным.)
-
Существуют ли другие подходящие инструменты в R, кроме agrep
и tm
?
-
Должен ли я делать это в R, или если это будет
выполняется непосредственно в базе данных? (Это база данных Access, поэтому я бы
скорее избегайте прикосновения к нему, если это возможно.)
Ответы
Ответ 1
Если вы делаете небольшие партии, которые относительно хорошо сформированы, то функции compare.linkage()
или compare.dedup()
в пакете RecordLinkage
должны быть отличная отправная точка. Но если у вас большие партии, вам, возможно, придется немного потренироваться.
Я использую функции jarowinkler()
, levenshteinSim()
и soundex()
в RecordLinkage
, чтобы написать свою собственную функцию, которая использует мою собственную схему взвешивания (также, как это, вы не можете использовать soundex()
для большие наборы данных с RecordLinkage
).
Если у меня есть два списка имен, которые я хочу сопоставить ( "запись ссылки" ), я обычно конвертирую их в нижний регистр и удаляю все знаки препинания. Чтобы позаботиться о "Ограниченной" и "ЛТД", я обычно создаю еще один вектор первого слова из каждого списка, что позволяет дополнительно взвешивать первое слово. Если я думаю, что в одном списке могут быть аббревиатуры (возможно, ATT или IBM), тогда я перекрою другой список. Для каждого списка я получаю кадр данных строк, который я бы хотел сравнить, который я пишу как отдельные таблицы в базе данных MySQL.
Поэтому, чтобы у меня не было слишком много кандидатов, я LEFT OUTER JOIN
эти две таблицы на то, что должно совпадать между двумя списками (возможно, что первые три буквы в каждом списке или первые три буквы и первые три буквы в аббревиатуре). Затем я вычисляю результаты совпадения с использованием вышеуказанных функций.
Вам все равно придется выполнять ручную проверку вручную, но вы можете сортировать по счету, чтобы быстро исключить несоответствия.
Ответ 2
Возможно, google ref может помочь. Похоже, что он более приспособлен, если у вас много исключений, и вы еще не знаете их всех.
Ответ 3
То, что вы делаете, называется запись ссылки, и это была огромная область исследований на протяжении многих десятилетий. К счастью для вас, есть целая куча инструментов, готовых для такого рода вещей. В принципе, вы можете указать их в своей базе данных, настроить некоторые чистки и компараторы (например, Левенштейна или Яро-Винклера или...), и они уйдут и сделают эту работу за вас.
В этих инструментах обычно есть функции для решения проблем с производительностью, поэтому, хотя Levenshtein работает медленно, они могут работать быстро, потому что большинство пар записей никогда не сравниваются вообще.
В приведенной выше ссылке в Википедии есть ссылки на ряд инструментов для создания записей, которые вы можете использовать. Я лично написал один из них, названный Duke на Java, который я успешно использовал для этого. Если вам нужно что-то большое и дорогое, вы можете купить инструмент управления основными данными.
Ответ 4
В вашем случае, возможно, что-то вроде вычисления "расстояние-расстояние" будет работать, но если вам нужно найти почти дубликаты в больших текстовых документах, вы можете попробовать
http://www.softcorporation.com/products/neardup/