Каков эффективный способ проверить, близко ли текущее слово к слову в строке?

рассмотрим примеры ниже:

  1. Пример 1:

    str1 = "wow...it  looks amazing"
    str2 = "looks amazi"
    

    Вы видите, что amazi близко к amazing, str2 опечатка, я хотел написать программу, которая скажет мне, что amazi близко к amazing, тогда в str2 я заменю amazi на amazing

  2. Пример 2:

    str1 = "is looking good"
    str2 = "looks goo"
    

    В этом случае обновленный str2 будет "looking good"

  3. Пример 3:

    str1 = "you are really looking good"
    str2 = "lok goo"
    

    В этом случае str2 будет "good", так как lok не близко к looking (или даже если программа может конвертировать в этом случае lok в looking, то это нормально для решения моей проблемы)

  4. Пример 4:

    str1 = "Stu is actually SEVERLY sunburnt....it hurts!!!"
    str2 = "hurts!!"
    

    Обновленный str2 будет "hurts!!!"

  5. Пример 5:

    str1 = "you guys were absolutely amazing tonight, a..."
    str2 = "ly amazin"
    

    Обновленное str2 будет "amazing", "ly" должно быть удалено или заменено на абсолютно.

Какой будет алгоритм и код для этого?

Может быть, мы можем сделать это, взглянув на символ лексикографически и установив порог, например 0,8 или 80%, поэтому, если word2 получает 80% последовательных символов word1 из str1, тогда мы заменяем word2 в str2 словом str1? Любое другое эффективное решение с кодом Python, пожалуйста?


person Mobassir Hossen    schedule 30.05.2020    source источник
comment
Пакет python pypi.org/project/fuzzywuzzy может быть тем, что вам нужно.   -  person Brett Lapierre    schedule 30.05.2020
comment
Вы должны использовать байесовскую сеть для этой задачи, так как поиск правильного мира - это вопрос вероятностей.   -  person Laurent B.    schedule 30.05.2020
comment
что пакет показывает соотношение? я хотел проверить, где у нас есть слово, которое очень близко, но не совсем то же самое, в этот момент просто замените исходным словом, можете ли вы опубликовать код своего решения в качестве ответа? я соглашусь, если он пройдет все тесты   -  person Mobassir Hossen    schedule 30.05.2020


Ответы (4)


Есть много способов приблизиться к этому. Это решает все ваши примеры. Я добавил фильтр минимального подобия, чтобы возвращать только совпадения более высокого качества. Это то, что позволяет отбросить слово «ly» в последнем образце, так как оно не совсем близко ни к одному из слов.

Документация

Вы можете установить левенштейн с помощью pip install python-Levenshtein

import Levenshtein

def find_match(str1,str2):
    min_similarity = .75
    output = []
    results = [[Levenshtein.jaro_winkler(x,y) for x in str1.split()] for y in str2.split()]
    for x in results:
        if max(x) >= min_similarity:
            output.append(str1.split()[x.index(max(x))])
    return output

Каждый предложенный вами образец.

find_match("is looking good", "looks goo")

['looking','good']

find_match("you are really looking good", "lok goo")

['looking','good']

find_match("Stu is actually SEVERLY sunburnt....it hurts!!!", "hurts!!")

['hurts!!!']

find_match("you guys were absolutely amazing tonight, a...", "ly amazin")

['amazing']
person Chris    schedule 30.05.2020
comment
лучший ответ, проходит каждый тестовый пример, проголосовал и принял, не может просить лучшего ответа, чем этот - person Mobassir Hossen; 30.05.2020
comment
1 дополнительный вопрос: можно ли использовать ваш код python-Levenshtein в автономном режиме? этот код не будет работать без интернета - person Mobassir Hossen; 30.05.2020
comment
Этот код не должен требовать подключения к Интернету. Если это не удается, это, вероятно, связано с чем-то другим - person Chris; 30.05.2020
comment
pip install python-Levenshtein мы не используем интернет для этой установки? - person Mobassir Hossen; 30.05.2020
comment
Ах да за пакет, но это один раз. Вы можете загрузить пакет на флэш-накопитель и установить оттуда один раз на сайте. Или установите его на одном компьютере и скопируйте эту папку python на флэш-накопитель, чтобы установить его в другом месте. Множество способов обработки пакетов pip без подключения. - person Chris; 30.05.2020
comment
спасибо, последний вопрос, если вы не возражаете, есть ли способ исправить орфографию строки 2, заглянув в словарь английского языка вместо str1? я имею в виду, что у str2 есть амази, что близко к удивительному, верно? я хотел бы знать, как я могу обновить этот код, чтобы он лучше всего соответствовал английскому словарю, а затем заменял? это было бы намного лучше для моего проекта НЛП, просто прошу друга, спасибо :) - person Mobassir Hossen; 31.05.2020

