На сколько процентов совпадают две строки? - PullRequest
0 голосов
/ 23 декабря 2019

У меня есть 2 столбца названий болезней, я должен попытаться подобрать лучшие варианты. Я попытался использовать модуль "SequenceMatcher" и модуль "fuzzywuzzy" в python, и результаты оказались удивительными. Я вставил результаты и мои сомнения ниже:

Учтите, что есть заболевание "новообразования печени", которое мне нужно сопоставить с наилучшим подходящим названием "рак, печень" или "рак, грудь". Теперь очевидно, что, поскольку слово «печень» совпадает, ей следует легко подобрать слово «рак, печень», но этого не происходит. Я хотел бы знать причину и лучший способ соответствовать в Python.

from difflib import SequenceMatcher

s1 = 'liver neoplasms'
s2 = 'cancer, liver'

SequenceMatcher(None, s1, s2).ratio() 
# Answer = 0.3571

s2 = 'cancer, breast'
SequenceMatcher(None, s1, s2).ratio()
# Answer = 0.4137 

# fuzzy.ratio also has the same results.

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

Спасибо :)

Ответы [ 2 ]

3 голосов
/ 23 декабря 2019

здесь - алгоритм сопоставления косинусного сходства между двумя строками.

Пожалуйста, обратитесь к следующей ссылке для объяснения теории

https://blog.nishtahir.com/2015/09/19/fuzzy-string-matching-using-cosine-similarity/

import re
import math
from collections import Counter


def get_cosine(vec1, vec2):
    intersection = set(vec1.keys()) & set(vec2.keys())
    numerator = sum([vec1[x] * vec2[x] for x in intersection])

    sum1 = sum([vec1[x]**2 for x in vec1.keys()])
    sum2 = sum([vec2[x]**2 for x in vec2.keys()])
    denominator = math.sqrt(sum1) * math.sqrt(sum2)

    if not denominator:
        return 0.0
    else:
        return float(numerator) / denominator


def text_to_vector(text):
    word = re.compile(r'\w+')
    words = word.findall(text)
    return Counter(words)


def get_result(content_a, content_b):
    text1 = content_a
    text2 = content_b

    vector1 = text_to_vector(text1)
    vector2 = text_to_vector(text2)

    cosine_result = get_cosine(vector1, vector2)
    return cosine_result


print(get_result('liver neoplasms', 'cancer, liver'))
print(get_result('liver neoplasms', 'cancer, breast'))
1 голос
/ 23 декабря 2019

Эти типы сопоставителей не имеют семантического понимания. Они просто считают, сколько символов совпадают. Некоторые из них более сложные, чем другие.

Может помочь расстояние levenshtein. Смотри https://github.com/ztane/python-Levenshtein.

from difflib import SequenceMatcher from Levenshtein import distance

s1 = 'liver neoplasms' s2 = 'cancer, liver'

print('Sequence-matcher: ', SequenceMatcher(None, s1, s2).ratio()) 
# Answer = 0.35...

print('Levenshtein: ', distance(s1, s2))
# Answer = 13

s2 = 'cancer, breast' 

print('Sequence-matcher: ', SequenceMatcher(None, s1, s2).ratio()) 
# Answer = 0.41...

print('Levenshtein: ', distance(s1, s2))
# Answer = 12
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...