Понятно, что единственными людьми, у которых есть шанс получить в подарок поисковую систему Яндекс, являются дети Аркадия Воложа – все остальные конкретно в пролете по понятным причинам. Сегодня мы не будем строить из себя олигархов, которые обладают деньгами, в количествах достаточных, чтобы купить Яндекс целиком и свести к нулю шансы детей Воложа получить Яндекс; сегодня мы будем играться в игру "Ощути себя Ильей Сегаловичем". Говоря простыми словами, будем разбираться, как своими руками сделать поисковую систему с поддержкой русской или другой морфологии (казахская, украинская, белорусская тоже под этот алгоримт подойдут, нужны будут только словари нужного языка). Замечу, что мы будем играть в игру, а не писать полноценный поисковик по Рунету, поэтому своих детей придется лишний раз угостить мороженым, чтобы не плакали, что вы им вместо Яндекса подарили его упрощенную модель, пусть и работающую.
Любезные друзья, статья будет длинной, и с условием, что я (в сравнении с некоторыми) слабо соображаю в том, о чем пишу, хочется сразу же сказать, что я:
(Для программистов: читайте внимательно, я начинаю частично описывать действия, которые должны находить свое отображение в программе) 1. Возьмите какой-нибудь абзац текста, например: Илья Валентинович Сегалович — российский программист и общественный деятель, один из основателей (вместе со своим другом и одноклассником Аркадием Воложем) компании «Яндекс», ныне технический директор компании. Компания «Яндекс» — лидер на рынке поиска в России. 2. Выкидываем (Илья и Аркадий, уж простите) из абзаца имена собственные, например, пользуясь словарем имен собственных, получаем: российский программист и общественный деятель, один из основателей (вместе со своим другом и одноклассником) компании «Яндекс», ныне технический директор компании. Компания «Яндекс» — лидер на рынке поиска в России. 3. Убираем все стоп-слова (заведите себе словарик стоп-слов), предлоги, союзы и др: российский программист общественный деятель, один основателей (вместе своим другом одноклассником) компании «Яндекс», ныне технический директор компании. Компания «Яндекс» — лидер рынке поиска России. 4. Запятые, точки, тире, черточки, двоеточия, скобки, елочки, циферки заменяем на пробелы, двойные пробелы удаляем: российский программист общественный деятель один основателей вместе своим другом одноклассником компании Яндекс ныне технический директор компании Компания Яндекс лидер рынке поиска России Имеем еще вполне осмысленный набор слов. Пишем слова в столбик, приводим в один регистр и приводим рядом пару-тройку однокоренных слов (для сравнения):
Что бросается в глаза? Неужели ничего? Показываю:
Для того чтобы приближенно получить корни слов, я отрезал часть. Т.к. резал лично я, то и получилось, что резал я более или менее «правильно» (в определенном смысле этого слова), ниже я покажу, как ПОЧТИ наверняка правильно резать при помощи программы. Если упорно делать так, как делаю я, т.е. напрочь забыть про правила русского языка, то считайте, что несложный морфологический поиск по маленькой базе тестов у вас уже есть. Правда, он реализован методом лобовой атаки, но уже можно гордо смотреть своему сынишке в глаза, т.к. альфа-релиз поиска практически состоялся, поиск будет работать, независимо от того, с каким окончание будут попадать слова в исходный запрос. Всего лишь, что нужно сделать в программе:
Думаю, что ваш программист уже очухался от предыдущего задания и его снова можно загрузить. После первого этапа можно приступать ко второму, все знания у вас уже есть, теорию в голову вложили. Хотя еще немного теории не помешает. Основой (костяком) любого текста являются существительные, местоимения и глаголы, на прилагательные, наречия, предлоги, союзы по большому счету можно не смотреть. Для качественной работы с текстами можно и нужно искать словари, в которых есть флаги, указывающие на часть речи каждого конкретного слова. Как было видно в первой части, для реализации поиска было сделано две вещи: - обработка текста; - обработка запроса. Смутно догадываюсь, т.к. в этой области я вообще не силен, и мои познания в русском языке ограничиваются школьной программой, что что-то подобное называется «нормализацией», или «лемматизацией», т.е. когда и тексты и запросы приводятся в нормальную (начальную – прим. редакции) форму. Нормальной формой для глаголов будет инфинитив, или неопределённая форма глагола, для существительных — первое лицо, единственное число, про другие части речи поищите сами (для местоимений – в зависимости от типа; для прилагательных и причастий – это первое лицо, единственное число, мужской род; наречия не изменяются вообще – прим. редакции). То, что я привел выше, конечно, не является полным приведением в начальную форму. Полным приведением текста в начальную форму будет поиск всех соответствий между словами в различных формах и начальную формами этих слов, т.е. в результате всех действий наш список ДОЛЖЕН превратиться в такой:
Как это сделать?
Как бороться с четкими дублями? Бороться с четкими дублями достаточно просто. Если взять сумму индексов слов в объявлении и найти другие объявления, где эта сумма такая же, то получаем множество четких дублей. Индекс слова представляет из себя CRC32 самого слова и выражен числом. Вероятность, что во всей базе будет другое объявление, составленное из тех же слов, но имеющее другой смысл, минимальна. Также минимальна вероятность того, что другие слова из абсолютно непохожего объявления дадут такую же сумму (в результате сложения CRC32 слов, или, по-другому, индексов слов, получаются числа с 7-8 разрядами). На сегодня у меня есть полностью готовые системы поиска, которые имеют функционал фильтрации четких дублей. Т.е., чтобы вы были уверены, что до этого шага, на котором я только что прервался, я уже дошел, поэтому все еще пишу с некоторым пониманием того, о ЧЕМ пишу, и держу в уме свои практические наработки.
Как бороться с нечеткими дублями? Для разборок с нечеткими дублями нужен функционал по работе с множествами – там контрольными суммами уже не обойтись. Придется серьезно начинать работать в сторону увеличения количества данных, которые появляются в результате индексации. Т.е. тупого набора нормальных форм слов, превращенных в их контрольные суммы при помощи функции CRC32, уже не достаточно. Скорее всего, необходимо будет выделять костяк объявления, построенный исключительно из существительных, глаголов и наиболее часто встречающихся их синонимов. Т.е. намек должен быть понятен. Придется запастись словариком синонимов, вернее не словариком, а таблицей отношений, в которой CRC32 одного слова будет указывать, что начальная форма слова с такой контрольной суммой является синонимом начальной формы слова с другой контрольной суммой (сами слова можно не хранить). Также, скорее всего, будет необходимо в момент индексации разделять тексты на абзацы и законченные предложения, чтобы анализировать перестановки абзацев и предложений. Собственно, вы придете к тому, что у вас будет еще одна или две таблицы, в которые будут внесены цепочки слов, которые составляют костяк абзацев и предложений, которые в них входят (с привязкой к конкретному тексту и с учетом синонимов).
Какие факторы могут влиять на позиции разных текстов в таком поиске?
Актуализация индекса Поисковая система на этом этапе УЖЕ представляет из себя практически живой организм, который намерен вырваться из компьютера и захватить весь мир. Чтобы не вызывать Крепкого орешка и Терминатора для борьбы с искусственным интеллектом, вам необходимо поддерживать его комфортную жизнь внутри системы. Первым и, думаю, главным действием по обеспечению жизни системы является актуализация индекса. Она состоит из:
Препроцессор, он же Колдунщик Понятно, что эту статью читают люди, которые по роду своей деятельности выполняют работу шаманов, поэтому то, что нормальные люди называют препроцессором поисковых запросов, они (шаманы) называли Колдунщик. Если вы пишете специализированный поиск, то, скорее всего, в базе у вас будет бесконечное множество различных дополнительных признаков контнета, которые вы можете привязать к конкретным запросам. Например, в Jobcast'е, моей поисковой системе по вакансиям и резюме в Украине, запрос «резюме программиста в Киеве» проходит обработку, в результате которой слово «резюме» убирается и преобразовывается в фильтр where vacancy = 0, а часть запроса «в Киеве» преобразовывается в фильтр AND city_id = 7. Для оставшегося слова «программиста» находится начальная форма, и происходит поиск по индексу с учетом фильтров.
Кеш Понятно даже ежику, что на частотных запросах система все равно будет впустую лопатить кучу данных. Произойдет это тогда, когда частота подачи в систему какого-то одного и того же запроса превысит частоту актуализации и обновления данных, которые выдаются по этому запросу. Изначально при написании поиска в систему должен быть заложен функционал по логгированию поисковых запросов, а также предусмотрены кеши результатов этих запросов. Таким образом, вы получите возможность перестраивать кеш в моменты наименьшей нагрузки на систему, замораживая выдачу в бизнес время. Кеш также поможет отфильтровывать тексты, когда они еще не попали в результаты поиска.
Количество результатов, пользователи и другие нюансы В общем случае не имеет смысла выдавать больше 50-ти результатов поиска. Это приблизительно то число результатов, которое максимально просматривает нормальный человек (чаще это число еще меньше). Яндекс может себе позволить выдавать больше, а вам я не советую зря напрягать свое железо. Советую учить своих пользователей, как пользоваться вашим поиском, предоставляя им удачные примеры эффективных именно в вашей системе поисковых запросов. Всегда найдется товарищ, который в поисковую систему по вакансиям и резюме введет известное слово из трех букв и будет кричать, что система не выдает релевантных результатов. Ваша задача не ублажать идиотов, а предоставить удобный инструмент для своих пользователей. Каждый писатель поисковых систем рано или поздно наступает на грабли XSS. Самый простой пример – фраза «результатов по запросу тут_ идет_запрос нет». Внедрить в запрос валидный html-код, чтобы получить ссылку с ваших сайтов или угнать куки, не составит большого труда. Именно поэтому фильтруйте то, что выводите пользователю в качестве первоначального поискового запроса. Собаководы-профессионалы, которые тоже изредка пописывают подобные системы, советуют дополнительно фильтровать запросы, поступающие в систему, чтобы по некоторым из них не показывать контекстную рекламу или вообще ничего не показывать (даже сообщения об ошибке). Для этого заводится отдельный словарик стоп-запросов.
Сергей Колесниченко, "Есть работа в Киеве!"