File:  [Local Repository] / db / prgsrc / search_readme.txt
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Wed Oct 31 03:08:27 2001 UTC (22 years, 7 months ago) by boris
Branches: MAIN
CVS tags: HEAD
moved readme to search_readme

    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>