Сегодня утром я боролся с проблемой в офисе.
Мне нужно найти способ сгруппировать строки из списка.Трудно объяснить, вот пример:
Допустим, у меня есть следующий список:
['MONTREAL EDUCATION BOARD', 'Île de Montréal', 'Montréal',
'Ville de Montréal', 'MONTREAL CITY', 'Monrtéal', 'Mont-réal',
'Toronto', 'Toronto city', 'Tornoto', 'What is this', 'Bananasplit',
'Banana', 'StLouis', 'St-Louis', 'Saint Louis']
Мне нужно найти способ сгруппировать эти значения вместе в зависимости от их сходства:
[['MONTREAL EDUCATION BOARD'],
['Île de Montréal', 'Montréal','Ville de Montréal', 'MONTREAL CITY', 'Monrtéal', 'Mont-réal'],
['Toronto', 'Toronto city', 'Tornoto'],
['anything'],
['Bananasplit', 'Banana'],
['StLouis', 'St-Louis', 'Saint Louis']
]
Это был бы идеальный случай.Очевидно, что это может иметь (и будет) ошибки.Мне нужно сделать это с около 10 000 списков, которые содержат от 5 до 15 000 строк в каждом.Мне нужно минимизировать ошибку и получить лучшие группы, которые я могу.
Я использую слегка модифицированную версию fuzzywuzzy
.Сначала я снимаю акценты и пишу с заглавной буквы все буквы для более точного расстояния Левенштейна.
Я пытался установить порог (скажем, 80), перебирать список, делать группу из каждой строки и братьиз дубликатов элементов.Очевидно, это не тот результат, который мне нужен, потому что мне нужно, чтобы каждый элемент появлялся только в одном списке (и это не так, потому что A можно связать с B, B с C, но не с A до C).
groups = []
for curr in lst:
curr_grp = []
for item in lst:
ratio = normalized.partial_ratio(curr, item)
if ratio > SET_THRESHOLD:
curr_grp.append((item, ratio))
groups.append(curr_grp)
Я думаю , что можно найти способ найти наиболее оптимальную конфигурацию из моего вывода:
[[('MONTREAL EDUCATION BOARD', 100),
('Montréal', 100), # Will probably have to use ratio() and not partial_ratio() because
('Monrtéal', 88), # this can't happen, EDUCATION BOARD is NOT Montreal
('Mont-réal', 89)],
[('Île de Montréal', 100),
('Montréal', 100),
('Ville de Montréal', 93),
('Monrtéal', 88),
('Mont-réal', 94)],
[('MONTREAL EDUCATION BOARD', 100),
('Île de Montréal', 100),
('Montréal', 100),
('Ville de Montréal', 100),
('MONTREAL CITY', 100),
('Monrtéal', 88),
('Mont-réal', 88)],
[('Île de Montréal', 93),
('Montréal', 100),
('Ville de Montréal', 100),
('Monrtéal', 88),
('Mont-réal', 94)],
[('Montréal', 100),
('MONTREAL CITY', 100),
('Monrtéal', 88),
('Mont-réal', 89)],
[('MONTREAL EDUCATION BOARD', 88),
('Île de Montréal', 88),
('Montréal', 88),
('Ville de Montréal', 88),
('MONTREAL CITY', 88),
('Monrtéal', 100)],
[('MONTREAL EDUCATION BOARD', 89),
('Île de Montréal', 94),
('Montréal', 88),
('Ville de Montréal', 94),
('MONTREAL CITY', 89),
('Mont-réal', 100)],
[('Toronto', 100), ('Toronto city', 100), ('Tornoto', 86)],
[('Toronto', 100), ('Toronto city', 100), ('Tornoto', 86)],
[('Toronto', 86), ('Toronto city', 86), ('Tornoto', 100)],
[('What is this', 100)],
[('Bananasplit', 100), ('Banana', 100)],
[('Bananasplit', 100), ('Banana', 100)],
[('StLouis', 100), ('St-Louis', 86), ('Saint Louis', 86)],
[('StLouis', 86), ('St-Louis', 100)],
[('StLouis', 86), ('Saint Louis', 100)]]
Можно ли найти наиболее оптимальное подмножество этогосписок, где каждый элемент появляется только в одной группе?(так с наибольшим количеством очков?) Примите во внимание, что мои списки будут НАМНОГО больше, поэтому я не могу протестировать каждую конфигурацию, потому что это займет годы.
Иначе, есть еще один более эффективный способ сделать то, чтоЯ пытаюсь сделать?
Спасибо!