Как это:

str1 = "wow...it looks amazing"
str2 =  "looks amazi"
str3 = []

# Checking for similar strings in both strings:
for n in str1.split():
    for m in str2.split():
        if m in n:
            str3.append(n)

# If found 2 similar strings:
if len(str3) == 2:
    # If their indexes align:
    if str1.split().index(str3[1]) - str1.split().index(str3[0]) == 1:
        print(' '.join(str3))

elif len(str3) == 1:
    print(str3[0])

Выход:

looks amazing

ОБНОВЛЕНИЕ с условием, заданным OP:

str1 = "good..."
str2 =  "god.."
str3 = []

# Checking for similar strings in both strings:
for n in str1.split():
    for m in str2.split():

        # Calculating matching character in the 2 words:
        c = ''
        for i in m:
            if i in n:
                c+=i
        # If the amount of matching characters is greater or equal to 50% the length of the larger word
        # or the smaller word is in the larger word:
        if len(list(c)) >= len(n)*0.50 or m in n:
            str3.append(n)


# If found 2 similar strings:
if len(str3) == 2:
    # If their indexes align:
    if str1.split().index(str3[1]) - str1.split().index(str3[0]) == 1:
        print(' '.join(str3))

elif len(str3) == 1:
    print(str3[0])
person Ann Zen    schedule 30.05.2020
comment
я пробую разные строки с вашим кодом, но ваш код потрясающий, не знаю, почему и кто за него проголосовал - person Mobassir Hossen; 30.05.2020
comment
str1 = вау... это выглядит потрясающе str2 = loks amazi здесь loks близок к внешнему виду, поэтому он должен дать мне потрясающий вид, но ваша программа дает потрясающие результаты - person Mobassir Hossen; 30.05.2020
comment
Вам нужно дать правило относительно того, что означает подобное. У компьютеров нет органов чувств, поэтому им нужны правила. Например, правило, сообщающее компьютеру, что два слова похожи, если в них содержится 5 одинаковых букв. - person Ann Zen; 30.05.2020
comment
можно ли сделать с каким-то порогом, проверив, сколько совпадений у нас есть? - person Mobassir Hossen; 30.05.2020
comment
@MobassirHossen Да, это так. Можете ли вы дать один? - person Ann Zen; 30.05.2020
comment
рассмотрим взгляды против локов ... взгляды имеют 5 символов, а локсы имеют 4 символа, и 4 из этих символов локов в 5 из этих символов взглядов, поэтому мы можем сделать, какие процентные символы совпадают, а затем сказать, например, если этот процент ›80% то заменяем иначе не заменяем - person Mobassir Hossen; 30.05.2020
comment
Согласно вашему примеру, процент должен быть ›= 75%. - person Ann Zen; 30.05.2020
comment
не уверен, почему 2 минуса, код работает нормально для меня, принят и проголосовал, спасибо - person Mobassir Hossen; 30.05.2020
comment
Спасибо. Со вчерашнего дня на меня нацелился серийный даунвотер :( Я разместил на мета - person Ann Zen; 30.05.2020
comment
str1 = хорошо... str2 = хорошо.. str3 = [] извините, теперь это не работает с обновленным кодом - person Mobassir Hossen; 30.05.2020
comment
str1 должен быть длиннее, чем str2 - person Ann Zen; 30.05.2020
comment
ваш первый код решает эту проблему str1 = хорошо... str2 = хорошо.. str3 = [] но обновленный код не работает для него - person Mobassir Hossen; 30.05.2020
comment
Подожди, я проверю - person Ann Zen; 30.05.2020
comment
Исправил, c должна была быть строкой, а не набором :) - person Ann Zen; 30.05.2020
comment
обнаружена еще одна ошибка, это дает хорошо... для этого str1 = хорошо... str2 = doog str3 = [] любое предложение по этому поводу? дуг и добро не одно и то же, можем ли мы применить какое-либо правило для таких случаев? - person Mobassir Hossen; 30.05.2020
comment
Я не понимаю, я только что попробовал, и это сработало. Можете ли вы скопировать и вставить мой и попробовать еще раз? - person Ann Zen; 30.05.2020
comment
Это потому, что в моей программе, так как весь характер до в хорошем, это дает 100%. Можете ли вы дать порог более подробно? - person Ann Zen; 30.05.2020
comment
у меня меньше опыта, чем у вас, поэтому, если бы вы могли дать лучшую пороговую идею, чтобы справиться с таким наихудшим сценарием, как это возможно, я был бы очень признателен - person Mobassir Hossen; 30.05.2020
comment
Ладно, дай мне время ;) - person Ann Zen; 30.05.2020

