Как определить, говорят ли два предложения об одинаковых темах?

Я хотел бы задать вам вопрос. Есть ли какой-нибудь алгоритм/инструмент, который может позволить мне установить связь между словами? Например: у меня есть следующая группа предложений:

(1)
    "My phone is on the table"
    "I cannot find the charger". # no reference on phone
(2) 
    "My phone is on the table"
    "I cannot find the phone's charger". 

Что я хотел бы сделать, так это найти связь, возможно семантическую связь, которая позволила бы мне сказать, что первые два предложения говорят о теме (телефоне), поскольку два термина (телефон и зарядное устройство) являются общими в ней (в Общее). То же самое для второго предложения. У меня должно быть что-то, что может подключить телефон к зарядному устройству, в первом предложении. Я думал об использовании Word2vec, но не уверен, что смогу с ним что-то сделать. Есть ли у вас какие-либо предложения по поводу алгоритмов, которые я могу использовать для определения сходства тем (т. е. предложений, сформулированных по-разному, но имеющих одну и ту же тему)?


person Community    schedule 29.07.2020    source источник
comment
Возможно, поможет: Вычисление сходства текста с Gensim   -  person DarrylG    schedule 29.07.2020
comment
Возможно, добавить слова первого предложения в set, а затем проверить, содержит ли набор некоторые слова из второго предложения.   -  person Daniel    schedule 29.07.2020
comment
Большое спасибо за ваши предложения. На самом деле я уже использовал gensim и смотрел на количество слов в общем доступе. Однако я не уверен, рассматриваю ли я эту тему. Например, могут быть слова с разными значениями, если они используются в другом контексте, и сходство не должно работать.   -  person    schedule 29.07.2020


Ответы (1)


В Python я почти уверен, что у вас есть Sequence Matcher, который вы можете использовать

from difflib import SequenceMatcher

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

Если вам нужен собственный алгоритм, я бы предложил расстояние Левенстайна (оно вычисляет, сколько операций вам нужно, чтобы превратить одну строку (предложение) в другую. Может быть полезно.). Я сам закодировал это так для двух строк

    edits = [[x for x in range(len(str1) + 1)] for y in range(len(str2)+ 1)]
    for i in range(len(str2) + 1):
        edits[i][0] = i
    for i in range(1, len(str2) + 1):
        for j in range(1,  len(str1) + 1):
            if str2[i-1] == str1[j-1]:
                edits[i][j] = edits[i-1][j-1]
            else:
                edits[i][j] = 1 + min(edits[i-1][j-1], edits[i-1][j],
                                     edits[i][j-1])
    return edits[-1][-1]

[EDIT] Для вас вы хотите сравнить, относятся ли предложения к похожей теме. Я бы предложил любой из следующих алгоритмов (все они довольно просты)

  1. Жаккари Сходство
  2. K-средние и иерархическая кластерная дендрограмма
  3. Косинус сходства
person vukojevicf    schedule 29.07.2020
comment
Большое спасибо @vukojevicf за ответ и совет! Могу я спросить вас кое-что о последнем коде? почему есть возврат? - person ; 29.07.2020
comment
О, извините, все это можно было бы обернуть внутри функции, называемой, например, LD как расстояние Левенштейна, чтобы она возвращала количество операций над одной строкой, необходимых для ее сопоставления с другой. Например, предположим, что у вас есть только 2 слова, abc и xabd, он вернет 2, потому что мы можем добавить x к первой строке, превратив ее в xabc, а затем изменить c на d, чтобы это тоже было xabd. Конечно, на самом деле мы не меняем строки, а просто вычисляем так называемое расстояние Левенштейна. В предложении вы, вероятно, захотите разделить его на целое предложение, чтобы получить какое-то соотношение - person vukojevicf; 29.07.2020
comment
Спасибо, это то, что я ищу. Могу я спросить вас, что должен означать вывод в случае первых двух предложений? Я получил 17. Если я использую My phone is on the table и My phone is NOT on the table, я получаю 4 и, если я правильно понял, это должно быть положение not в данном конкретном случае (дальнейших изменений не требуется) - person ; 29.07.2020
comment
Эй, ты абсолютно прав. Но когда я тестирую два предложения I cannot find the charger и I cannot find the phone's charger, я получаю 8, чего я и ожидал. Не говорю, что это лучший способ определить, говорят ли два предложения об одном и том же, но в некоторых случаях это может помочь. - person vukojevicf; 29.07.2020
comment
Вы можете протестировать алгоритм по этой ссылке здесь: repl.it/repls/ClosedBitesizedMass - person vukojevicf; 29.07.2020
comment
Последний вопрос: как я могу увидеть, какое слово (слова) отличается (являются) между двумя предложениями? Было бы сложно, если бы два предложения не имели ничего общего, но если они есть, это должно быть полезно. - person ; 29.07.2020