Сравнение человеческих имен:способы решения этой задачи
-
06-07-2019 - |
Вопрос
Я не изучаю программирование на естественном языке, но знаю, что это нетривиально strcmp(n1,n2).
Вот что я узнал на данный момент:
- сравнение личных имен не может быть решено на 100%
- существуют способы достижения определенной степени точности.
- ответ будет зависеть от локали, это нормально.
Я не ищу альтернативы написанию!Предполагается, что вводимые данные написаны правильно.
Например, все имена ниже могут относиться к одному и тому же человеку:
- Берри Цакала
- Бернар Цакала
- Берри Дж.Цакала
- Цакала, Берри
Я пытаюсь:
- построить (или скопировать) алгоритм, который оценивает взаимосвязь 2 входных имени
- найти метод индексации (для имен в моей базе данных, для хеш-таблиц и т. д.)
примечание:Моя задача не найти имена в тексте, а сравнить 2 имени.например
name_compare( "James Brown", "Brown, James", "en-US" ) ---> 99.0%
Решение
Я использовал коэффициент Танимото для быстрого (но не супер) решения на Python:
"""
Formula:
Na = number of set A elements
Nb = number of set B elements
Nc = number of common items
T = Nc / (Na + Nb - Nc)
"""
def tanimoto(a, b):
c = [v for v in a if v in b]
return float(len(c)) / (len(a)+len(b)-len(c))
def name_compare(name1, name2):
return tanimoto(name1, name2)
>>> name_compare("James Brown", "Brown, James")
0.91666666666666663
>>> name_compare("Berry Tsakala", "Bernard Tsakala")
0.75
>>>
Редактировать: Ссылка на хорошую и полезную книгу.
Другие советы
Саундекс иногда используется для сравнения похожих имен.Он не занимается упорядочиванием имен и фамилий, но вы, вероятно, могли бы просто поискать в коде запятую, чтобы решить эту проблему.
В последнее время мы постоянно занимаемся такой работой, и наш подход заключается в том, чтобы иметь справочную таблицу или список псевдонимов.Если вы можете не принимать во внимание орфографические/неслышанные/неанглийские имена, тогда самая сложная часть будет решена.В ваших примерах мы предполагаем, что первое и последнее слово — это имя и фамилия.Все, что находится между ними, будет отброшено (отчества, инициалы).Берри и Бернард будут в списке псевдонимов, и когда Цакала не будет соответствовать Берри, мы перевернем порядок слов и получим совпадение.
Вам нужно понять одну вещь: базу данных/списки людей, с которыми вы имеете дело.В англоязычном мире отчества записываются непоследовательно.Таким образом, вы не можете установить или отклонить совпадение на основе отчества или отчества.Soundex не поможет вам с распространенными псевдонимами, такими как «Дик» и «Ричард», «Берри» и «Бернард» и, возможно, «Стив» и «Стивен».В некоторых сообществах люди довольно часто живут по одному и тому же адресу, и по этому адресу живут 2 или 3 поколения с одним и тем же именем.Разделить их можно только по дате рождения.Дата рождения может быть записана или не записана.Если у вас есть влияние, вам, вероятно, следует сделать запись даты рождения обязательной.Многие «базы данных о людях» либо не записывают дату рождения, либо не раскрывают ее по соображениям конфиденциальности.
На самом деле сопоставление имен людей не так уж и сложно.Это полностью основано на качестве предоставленных данных.На практике происходит так, что многие записи остаются несовпадающими, и даже человек, просматривающий их, не может устранить несоответствие.Человек может заметить псевдонимы имен, не записанные в списке псевдонимов, или может найти информацию о человеке в Интернете, но вы не можете ожидать, что ваша программа сделает это.
Банки, кредитно-рейтинговые организации и правительство имеют о нас много подробной информации.Предыдущие адреса, дата рождения и т. д.И это помогает им объединять имена.Но для нас, обычных программистов, не существует волшебного средства.
Анализ порядка имен и существования вторых имен/инициалов, конечно, тривиален, поэтому похоже, что настоящая проблема заключается в знании альтернативных распространенных имен.Я сомневаюсь, что это можно сделать без использования какой-либо таблицы поиска псевдонимов. Этот список это хорошая отправная точка.Он не сопоставляет Бернарда с Берри, но, вероятно, позволит выявить наиболее распространенные случаи.Возможно, еще более полный список можно найти где-нибудь еще, но я определенно считаю, что лучше всего использовать таблицу поиска для конкретной локали.
У меня были реальные проблемы с Tanimoto, использующим utf-8.
Что работает для языков, использующих диакритические знаки, так это difflib.SequenceMatcher()