![]() |
|
|
![]()
|
|
| Maksym |
|
|||
![]() . ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1456 Регистрация: 19.8.2005 Где: Odessa, Black Sea Репутация: нет Всего: 62 |
Итак.
Есть таблица -- 500 000 строк, для начала. Есть входная строка. Необходимо максимально эффективным способом выбрать все строки из таблицы, для которых дистанция между ними и входной строкой меньше некотрого заданного значения. Дистанция между двумя строками определяется как минимальное число атамарных операций изменения первой строки (удаление/ вставка/замена символа), с помощью которых ее можно трансформировать во вторую. На данный момент это делается тупо перебором и применением алгоритма Левенштайна для каждой строки и входной строки. Понятно, что это крайне не эффективно (да и работает долго Напрашивается создание индекса, который бы можно было использовать для нечеткого поиска. Задача эта, насколько я понимаю, известная. Google дает много математики в ответ на запрос и математики нетривиальной. Никакого общепринятного единого решения я не нашел. Есть ряд мыслей в разработке, но красивого решения нет. Что предложите вы, дорогие софорумчане? ЗЫ. БД Oracle, язык Java. |
|||
|
||||
| maxim1000 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 33 Всего: 110 |
первое, что пришло в голову:
возьмём количество букв "а" в строке если было сделано n преобразований, то количество не может измениться больше, чем на n т.е. можно по этому критерию делать отсечение по идее, хорошо будет работать, только когда n<<длины строки конечно же, следующий шаг - переход к статистике по каждому символу P.S. хотя не очень мне эта мысль и нравится, но вдруг пригодится... Добавлено через 8 минут и 3 секунды а... вот почему она мне не нравится: много букофф даже если у нас длина строки - около 100 и используются только латинские буквы, то среднее количество вхождений каждой буквы будет меньше 4 (конечно же, для каких-то букв частота будет выше, для каких=то - ниже), даже при допустимом количестве изменений 5, скорее всего, хорошие отсечения будут встречаться очень редко есть ещё один вариант: делим все значения символа на две группы (желательно, чтобы в среднестатистической строке количество символов из каждой группы было приблизительно половина) и наша характеристика - количество в строке символов из первой группы (ну или второй, например) соответственно выбираем из таблицы все строки с характеристикой X+/-n P.S. неплохо было бы узнать какие-то оценки для средней длины строк и допустимого количества трансформаций -------------------- qqq |
|||
|
||||
| Maksym |
|
|||
![]() . ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1456 Регистрация: 19.8.2005 Где: Odessa, Black Sea Репутация: нет Всего: 62 |
||||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: нет Всего: 149 |
Maksym, а насколько осмысленные данные лежат в таблице и входной строке? Насколько осмысленным будут эти трансформации?
Например, если трансформации не затрагивают количество слов (трансформируются только формы слов: окончания, суффиксы, приставки) , то можно индексить это количество. В общем, хотелось бы более конкретные данные о самих строках и их трансформациями. Добавлено через 1 минуту и 11 секунд Мне эта идея нравится maxim1000, +1 |
|||
|
||||
| Maksym |
|
|||
![]() . ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1456 Регистрация: 19.8.2005 Где: Odessa, Black Sea Репутация: нет Всего: 62 |
Это фамилии, но национальная принадлежность произвольная, встречается страшный бред. Трансформации, по сути, -- это описки, опечатки, транслитерации с других языков и т.п. Сейчас работаем в направлении построения битовых сигнатур. Смысл метода в следующем: - каждому слову ставим в соответствие битовый вектор, например длины 26. - включенный бит на позиции n означает что n-ая буква латинского алфавита присутствует в слове Удобное свойство этой сигнатуры в том, что одна трансформация исходного слова влечет за собой изменение числа бит в сигнатуре не более чем на один... Длину сигнатуры можно уменьшить, чтобы снизить комбинаторику и упростить вычисления, например за счет сведения частых букв к одной позиции в сигнатуре... Пока практического результата нет, идет research. Буду рад любым вашим мыслям и идеям. ЗЫ. Попытка применить метод Q-грамм существенного прироста производительности не дала, хотя сам по себе метод интересный и заслуживает внимания для близких задач. |
|||
|
||||
| Maksym |
|
|||
![]() . ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1456 Регистрация: 19.8.2005 Где: Odessa, Black Sea Репутация: нет Всего: 62 |
Уточнение к постановке задачи:
Операция изменения таблицы происходит один раз в сутки (централизованный update из другого источника данных). Обращение к операции нечеткого поиска (которую и нужно оптимизировать) -- десятки тысяч раз в сутки. |
|||
|
||||
| snooker2 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.8.2007 Репутация: нет Всего: нет |
Работаю над аналогичной задачей.
Левенштейн годится когда строки (эталон и где ищем) примерно одной длины, если разница большая, то он малоэффективен (личное мнение). Разработал алгоритм подсчета количества вхождений сочетаний символов одной строки в другую, то есть берем, к примеру, три первых символа в первой строке и находим их во второй, сдвигаемся на одну позицию вправо в первой строке и берем очередные три символа, снова ищем во второй и так далее, подсчитывая количество совпадений. Алгоритм медленный, но дает достаточно высокую степень распознования. Тема очень для меня актуальная, буду рад пообщаться более конкретно. Мой ICQ 14099319. |
|||
|
||||
| ProgBeat |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 6.8.2007 Репутация: нет Всего: нет |
Я так понимаю задача найти не оптимальное решение, а эффективное на практике, так?
|
|||
|
||||
| snooker2 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.8.2007 Репутация: нет Всего: нет |
Стоит реальная практическая задача, то есть ограничения на время, производительность и т.д. Нужен алгоритм поиска небольшой строки в большой с учетом возможных ошибок внутри строк, строки текстовые на русском языке.
|
|||
|
||||
| ProgBeat |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 6.8.2007 Репутация: нет Всего: нет |
задача значительно упрощается, если текст состоит из какихнибудь слов, а не просто из последовательности символов....
можно предположить что например ошибок в пробелах нема (кому придет в голову напесть на Вася Пупкин, а ВасП яупкин или ВасяП упкин) к тому же, если слова например русские, то очень сложно допустить в слове 5 ошибок, да в 5 ошибок может конкретно смысл измениться (сам гугль обрабатывает в среднем по 2е ошибки (но в гугле паходу растояние както по хитрому считается)) из этих всех соображений, можно создать список слов которые встречаются вплоть до двух ошибок, можно до одной (но тогда при запросе нужно будет сделать одну ошибку в запросе...) ну... чтото типа такого... когда мало ошибок, такой вариант работает быстро... как другой вариант можно из строк построить дерево ключей, а поиск вхождений - просмотр дерева с учётом ошибок с меморизацией... (такой вариант годится когда запрос небольшой и количество вхождений тоже не громадно) |
|||
|
||||
| ProgBeat |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 6.8.2007 Репутация: нет Всего: нет |
есть хорошая книга почти на эту тему:
"Дэн Гасфилд Строки, деревья и последовательности в алгоритмах Информатика и вычислительная биология" но в ней некоторые алгоритмы, больше расчитаны на какуюто фигню типа последовательности днк и тд, а не русского текста... но разницы почти нет.... ) |
|||
|
||||
| snooker2 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.8.2007 Репутация: нет Всего: нет |
Тонкость в том что поиск осуществляется в почтовых адресах, а перековеркать название какой-нибудь чукотской деревни можно гораздо больше чем с двумя ошибками. Опять же возникают проблемы со всевозможными местечковыми сокращениями
|
|||
|
||||
| snooker2 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.8.2007 Репутация: нет Всего: нет |
Можно ли где-нибудь скачать книгу Гасфилда?
|
|||
|
||||
| ProgBeat |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 6.8.2007 Репутация: нет Всего: нет |
где скачать не знаю... у меня бумажный вариант... возможно в файлообменных сетях можно нарыть....
можно поискать метод BLAST (када читал не асилил) но насколько я знаю он хорошо себя зарекомендовал для поиска биологических последовательностей... о эффективном применении для поиска почтовых адресов с помощью него не слышал... (но возможно и в этом он себя зарекомендует кагданибудь) а какие размеры данных нужно обрабатывать ? сколько адресов, средняя длина адреса, средняя длина запроса? хоть приблизительно порядок 10000, 1000000 адресов? может данные можно однозначно разбить на группы? |
|||
|
||||
| Maksym |
|
|||
![]() . ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1456 Регистрация: 19.8.2005 Где: Odessa, Black Sea Репутация: нет Всего: 62 |
В моем случае проблема решилась с помощью построения отдельного индексного файла для всех строк таблицы после каждого её изменения. Файл содержал для каждой строки набор битовых сигнатур, находящихся от этой сроки на заданном расстоянии. Таким образом при поиске для входной строки строились все возможные битовые сигнатуры, находящиеся на заданном расстоянии, и осуществлялся поиск на совпадение в этом индексном файле. Такая операция отсекала большее число записей, а по оставшимся проходили Левенштайном. Фишка тут в том, что индексный файл даже для большого числа строк можно целиком забрать в оперативную память, а практика показала, что работа с ним осуществляется на порядки быстрее, чем любые выборки из базы. Такое решение оказалось возможным в моем случае благодаря тому, что операции обновления таблицы очень редки (перестроение индексного файла -- затратная операция).
|
|||
|
||||
![]()
|
| Правила форума "Алгоритмы" | |
|
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Алгоритмы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |