Как вернуть имена "с разным написанием" из фрейма данных - PullRequest
1 голос
/ 16 апреля 2019

Как вы знаете, многие имена имеют несколько вариантов написания.

У меня есть набор данных с именами и фамилиями, но у меня есть проблема с вариациями правописания.

Вотобразец из набора данных:

    firstName  lastName
0    Ali        Khaled
1    Hamada     5ald
2    3ly        7mada
3    7amada     5aled 
4    Sophia     Andrew
5    Sofiya     Jaxon
6    Matthieu   Jackson
7    Matthieu   Jozeph
8    Mathew     Andru

Поэтому я пытаюсь вернуть всех людей, их имя "Мэтью":
Мэтью, Мэтью и Мэтью

Или люди по имениили фамилия "Hamada":
Hamada, 7amada, 7mada

Я попытался заменить эти числа соответствующими буквами, а затем использовать функцию get_close_matches, но она не является ни точной, ни pythonic.

РЕДАКТИРОВАТЬ :
Я думаю, что будет лучше заменить все несколько написаний на популярные (как в первом, так и в последнем).Так что если {"Matthew": 4, "Mathew": 2, "Matthieu": 1}, заменить "Мэтью" и "Матье" на "Мэтью"

Ответы [ 3 ]

1 голос
/ 16 апреля 2019

Вы можете сделать следующее, чтобы сгруппировать близкие совпадения и вернуть его в качестве нового столбца:


from difflib import get_close_matches as gsm

df['Close_Matches'] = [', '.join(gsm(name, df.firstName)) for name in df.firstName]

print(df)

  firstName lastName               Close_Matches
0       Ali   Khaled                         Ali
1    Hamada     5ald              Hamada, 7amada
2       3ly    7mada                         3ly
3    7amada    5aled              7amada, Hamada
4    Sophia   Andrew              Sophia, Sofiya
5    Sofiya    Jaxon              Sofiya, Sophia
6  Matthieu  Jackson  Matthieu, Matthieu, Mathew
7  Matthieu   Jozeph  Matthieu, Matthieu, Mathew
8    Mathew    Andru  Mathew, Matthieu, Matthieu
0 голосов
/ 17 апреля 2019

Чтобы найти сходство между двумя словами \ предложениями, вы можете использовать что-то вроде Изменить расстояние или Расстояние Джакарда .

Давайте проверим это в вашем случае, используя Изменить расстояние :

firstName = ['Ali', 'Hamada', '3ly', '7amada', 'Sophia', 'Sofiya', 'Matthieu', 'Matthieu', 'Mathew']

#No need to implement the distance function, you can call it from NLTK

import nltk

# Find similier first name using edit distance
for name in firstName:
    nameToCompare = [x for x in firstName if x != name]
    for n in nameToCompare:
        print(name, n, nltk.edit_distance(name, n))
    print('***************')

# Ali Hamada 6
# Ali 3ly 2
# Ali 7amada 6
# Ali Sophia 5
# Ali Sofiya 5
# Ali Matthieu 7
# Ali Matthieu 7
# Ali Mathew 6
#***************
# Hamada Ali 6
# Hamada 3ly 6
# Hamada 7amada 1
# Hamada Sophia 5
# Hamada Sofiya 5
# Hamada Matthieu 7
# Hamada Matthieu 7
# Hamada Mathew 5
#***************
# 3ly Ali 2
# 3ly Hamada 6
# 3ly 7amada 6
# 3ly Sophia 6
# 3ly Sofiya 5
# 3ly Matthieu 8
# 3ly Matthieu 8
# 3ly Mathew 6
#***************
# 7amada Ali 6
# 7amada Hamada 1
# 7amada 3ly 6
# 7amada Sophia 5
# 7amada Sofiya 5
# 7amada Matthieu 7
# 7amada Matthieu 7
# 7amada Mathew 5
#***************
# Sophia Ali 5
# Sophia Hamada 5
# Sophia 3ly 6
# Sophia 7amada 5
# Sophia Sofiya 3
# Sophia Matthieu 6
# Sophia Matthieu 6
# Sophia Mathew 5
#***************
# Sofiya Ali 5
# Sofiya Hamada 5
# Sofiya 3ly 5
# Sofiya 7amada 5
# Sofiya Sophia 3
# Sofiya Matthieu 7
# Sofiya Matthieu 7
# Sofiya Mathew 6
#***************
# Matthieu Ali 7
# Matthieu Hamada 7
# Matthieu 3ly 8
# Matthieu 7amada 7
# Matthieu Sophia 6
# Matthieu Sofiya 7
# Matthieu Mathew 3
#***************
# Matthieu Ali 7
# Matthieu Hamada 7
# Matthieu 3ly 8
# Matthieu 7amada 7
# Matthieu Sophia 6
# Matthieu Sofiya 7
# Matthieu Mathew 3
#***************
# Mathew Ali 6
# Mathew Hamada 5
# Mathew 3ly 6
# Mathew 7amada 5
# Mathew Sophia 5
# Mathew Sofiya 6
# Mathew Matthieu 3
# Mathew Matthieu 3
#***************

