Pandas, Анализ данных

FuzzyWuzzy или нечёткое сравнение «грязных» pandas столбцов на основании расстояния Левенштейна

Время прочтения: 4 мин.

Предполагаемый результат — сопоставить каждое значение столбца A с ближайшим соответствующим значением в столбце B, которое затем помещается в ту же строку.

Часто, когда вы работаете с разными источниками данных, один и тот же объект (адрес, номер телефона, e-mail и др.) может быть написан в свободной форме или сформулирован по-разному.

Мы будем работать над сопоставлением адресов, первый DataFrame которого содержит адреса, извлеченные из PDF-сканов договоров аренды, второй DataFrame представляет собой выгрузку адресов из базы, с необходимыми в последующем данными.

  1. Пакеты

Во-первых, импортируем, все необходимые для нас, пакеты:

import pandas as pd

Вы можете установить FuzzyWuzzy, запустив в своем JupyterNotebook или через cmd:

От FuzzyWuzzy нам в основном понадобятся два модуля: process и fuzz.

from fuzzywuzzy import fuzz 
from fuzzywuzzy import process
  1. Данные

На входе у нас есть два кадра данных таблицы, которые нужно будет сопоставить:

df_num содержит номера договоров аренды и адрес, сформулированный в свободной форме.

df_base содержит адрес, площадь и стоимость арендованного помещения, выгруженные из базы.

Каждому адресу из df_num соответствует один адрес из df_base.

df_num = pd.read_excel('Aдpec_номep.xlsx')
df_base = pd.read_excel ('Aдpec_база.xlsx')
  1. Введение в FuzzyWuzzy

Давайте начнем с основного введения в FuzzyWuzzy. Этот пакет сравнивает две строки A и B и выводит соотношение, которое оценивает расстояние между ними. Мы говорим здесь о расстоянии Левенштейна, которое является расстоянием между A и B с точки зрения того, сколько изменений мы должны внести в строку A, чтобы преобразовать ее в строку B.

Изменения включают в себя удаление, добавление или замену символов. Чем меньше изменений мы можем сделать, тем больше похожи А и В, что приводит к более высокому соотношению.

Вот два основных модуля, которые мы рассмотрим в этой статье:

fuzz.ratio: сравнивает две строки и выводит соотношение. Например:

fuzz.ratio(‘Ha улице солнечно!’ , ‘На улице действительно солнечно’)
69

process.extract: он принимает строку A, а затем ищет лучшие соответствия для нее в списке строк, затем возвращает эти строки вместе с их отношениями (параметр limit сообщает модулю, сколько похожих строк мы хотим вернуть). Например:

list_of_strings = [‘a’, ‘ab’, ’c’, ‘cd’]
process.extract (’aaa’, list_of_strings, limit = 2)
[(‘a’ , 90), (‘ab’ , 45)]

Эти два модуля могут использовать различные способы вычисления отношения, от основного отношения Левенштейна до более сложного взвешенного отношения. 

  1. Применение FuzzyWuzzy

Теперь давайте использовать process.extract для сравнения:

from fuzzywuzzy import fuzz 
from fuzzywuzzy import process
actual_adress=[]
similarity=[]
for i in df_num.Adress:
ratio = process.extract (i , df_base['Адрес'],  limit=2, scorer=fuzz.token_sort_ratio)
actual_adress.append(ratio[0] [0])
similarity.append(ratio[0][1])
df_num['Adr']=pd.Series(actual_adress) 
df_num['Similarity']=pd.Series(similarity) 
df_num
  1. Проверка на верное сопоставление

Хороший способ проверить наше сопоставление — отформатировать фрейм данных с помощью цветовой карты, чтобы было легче определить и проверить низкие коэффициенты сопоставления.

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

df_num.style.background_gradient(subset=’Similarity’, cmap=’summer_r’)

У FuzzyWuzzy есть много разных счётчиков, которые вы можете выбрать в зависимости от типа данных, с которыми вы работаете. 

fuzz.ratio
fuzz.partial_ratio
fuzz.token_set_ratio
fuzz.token_sort_ratio
fuzz.partial_token_set_ratio
fuzz.partial_token_sort_ratio
fuzz.WRatio
fuzz.QRatio
fuzz.UWRatio
fuzz.UQRatio

По умолчанию используется процесс fuzz.WRatio

Если вы хотите использовать process с одним из этих счётчиков, просто передайте его в качестве аргумента, например:

ratio = process.extract(column_A, column_B, limit=1, scorer=fuzz.ratio)

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

Вот почему вы должны знать применение счётчиков FuzzyWuzzy, чтобы выбрать тот, который лучше всего подходит для того типа данных, с которым вы работаете.

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

Советуем почитать