Допустим, у меня есть большая коллекция строк данных, где каждый элемент в строке представляет собой пару (ключ, значение):
1) [(bird, "eagle"), (fish, "cod"), ... , (soda, "coke")]
2) [(bird, "lark"), (fish, "bass"), ..., (soda, "pepsi")]
n) ....
n+1) [(bird, "robin"), (fish, "flounder"), ..., (soda, "fanta")]
Я хотел бы иметь возможность выполнить некоторые вычисления, которые позволили бы мне определить для новой строки, какая строка «наиболее похожа» на эту строку?
Самый простой способ найти «наиболее похожую» строку для любой конкретной строки — это напрямую сравнить указанную строку со всеми другими строками. Очевидно, что это очень затратно в вычислительном отношении.
Я ищу решение следующего вида.
Функция, которая может взять строку и сгенерировать производное целое число для этой строки. Это возвращенное целое число будет своего рода «подписью» строки. Важным свойством этой сигнатуры является то, что если две строки очень «похожи», они будут генерировать очень близкие целые числа, если строки очень «различны», они будут генерировать далекие целые числа. Очевидно, что если это идентичные строки, они будут генерировать одну и ту же подпись.
Затем я мог бы взять эти сгенерированные подписи с индексом строки, на которую они указывают, и отсортировать их все по их подписям. Эту структуру данных я бы сохранил, чтобы выполнять быстрый поиск. Назовите это базой данных B.
Когда у меня есть новая строка, я хочу знать, какая из существующих строк в базе данных B наиболее похожа, я бы:
- Generate a signature for the new row
- Двоичный поиск в отсортированном списке (подпись, индекс) в базе данных B для близкого совпадения
- Возвращает ближайшую совпадающую (может быть идеально совпадающую) строку в базе данных B.
Я знаю, что в этом вопросе много машет рукой. Моя проблема в том, что я на самом деле не знаю, какая функция будет генерировать эту подпись. Я вижу расстояния Левенштейна, но они представляют собой стоимость преобразования, а не сигнатуру. Я вижу, что могу попробовать сжатие с потерями, две вещи могут быть «сжимаемыми», поскольку они сжимаются до одной и той же вещи. Я ищу другие идеи о том, как это сделать.
Спасибо.