Поиск наиболее похожего совпадения предложения

У меня есть большой набор данных, содержащий сочетание слов и коротких фраз, например:

dataset = [
    "car",
    "red-car",
    "lorry",
    "broken lorry",
    "truck owner",
    "train",
    ...
]

Я пытаюсь найти способ определить наиболее похожее слово из короткого предложения, например:

input = "I love my car that is red"   # should map to "red-car"
input = "I purchased a new lorry"     # should map to "lorry"
input = "I hate my redcar"            # should map to "red-car"
input = "I will use my truck"         # should map to "truck owner"
input = "Look at that yellow lorri"   # should map to "lorry"

Я пробовал несколько подходов к этому, но безрезультатно, в том числе:

Векторизация dataset и input с использованием TfidfVectorizer, затем вычисление косинусного сходства векторизованного значения input с каждым отдельным векторизованным значением элемента из dataset.

Проблема в том, что это действительно работает, только если input содержит точное слово (слова), которые есть в наборе данных - так, например, в случае, когда input = "trai", тогда он будет иметь значение косинуса 0, тогда как я пытаюсь получить его нужно сопоставить со значением "train" в наборе данных.

Самым очевидным решением было бы выполнить простую проверку орфографии, но это может быть недопустимым вариантом, потому что я все равно хочу выбрать наиболее похожий результат, даже если слова немного отличаются, то есть:

input = "broke"    # should map to "broken lorry" given the above dataset

Если бы кто-то мог предложить другой потенциальный подход, который я мог бы попробовать, я был бы очень признателен.

Возможно, вы захотите рассмотреть расстояние Левенштейна между парами слов, поскольку кажется, что вы хотите иметь возможность предсказать совпадение даже при неверно написанном вводе.

axolotl 20.06.2018 17:40

Аналогичным образом, использование пакета nltk должно позволить вам находить основные слова (например, «сломанный», «сломанный», «разрыв» можно сопоставить с одним основным словом).

Tom Dalton 20.06.2018 17:54

@Aalok Я пробовал расстояние Левенштейна, о котором я должен был упомянуть, но это не кажется подходящим вариантом, так как в некоторых случаях dataset может содержать более длинные предложения, такие как the red car, тогда как input может быть просто одним словом такие как red, и, учитывая характер расстояния Левенштейна, маловероятно, что они когда-либо будут точно нанесены на карту (особенно потому, что это такой огромный набор данных).

user9966656 20.06.2018 18:10
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
3
1 305
2

Ответы 2

Как предложил @Aaalok в комментариях, одна из идей - использовать другую функцию расстояния / сходства. Возможные кандидаты включают

  • Расстояние Левенштейна (измеряет количество изменений для преобразования одной струны в другую)
  • Сходство N-граммов (измеряет количество общих n-граммов между обеими строками)

Другая возможность - создание функций, то есть расширение элементов в вашем наборе данных с помощью дополнительных строк. Это могут быть н-граммы, штрихи или что угодно, что вам нужно. Например, вы можете (автоматически) развернуть red-car в

red-car red car

1. Я вкратце проверил расстояние Левенштейна, но я немного смущен тем, как это может быть точно отображено, потому что, скажем, у вас есть набор данных только с тремя элементами dataset = ['fly', 'red car', 'train'] и input = 'car', я бы хотел, чтобы он отображался на 'red car', поскольку это наиболее похоже, но вместо этого он будет отображаться на fly, поскольку для этого требуется всего три изменения. 2. Сходство N-грамм не смотрел, посмотрю сейчас. 3. Редактировать набор данных, к сожалению, нельзя.

user9966656 20.06.2018 18:47

Для генерации признаков вам не нужно редактировать набор данных. Вы загружаете набор данных, а затем дополняете его (автоматически) с помощью кода (например, добавляя основы). Затем вы используете расширенный набор данных в качестве входных данных для вашего алгоритма обучения.

Florian Brucker 20.06.2018 18:51

Paragraph vector или doc2vec должны решить вашу проблему. При условии, что у вас достаточно и надлежащего набора данных. Конечно, вам придется много настраивать, чтобы получить правильные результаты. Вы можете попробовать gensim / deeplearning4j. Но, возможно, вам придется использовать другие методы для исправления орфографических ошибок.

Другие вопросы по теме