Маленькие числа означают, что это больше похоже.Вы можете заметить, что он может идентифицировать похожую гриву с разным написанием.

Теперь давайте применим Расстояние Джакарта

for name in firstName:
    nameToCompare = [x for x in firstName if x != name]
    for n in nameToCompare:
        print(name, n, (1-nltk.jaccard_distance(set(name), set(n)))*100)
    print('***************')

# Ali Hamada 0.0
# Ali 3ly 19.999999999999996
# Ali 7amada 0.0
# Ali Sophia 12.5
# Ali Sofiya 12.5
# Ali Matthieu 11.111111111111116
# Ali Matthieu 11.111111111111116
# Ali Mathew 0.0
#***************
# Hamada Ali 0.0
# Hamada 3ly 0.0
# Hamada 7amada 60.0
# Hamada Sophia 11.111111111111116
# Hamada Sofiya 11.111111111111116
# Hamada Matthieu 9.999999999999998
# Hamada Matthieu 9.999999999999998
# Hamada Mathew 11.111111111111116
#***************
# 3ly Ali 19.999999999999996
# 3ly Hamada 0.0
# 3ly 7amada 0.0
# 3ly Sophia 0.0
# 3ly Sofiya 12.5
# 3ly Matthieu 0.0
# 3ly Matthieu 0.0
# 3ly Mathew 0.0
#***************
# 7amada Ali 0.0
# 7amada Hamada 60.0
# 7amada 3ly 0.0
# 7amada Sophia 11.111111111111116
# 7amada Sofiya 11.111111111111116
# 7amada Matthieu 9.999999999999998
# 7amada Matthieu 9.999999999999998
# 7amada Mathew 11.111111111111116
#***************
# Sophia Ali 12.5
# Sophia Hamada 11.111111111111116
# Sophia 3ly 0.0
# Sophia 7amada 11.111111111111116
# Sophia Sofiya 50.0
# Sophia Matthieu 30.000000000000004
# Sophia Matthieu 30.000000000000004
# Sophia Mathew 19.999999999999996
#***************
# Sofiya Ali 12.5
# Sofiya Hamada 11.111111111111116
# Sofiya 3ly 12.5
# Sofiya 7amada 11.111111111111116
# Sofiya Sophia 50.0
# Sofiya Matthieu 18.181818181818176
# Sofiya Matthieu 18.181818181818176
# Sofiya Mathew 9.090909090909093
#***************
# Matthieu Ali 11.111111111111116
# Matthieu Hamada 9.999999999999998
# Matthieu 3ly 0.0
# Matthieu 7amada 9.999999999999998
# Matthieu Sophia 30.000000000000004
# Matthieu Sofiya 18.181818181818176
# Matthieu Mathew 62.5
#***************
# Matthieu Ali 11.111111111111116
# Matthieu Hamada 9.999999999999998
# Matthieu 3ly 0.0
# Matthieu 7amada 9.999999999999998
# Matthieu Sophia 30.000000000000004
# Matthieu Sofiya 18.181818181818176
# Matthieu Mathew 62.5
#***************
# Mathew Ali 0.0
# Mathew Hamada 11.111111111111116
# Mathew 3ly 0.0
# Mathew 7amada 11.111111111111116
# Mathew Sophia 19.999999999999996
# Mathew Sofiya 9.090909090909093
# Mathew Matthieu 62.5
# Mathew Matthieu 62.5
#***************

Также у нас отличные результаты!

Надеюсь, это поможет

0 голосов
/ 16 апреля 2019

Проблема в том, что понятие «одно и то же имя с другим правописанием» зависит от фонетики.Люди определяют это, слушая произношение обоих имен и говоря: «Эй, они звучат одинаково».Единственный способ, которым компьютер мог бы знать, что «Мэтью» и «Матье» - это «одно и то же имя», - это использовать некоторый тип преобразования текста в речь в некоторый анализ звука.

Поскольку это наиболее вероятноне то, что вы хотите сделать, единственное, на что вы действительно можете смотреть, это расстояние Хэмминга и определение некоторого порога (возможно, 1 символ), который вы принимаете как «то же имя».Это наиболее вероятно, что делает get_close_matches (), но оценивает это как отношение к длине слова.Но даже у этого будут ложные срабатывания (наверняка есть разные имена с расстоянием Хэмминга, равным 1, даже если я не могу думать о них сейчас), и вы не будете правильно группировать имена, такие как «Хейли» и «Хейли», пока неподнимите этот порог до 4, и тогда у вас будет много ложных срабатываний.

Не говоря уже о том, что имена не обязательно должны произноситься фонетически.Я могу назвать своего сына "а" и назвать его "Джаред".Как вы могли обнаружить, что это альтернативное написание слова "Джеррод"?Вы не можете, и, следовательно, вы не можете программно определить, являются ли два имени «одинаковыми».Проблема в том, что сама проблема не очень хорошо определена.Вы могли бы лучше определить это, сказав, что вы хотите сгруппировать имена, которые «фонетически одинаковы».Это позволяет вам пропустить надуманные примеры, такие как «а», но вы просто обменяли эту проблему на потребность в каком-то фонетическом движке, который далек от тривиального.

tl; dr невозможен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...