Категоризация данных на основе подписи данных

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

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 наиболее похожа, я бы:

    1. Generate a signature for the new row
    2. Двоичный поиск в отсортированном списке (подпись, индекс) в базе данных B для близкого совпадения
    3. Возвращает ближайшую совпадающую (может быть идеально совпадающую) строку в базе данных B.

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

Спасибо.


person Stephen Cagle    schedule 22.01.2011    source источник


Ответы (2)


EDIT: это мой первоначальный ответ, который мы назовем случаем 1, где нет приоритета для ключей

Вы не можете сделать это как отсортированное целое число, потому что оно одномерно, а ваши данные многомерны. Так что «близость» в этом смысле не может быть установлена ​​на линии.

В вашем примере показаны птица, рыба и газировка для всех трех строк. Являются ли ключи фиксированными и известными? Если это не так, то ваш первый шаг — хешировать ключи строки, чтобы установить строки с одинаковыми ключами.

Что касается значений, считайте это уловкой сходства бедняков в субботу вечером. Хешируйте значения, любые две строки, которые совпадают в этом хеше, являются точным совпадением и представляют одно и то же «пятно», нулевое расстояние.

Если N — количество пар ключ/значение:

Ближайшая неточная «близость» будет означать совпадение N-1 из N значений. Таким образом, вы генерируете еще N хэшей, каждый из которых выбрасывает одно из значений. Любые две строки, совпадающие в этих хэшах, имеют N-1 из N общих значений.

Следующая ближайшая неточная «близость» будет означать совпадение N-2 из N значений. Таким образом, вы генерируете больше, чем N хэшей (я не могу понять двоичный код так поздно), на этот раз каждый хэш не включает комбинацию двух значений. Любые две строки, совпадающие в этих хэшах, имеют N-2 из N общих значений.

Так что вы можете видеть, куда это идет. В логическом пределе вы получите 2 ^ N хэшей, что не очень приятно, но я предполагаю, что вы не зайдете так далеко, потому что достигнете точки, когда слишком мало совпадающих значений будет считаться «далеко».

РЕДАКТИРОВАТЬ: чтобы увидеть, как мы не можем избежать многомерности, рассмотрим всего два ключа со значениями 1-9. Нанесите все возможные значения на график. Мы видим, что {1,1} близко к {2,2}, но также и что {5,6} близко к {6,7}. Итак, у нас мозговой штурм, мы говорим: Ага! Я рассчитаю расстояние каждой точки от начала координат по теореме Пифагора! Это упростит обнаружение как {1,1}, так и {2,2}. Но тогда две точки {1,10} и {10,1} получат одинаковое число, даже если они находятся на максимально возможном расстоянии друг от друга на графике. Итак, мы говорим, хорошо, мне нужно добавить угол для каждого. Две точки, находящиеся на одном и том же расстоянии, различаются своим углом, две точки, находящиеся под одним и тем же углом, различаются своим расстоянием. Но, конечно, теперь мы нанесли их на двухмерный график.

РЕДАКТИРОВАТЬ: Случай 2 будет иметь место, когда есть приоритет для ключей, когда ключ 1 более значим, чем ключ 2, который более важен, чем ключ 3 и т. д. В этом случае, если допустимые значения были AZ, вы должны были связать значения вместе, как если бы они были цифрами, чтобы получить сортируемое значение. ABC очень близка к ABD, но очень далека от BBD.

person Ken Downs    schedule 23.01.2011
comment
Это то, что люди продолжают говорить, и я вроде как понимаю это, но интуитивно я просто не понимаю этого. Я имею в виду, да, данные многомерны. Но скажем, я ограничиваю каждое значение менее чем 50 символами, так что существует конечное число возможных перестановок: не могу ли я тогда отобразить конечное количество перестановок на (концептуально) бесконечное количество целых чисел? Извиняюсь, если немного глупые вопросы. - person Stephen Cagle; 23.01.2011
comment
О, и отвечая на ваш первый вопрос, да, я хотел указать, что ключи даны, известны и специально заказаны. Я должен был быть более ясным. - person Stephen Cagle; 23.01.2011
comment
Спасибо за ваше редактирование. Я думаю, что понимаю это немного яснее. Я слишком много внимания уделял тому, можно ли нанести на карту конечное число вещей, и недостаточно на том, будет ли это отображение иметь какой-либо смысл. - person Stephen Cagle; 31.01.2011

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

Более простой, но менее точный способ сделать это — использовать Soundex, который доступен для многих языков. Вы можете сохранить soundex (который будет короткой строкой, а не целым числом, я боюсь) и искать точные совпадения с soundex, которые должны указывать на похожие строки.

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

person dj_segfault    schedule 23.01.2011
comment
Ха, да, с первыми двумя было сложно заморачиваться. Звук Soundex звучит (хромой каламбур) интересно, но я не думаю, что это именно то, что я ищу. Может быть, это нереально, но кажется, что может существовать. Почему нельзя создать хеш-функцию, обладающую тем свойством, что похожие строки будут вероятностно хэшироваться в похожие хэши. - person Stephen Cagle; 23.01.2011