Annotation of db/prgsrc/search_readme.txt, revision 1.1
1.1 ! boris 1:
! 2:
! 3: Общие слова
! 4: ~~~~~~~~~~~
! 5:
! 6: Словоформой считается жадная последовательность русских букв, латинских букв
! 7: и цифр. Например, "Екатерина", "England", "1974", "H2O".
! 8: "H_2O", "Владивосток-2000" -- это пары словорм.
! 9:
! 10: Начальная форма словоформы, не состоящей целиком из
! 11: русских букв -- это сама словоформа.
! 12:
! 13: Регистр букв при поиске не учитывается.
! 14:
! 15: Поиск по части слова не поддерживается. Не поддерживаются и
! 16: регулярные выражения.
! 17:
! 18: Список новых файлов, которые планируется поставить под CVS.
! 19: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! 20:
! 21: Словари:
! 22:
! 23: dict.koi Словарь Александра Лебедева для ispell.
! 24: Образован слиянием всех словарей,
! 25: которые я смог найти.
! 26:
! 27: mydict.koi Самопальное дополнение словаря. Допускаются некоторые
! 28: вольности. Например, в Лебедевском словаре
! 29: существительные второго склонения, как правило,
! 30: помечены ключем "K" или, если они не имеют формы
! 31: множественного числа - ключём "J". В mydict.koi
! 32: все такие существительные попадают с ключём "K".
! 33:
! 34:
! 35: ndict.koi Автоматически сгенерированный дополнительный словарь.
! 36: Пример: в dict.koi нет слова "Эйдельман",
! 37: а в базе встречаются словоформы "Эйдельман"
! 38: и "Эйдельмана". Скрипт, обнаружив это,
! 39: понял, что это могут быть формы существительного
! 40: женского рода "Эйдельмана" ("Эйдельман" -- форма
! 41: родительного падежа множественного числа), и дополнил
! 42: ею словарь.
! 43:
! 44:
! 45: raff.koi Таблица аффиксов к словарю Лебедева.
! 46:
! 47: Скрипты:
! 48:
! 49: makecheck.pl По таблице аффиксов генерирует текст функции,
! 50: ищущей начальную форму словоформы.
! 51:
! 52: mkRS.pl Пересоздаёт поисковые таблицы и обнуляет поле
! 53: ProcessedBySeacrh у всех вопросов.
! 54:
! 55: updateRS.pl Ищет вопросы с нулевым ProcessedBySearch
! 56: и добавляет информацию о них в таблицы.
! 57: Работает очень медленно (около секунды на вопрос на
! 58: AMD-400), начинает обрабатывать следующий ий вопрос
! 59: только после того, как в базе появилась информация о
! 60: предыдущем. В результате может быть в любой момент прерван
! 61: без ущерба для таблиц.
! 62:
! 63: updateRS1.pl Делает тоже самое, что updateRS.pl, но обрабатывает вопросы
! 64: порциями, записывая информацию в память, скидывая
! 65: информацию в базу только после того, как порция
! 66: будет полностью обработана. Оптимальный размер порции
! 67: зависит от мощности машины.
! 68:
! 69: dumpRS.pl Скидывает в файл дамп таблицы word2question.
! 70:
! 71: dumpin2out.pl Скидывает в файл таблицу соответствий
! 72: идентификатор вопроса в базе -> внешнее имя
! 73: (Турнир.Тур.Номер).
! 74:
! 75: dump2dump.pl Преобразует дамп таблицы word2question
! 76: под другую заливку базы, используя таблицы
! 77: соответствий двух заливок. Суть в том, что
! 78: при перезаливке базы изменяются идентификаторы
! 79: вопросов. Использование этого скрипта позволяет избежать
! 80: запуска "долгих" скриптов updateRS.pl и updateRS1.pl
! 81: Кроме того, скрипт может использоваться при переносе таблиц,
! 82: например, с бильбо на кулички.
! 83:
! 84: delRS Удаляет из дампа таблицы word2question информацию о
! 85: вопросах, соответствующих указанным файлам.
! 86:
! 87: checkPBS.pl Проставляет поле ProcessedBySearch на основании
! 88: информации из таблицы word2question
! 89:
! 90:
! 91: Вспомогательные файлы:
! 92:
! 93: chgk.cnf Конфигурационный файл.
! 94:
! 95: chgkfiles.pm Модуль для работы c файлами
! 96:
! 97: dbchgk Модуль для работы с базой
! 98:
! 99:
! 100:
! 101:
! 102: Стандартные процедуры
! 103: ~~~~~~~~~~~~~~~~~~~~~
! 104:
! 105: Полная заливка
! 106:
! 107: Запустить mkRS.pl, затем updateRS.pl и подождать сутки или больше.
! 108: Вместо updateRS.pl можно использовать updateRS1.pl, тогда будет побыстрее,
! 109: но всё равно довольно долго.
! 110:
! 111:
! 112: Перенос таблиц на другую машину
! 113:
! 114: На первой машине:
! 115: dumpRS.pl dump1
! 116: dumpin2out.pl first
! 117:
! 118: Затем залить dump1 и first на вторую машину и уже там:
! 119: dumpin2out.pl second
! 120: dump2dump.pl dump1 dump2 first second
! 121: loaddump second
! 122:
! 123: Все созданные файлы можно удалить.
! 124:
! 125: Добавление в базу новых файлов
! 126:
! 127: Добавить файлы скриптом updatedb.pl и запустить updateRS.pl.
! 128: Этот скрипт генерирует список нераспознанных слов.
! 129: Их начальные формы можно добавить в словарь mydict.koi.
! 130:
! 131: В принципе, эту процедуру хорошо бы делать перед заливкой (проверив
! 132: текстовые файлы), но во-первых скрипта для проверки файлов пока нет
! 133: (потому как я только сейчас его придумал), а во-вторых утяжелит
! 134: процесс апдейта. Лучше или иногда (раз в несколько месяцев) делать полную
! 135: переиндексацию, или сохранив список новых файлов, раз в те же самые
! 136: несколько месяцев проделывать процедуру удалить-добавить.
! 137:
! 138:
! 139:
! 140: Исправление существующих файлов
! 141:
! 142: Перед удалением старой базы:
! 143: dumpRS.pl temp
! 144: delRS temp список удалённых или исправленных файлов
! 145:
! 146: После заливки таблиц Questions и Tournaments:
! 147: loaddump.pl temp
! 148: rm temp
! 149: updateRS.pl
! 150:
! 151:
! 152: Генерация дополнительного словаря
! 153: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! 154: Автоматически сгенерированный автоматический словарь
! 155: нужен для обработки слов, которых нет в стандартном словаре,
! 156: но которые встречаются в базе, причём в разных формах.
! 157: В основном, это имена собственные. Работа это одноразовая,
! 158: она проделана, потому скрипты не выкладываю.
! 159:
! 160: 1. Сделали полный список русских словоформ, встречающихся в базе.
! 161:
! 162: 2. Проверили каждую словоформу, используя основные словари,
! 163: получили список неопознанных словоформ
! 164:
! 165: 3. Построили граф, вершины которого -- неопознанные словоформы (около 70000),
! 166: а рёбро есть в том и только том случае, когда одна словоформа
! 167: может являться нальной формой другой.
! 168:
! 169: 4. Разбили граф на компоненты связности, в каждой попытвлись
! 170: найти словоформу, которая может быть начальной формой всех остальных.
! 171: Если такая нашлась -- добавили её в дополнительный словарь.
! 172:
! 173: В результате работы этого алгоритма образовались допсловарь (около 7000
! 174: начальных форм) и список так и неопознанных словоформ (их осталось
! 175: около 40000). Большая часть этих слов -- орфографические ошибки. Очень
! 176: много из них получились из-за того, что в некоторых файлах в русских
! 177: словах встречаются латинские буквы, совпадающие по начертанию с русскими.
! 178:
! 179: Для всеобщей гармонии необходимо сделать следующее:
! 180:
! 181: 1. Исправить орфографические ошибки
! 182: 2. Проверить и исправить автоматически сгенерированные начальные формы.
! 183: 3. Добавить в словарь почём зря не опознанные словоформы.
! 184:
! 185: Вторым и третьим пунктами я иногда медленно и печально занимаюсь.
! 186:
! 187:
! 188: Структура таблиц для русского поиска
! 189: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! 190:
! 191: Таблица nf. В этой таблице живут список начальные формы.
! 192:
! 193: Поля:
! 194:
! 195: id INT UNSIGNED - идентификатор начальной формы
! 196: word CHAR(30) - сама начальная форма, записанная
! 197: заглавными русскими буквами.
! 198: flag CHAR(5) - список флагов таблицы аффиксов
! 199: number - количество вхождений форм данной начальной
! 200: формы в вопросы
! 201:
! 202: Таблица nests. В этой таблице живут пары соответствий словоформа -
! 203: начальная форма. Одной словоформе могут соответствовать несколько
! 204: начальных форм.
! 205:
! 206: Поля:
! 207:
! 208: id INT UNSIGNED - идентификатор записи
! 209: w1 CHAR(30) - словоформа, записанная заглавными буквами
! 210: w2 INT UNSIGNED - идентификатор начальной формы.
! 211:
! 212:
! 213: Таблица word2question. Таблица соответствий начальная форма -
! 214: список вхождений в вопросы. Наверное, эту таблицу можно
! 215: было объединить с таблицей nf.
! 216:
! 217: Поля:
! 218:
! 219: word INT UNSIGNED - идентификатор начальной формы
! 220: questions MEDIUMBLOB - список вхождений. Каждому вхождению соответствует
! 221: 4 байта: один на номер поля, два на номер вопроса,
! 222: один на позицию в вопросе. С ужасом жду, когда
! 223: Олег добавит вопрос номер 65536 и придётся
! 224: увеличивать число байт, отведенных на вхождение
! 225: или возиться с битами :) Хранится только нижний байт
! 226: номера вхождения в поле. Погрешность, связанную
! 227: с этим, считаю пренебрежимо малой.
! 228:
! 229:
! 230: Поиск
! 231: ~~~~~
! 232: Русский поиск производится скриптом db.cgi при указании опции
! 233: "metod=rus". Вот алгоритм:
! 234:
! 235:
! 236: 1. Выделяем из поисковый строки максимальные последовательности
! 237: русских, латинских букв и цифр.
! 238:
! 239: 2. Ищем начальные формы полученных словоформ по таблице nests. Формы,
! 240: которых там нет, проверяем по словарю и таблице аффиксов. Формы, которые
! 241: всё ещё неопознаны, считаем ненайденными.
! 242:
! 243: 3. По таблице word2questions ищем списки вхождений слов в
! 244: затребованные поля, выделяем списки вопосов, в которые входят слова,
! 245: в зависимости от значения опции all берём их объединение или пересечение -
! 246: это список найденных вопросов. Сохраняем для каждого вопроса списки вхождений.
! 247:
! 248: 4. Считаем для каждого найденного вопроса релевантность поисковой фразы и
! 249: сортируем по ней.
! 250:
! 251: 5. При выводе выделяем жирным шрифтом вхождения искомых слов.
! 252: Шаблон, по которому выделяются слова, формируется по таблице
! 253: nests.
! 254:
! 255:
! 256: В db.cgi добавлена также опция debug, при установке которой
! 257: выводится отладочная информация.
! 258:
! 259: В db.cgi поддерживаются также поиск по Simple Query и Advanced
! 260: Query (как их понимает altavista), но оказалось, что
! 261: поиск по регулярному выражению на пятидесяти тысячах вопросов работает
! 262: чересчур долго, потому эти возможности не используются.
! 263: Но, вообще-то, для них есть опции "metod=simple" и "metod=advancde".
! 264:
! 265: Формула релевантности
! 266: ~~~~~~~~~~~~~~~~~~~~~
! 267: Честно говоря, я взял первую пришедшую на ум формулу, вроде худо-бедно
! 268: работает.
! 269:
! 270: Пусть поисковая фраза состоит из слов s1,s2,...sn.
! 271: Каждое найденное слово добавляет к релевантности следующее значение:
! 272: количество_вхождений_в_вопрос+1000+1000/количество_вхождений_в_базу.
! 273:
! 274: Каждая пара (si, sj) добавляет к релевантности следующее значение:
! 275: 10 * (10- (min ( distance(i,j) , 10)).
! 276:
! 277: distance(i,j)=min(|i-j-pi+pj|)
! 278: (pi и pj -- позиции слов i и j в вопросе, минимум
! 279: считается по всем pi и pj)
! 280:
! 281:
! 282:
! 283: Суть в том, что максимальная релевантность будет у вопросов, в которых
! 284: встречается максимальное количество искомых слов (это имеет значение,
! 285: если all=no), затем учитывается распространённость каждого слова и
! 286: близость их в вопросе друг к другу. Максимальная релевантность,
! 287: как правило, будет у вопросов, в которых поисковые слова встречаются подряд,
! 288: в том же порядке, что и в запросе.
! 289:
! 290:
! 291:
! 292: Какие формы признаются одинаковыми
! 293: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! 294: Те, которые попадают в одно гнездо, согласно таблице аффиксов словаря Лебедева
! 295: для ispell.
! 296:
! 297: Описывать, какие словоизменения учитываются, а какие -- нет,
! 298: непросто. Поскольку словарь создан не для определения начальной формы,
! 299: а для проверки орфографии, очень много словоизменений он не учитывает.
! 300: Например, в словаре можно встретить и слово агнец, и слово агнцев --
! 301: добавить формы в словарь, видимо, оказалось проще, чем править
! 302: таблицу аффиксов. По-хорошему над таблицей аффиксов и словарём надо очень
! 303: серьёзно работать. В идеале, надо использовать не словарь Лебедева, а
! 304: словарь Зализняка, но его таблиц в удобном для обработки электронном виде
! 305: я не нашёл.
! 306:
! 307:
! 308: Роман Семизаров
! 309: roma7@zaba.ru
! 310:
! 311:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>