eshum

Рейтинг
17
Регистрация
12.01.2004
Должность
Programmer
walker:
все правильно, идеального алгоритма не существует

но зачем же так мучаться - легко предложить алгоритмы, решающие задачу с 99,9% необходимых характеристик и добавить обработку исключений

например, обрабатывать известный словарь - по дереву букв,
а неизвестные класть в хеш (с проверкой)

ну да, иногда будут коллизии, придется искать место - долго, конечно, но редко, очень редко

Добрый день,

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

С другой стороны не похоже что такая хеш функции существует... А почему бы просто не инкрементировать ID новых слов по мере их появления? А если индексация ведется на нескольких машинах? то выдать каждой свой диапазон ID для присвоения новым словам. И где-то держать центральный словарь с перекодировкой слово --> (ID1, ID2,..)

medaest:

Вам нужно обрабатывать страницу полностью. Т.е. проэмулировать процесс чтения документа, слово за словом, предложение за предложением. Количество скрытых слоёв должно быть очень велико, (если у Вас более 1 скрытого слоя, это уже головняк при определении весов, читай обучении, из опыта :) ), для запоминания/забывания критичных мест, обратные связи должны быть все просчитаны.

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

lagif:
Scaramush,
Недавно мне пропесочивали голову насчет искусственных интеллектов. Не обнадеживающе, но некоторые вещи можно попробовать и в поиске...

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

4LF:
eshum, честно говоря про "локальный инвертированный индекс" не стал читать = но примерно понял на каждом сервере хранится часть индекса одного слова, и тогда при запросе параллельно считываются пост-листы (поэтому получается так быстро?)

а если все организовать на одном сервере (не смейтесь), то как организовать индекс?

Для одной машины тоже лучше хранить индексы в нескольких файлах. Например можно их положить на разные диски, что ускорит чтение. Кроме того, так можно частично решить проблему обновления индекса, когда при доиндексировании нескольких документов прийдется "перелопатить" почти весь индекс. А так, разбив индекс на несколько файлов, уже будет легче, т.к. прийдется обновлять всего лишь его часть. Сооветственно при таком обновлении весь документ должен полностью сохраняться в одном файле индекса.

я просто делаю на BerkeleyDB (b+tree) key это id_слова value пост-лист (пока только массив id_страниц). Например предлог "и" то мой пост-лист будет содержать столько элементов сколько проиндексировано страниц (например 1 000 000).

Можно не учитывать распространенные части речи, т.е. использовать списки стоп-слов. Наверное есть и другие способы.

Этот массив нужно как-то сохранить в value (делаю на perl'e использую функцию pack и unpack; итог pack ~1сек unpack ~1сек + 1сек на считывание value), прокомментируйте/посоветуйте пожалуйста

Насчет способа хранения: пост-лист сохраняют обычно отсортированным, в порядке возрастания id документов. Причин тому несколько:

1) При поиске нескольких слов нужно объединять несколько пост-листов. При отсортированных списках это делается достаточно быстро - бинарным методом или другими более эффективным.

2) Для лучшей компресии, в отсортированных списках принято хранить не абсолютные значения id документов, а относителные (чем меньше значения - тем выше степень сжатия). Например 10, 15, 17, 18, 21 хранится как 10, 5, 2, 1, 3 (т.е. 10, 10+5, 15+2, 17+1, 18+3).

4LF:
хорошо... допустим у них индекс хранится на разных серверах (то есть часть там там и там) размер считываемых данных сократится = но все равно винт читает 60мб/с (около того)

Поиск ведется параллельно по всем (или по части) серверам кластера. Поэтому и скорость винчестера на время "отклика" влияет не значительно. Такая организация индекса иногда называется локальный инвертированный индекс - http://www.google.com/search?q=local+inverted+%28index+%7C+file%29

Кроме того индексы еще можно и компрессировать - http://citeseer.ist.psu.edu/scholer02compression.html

W.Ed.:
The current version of Larbin can fetch 5,000,000 pages a day
Это не 5М, 5млн страниц... 5 М в сутки это маловато :)

Маловато для чего? 5 000 000 000 * 25Kb(размер страницы) = ~120Gb html страниц в сутки. Вы можете построить индекс в 120Gb за 1 сутки на PC c стандартной конфигурацией?

W.Ed.:
Есть какие-нибудь реальные методы для выборки шинглов или лучше их все сохранять в базе чтобы ни одно совпадение не ускользнуло?

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

Есть еще такой open source проект Larbin. На их странице написано, о производительности в 5M индекируемых страниц в сутки.

Проект на мой взгляд достаточно интересный, вполне "читабельно" написан на С++, сокеты обрабатываются в poll, имеет собственный DNS резолвер, отдает статистику о своей работе прямо по http, и т.д.

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

Другой вывод - использовать 1 процес с nonblocking сокетам с обработкой их в poll select etc. После двух-трех сотен конкурентных и медленных соединений, разница в нагрузке на процессор будет ощутимо меньше (в разы) чем при использовании тредов и уж тем более отдельных процессов.

А вообще запускать спайдер из-под апача - странно это.

Если я не ошибаюсь, в PHP нет поддержки тредов или н****кируемого ввода/вывода, а без этого обойтись трудно. Можно конечно на каждый запрос порождать новый процес, но это тоже не дело.

На мой взгляд, хорошим решением по критерию время-результат-производительность будет perl или python + н****кируемый IO на сетевом интерфейсе.

123 4
Всего: 37