Улучшение алгоритма нечеткого сопоставления в Python

Задача: возьмите два текстовых файла и выведите 100% совпадений и 75% совпадений.

Решение:

import difflib
import csv

# Imports and parses the files
fileA = open("H:/comm.names.txt", 'r')
try:
        setA = fileA.readlines()
finally:    
        fileA.close()

fileB = open("H:/acad.names.txt", 'r')
try:
        setB = fileB.readlines()
finally:    
        fileB.close()

# 100% Match
setMatch100 = set(setA).intersection(setB)

Match100 = open("H:\Match100.txt", 'w')
try:
    for item in setMatch100:
        Match100.write(item)
finally:
    Match100.close()

# Remove 100% matches from the two lists
setA_LeftOver = set(setA).difference(setMatch100)
setB_LeftOver = set(setB).difference(setMatch100)

#Return the best match for setA_LeftOver[i] in setB_LeftOver that is at least 75% matching.
fMatch75 = open("H:\Match75.csv", 'w')
Match75 = csv.writer(fMatch75)
try:
    Match75.writerow(['File A', 'File B'])
    for item in setA_LeftOver:
                match = difflib.get_close_matches(item, setB_LeftOver, 1, 0.75)
                if len(match) > 0:
                        row = [item.rstrip(), match[0].rstrip()]
                        Match75.writerow(row)


finally:
    fMatch75.close()

Problem: This works, however the results aren't very good. Here is an example of a match:

Fovea Pharmaceuticals SA Kobe Pharmaceutical Univ
I can't turn up the minimum percent in Diff by too much because I need to be able to match Univ with University. Also, I can't just make sure that the first words match because some strings start with "The" and need to be matched with strings that exclude "The". Can anyone point me in a direction that would throw out matches that technically are 75% similar, but to a human aren't similar at all?


person MikeKusold    schedule 18.02.2011    source источник


Ответы (2)


Я бы попробовал сравнить строки с помощью такого инструмента, как pylevenshtein. Это позволяет нечеткое сравнение строк.

person e-satis    schedule 18.02.2011
comment
Спасибо за предложение, но я не думаю, что это сработает. У него та же проблема, что и при использовании Diff, в том, что он обрабатывает все слова одинаково. Мне почти нужен способ исключить определенные слова из сопоставления, чтобы остальная часть строки содержала более значимые слова. - person MikeKusold; 18.02.2011
comment
Я не уверен, что это решит проблему (между прочим, difflib должен лучше справляться с человеческими совпадениями, но оба не знают, что The неважно, а Univ — это сокращение от University) - person Steven; 18.02.2011
comment
Для этого вы можете предварительно обработать строки, заменив все строки общим эквивалентом и удалив неважные слова. - person e-satis; 20.02.2011

В итоге я написал наиболее распространенный сценарий слов, а затем удалил самые распространенные слова. Это значительно улучшило мои результаты, как предложил @e-satis в своем комментарии. Однако difflib дал мне лучшие результаты, чем pylevenshtein, поэтому я не могу отметить его ответ как принятый.

person MikeKusold    schedule 13.07.2011