Я прошел через это с помощью регулярных выражений

def check_regex(str1,str2):
    #New list to store the updated value
    str_new = []
    for i in str2:
        # regular expression for comparing the strings
        x = ['['+i+']','^'+i,i+'$','('+i+')']
        for k in x:
            h=0
            for j in str1:
                #Conditions to make sure the word is close enough to the particular word
                if "".join(re.findall(k,j)) == i or ("".join(re.findall(k,j)) in i and abs(len("".join(re.findall(k,j)))-len(i)) == 1 and len(i)!=2):
                    str_new.append(j)
                    h=1
                    break
            if h==1:
                break
    return str_new
import re
str1 = input().split()
str2 = input().split()
print(" ".join(check_regex(str1,str2)))

посмотрите, у меня он работает

person DaVinci    schedule 30.05.2020
comment
вероятно, этот код неверен, я получил g g g g для str1 = хорошо... str2 = goog - person Mobassir Hossen; 30.05.2020
comment
не могли бы вы дать полное предложение для str1, потому что, когда я бегу, это дает мне хорошее ... - person DaVinci; 30.05.2020
comment
это также пример: str1 = хорошо... str2 = goog для того, что ваша программа не удалась - person Mobassir Hossen; 30.05.2020
comment
Я добавил изображение, которое показывает, что он работает для меня с тем же кодом, который я упомянул. - person DaVinci; 30.05.2020
comment
спасибо, это работает, рассмотрите этот пример: str1 = look.. str2 = lok для этого кода Криса выводит str1, но ваше регулярное выражение ничего не выводит, но для других случаев оно работает просто отлично, спасибо - person Mobassir Hossen; 30.05.2020
comment
потому что лок не близок к тому, как вы упомянули в своем вопросе - person DaVinci; 30.05.2020
comment
сегодня я получил эту ошибку с вашим регулярным выражением: stackoverflow.com/ вопросы/44314290/ - person Mobassir Hossen; 07.06.2020
comment
str1 = ['да', 'когда', 'вы', 'начало', 'достижение', 'ваш', 'раннее-середина 20-х годов'] str2 = ['раннее-середина 20-х годов'], что вызывает это ошибка - person Mobassir Hossen; 07.06.2020
comment
кажется, что в этом коде больше ошибок: str1 = Early-Mid.split() str2 = Early Mid.split() print( .join(check_magic(str1,str2))) он дважды печатает Early-Mid Early-Mid - person Mobassir Hossen; 07.06.2020

В этом случае можно использовать коэффициент Жакара. Во-первых, вам нужно разделить первую и вторую строку пробелом. После этого для каждой строки в строке str2 возьмите коэффициент Жакара с каждой строкой в ​​строке str1, а затем замените на ту, которая дает вам самый высокий коэффициент Жакара.

Вы можете использовать sklearn.metrics.jaccard_score.

person Abhishek Verma    schedule 30.05.2020
comment
Вы отредактировали свой комментарий после того, как я проголосовал за него. Вот почему за это проголосовали. - person Chris; 30.05.2020
comment
Хорошо, тогда вы удовлетворены моим ответом сейчас или нет. - person Abhishek Verma; 30.05.2020