2016-09-27 12 views
1

Я довольно новичок в Python, и я пытаюсь использовать нечеткие wuzzy для нечеткого соответствия. Я считаю, что получаю неправильные оценки для совпадений, используя функцию partial_ratio. Вот мой разведочное код:Получение неверного результата от fuzzy wuzzy partial_ratio

>>>from fuzzywuzzy import fuzz 
>>>fuzz.partial_ratio('Subject: Dalki Manganese Ore Mine of M/S Bharat Process and Mechanical Engineers Ltd., Villages Dalki, Soyabahal, Sading and Thakurani R.F., Tehsil Barbil, Distt, Keonjhar, Orissa environmental clearance','Barbil') 
50 

Я считаю, что это должен вернуть 100 баллов, начиная со второй строки, «Barbil», содержится в первой строке. Когда я пытаюсь снимать несколько символов в конце или в начале первой строки, я получаю соответствующий балл 100.

>>>fuzz.partial_ratio('Subject: Dalki Manganese Ore Mine of M/S Bharat Process and Mechanical Engineers Ltd., Villages Dalki, Soyabahal, Sading and Thakurani R.F., Tehsil Barbil, Distt, Keonjhar, Orissa environmental clear','Barbil') 
100 
>>> fuzz.partial_ratio('ect: Dalki Manganese Ore Mine of M/S Bharat Process and Mechanical Engineers Ltd., Villages Dalki, Soyabahal, Sading and Thakurani R.F., Tehsil Barbil, Distt, Keonjhar, Orissa environmental clearance','Orissa') 
100 

Это, кажется, перейти от баллов от 50 до 100 баллов, когда длина первой строки идет до 199. Есть ли у кого-нибудь представление о том, что может произойти?

ответ

0

Это потому, что когда одна из строк 200 characters or longer, an automatic junk heuristic gets turned on in python's SequenceMatcher. Этот код должен работать на вас:

from difflib import SequenceMatcher 

def partial_ratio(s1, s2): 
    """"Return the ratio of the most similar substring 
    as a number between 0 and 100.""" 

    if len(s1) <= len(s2): 
     shorter = s1 
     longer = s2 
    else: 
     shorter = s2 
     longer = s1 

    m = SequenceMatcher(None, shorter, longer, autojunk=False) 
    blocks = m.get_matching_blocks() 

    # each block represents a sequence of matching characters in a string 
    # of the form (idx_1, idx_2, len) 
    # the best partial match will block align with at least one of those blocks 
    # e.g. shorter = "abcd", longer = XXXbcdeEEE 
    # block = (1,3,3) 
    # best score === ratio("abcd", "Xbcd") 
    scores = [] 
    for (short_start, long_start, _) in blocks: 
     long_end = long_start + len(shorter) 
     long_substr = longer[long_start:long_end] 

     m2 = SequenceMatcher(None, shorter, long_substr, autojunk=False) 
     r = m2.ratio() 
     if r > .995: 
      return 100 
     else: 
      scores.append(r) 

    return max(scores) * 100.0