Добавить Архитектура Запросы сейчас Цифры и факты FAQ Кнопка поиска Сделать стартовой |
Multilingual Morphology Module MMM/1.0
Статус этого документа.
Этот документ описывает внутренний для компании Stack Technologies Ltd. модуль многоязыковой морфологической поддержки в системе накопления и поиска информации. Документ предназначен для служебного использования. Этот документ может и должен являться предметом обсуждения, с последующим внесением изменений. Документ не ограничивает возможность разработчиков компании использовать другие морфологические пакеты.Copyright Notice
Copyright © Stack Technologies Ltd. (2001). All Rights Reserved.
Содержание.
1. Назначение. Модуль входит в основную библиотеку поисковой системы libturtle.a. Основным назначением модуля является определение принадлежности термина (слова) к конкретному языку и раскрытие всех возможных морфологических форм термина для различных языков. Библиотека написана на языке программирования "C". 2. Основные характеристики. В основе модуля были использованы данные, взятые из словарей ispell, к которым были добавлены слова и формы, полученные из других источников. В настоящий момент модуль может работать с 24 языками и возможно подключение новых языков. В качестве модели хранения данных используется пакет Berkeley DB версии 3.3.11. Выбор модели хранения на диске обусловлен тем, что суммарное количество словоформ языков весьма велико и не представлялось разумным держать все формы в памяти компьютера. Например, типовой накопитель данных - scanner Поисковой Системы - работает на простой Intel-платформе, имея 64MB памяти. В процессе своей работы такой scanner должен определять принадлежность полученного им документа к конкретному языку.
- 1. Назначение.
- 2. Основные характеристики.
- 3. Глобальные переменные.
- 4. Основные функции.
- 5. Пример использования.
- 6. Форматы файлов конфигурации.
Проводимые тесты показали скорость раскрытия словоформ слов как 20 тыс. слов в секунду. При этом половина слов была словарной, а половина не являлась словарной и не подлежала раскрытию на словоформы. Тесты показали, что именно "неудачные" раскрытия словоформ и составляют самую большую часть работы. Учитывая соотношение размера, занимаемого в памяти, функциональности и скорости работы, решение для накопителей данных было признано удовлетворительным. Модуль находится в файле lib/graber_lang.c.
3. Глобальные переменные.
Модуль не проектировался как отчуждаемый продукт, поэтому при разработке была заложена возможность использования глобальных переменных, входящих в состав конфигурационной структуры многих компонент Поисковой Системы. Модуль требует объявленной структуры TURTLE_PARAMS dmn, объявленной в include/turtle_structs.h. Имя глобальной переменной должно быть именно dmn в вашем модуле, если вы собираетесь использовать эту подсистему. Эта глобальная структура во внешней программе должна быть обязательно проинициализована вызовом функции init_daemoninfo(void).Модуль использует следующие элементы структуры TURTLE_PARAMS:
- char *dmn.dmn_lexemedb
- имя файла базы лексем.
- char *dmn.dmn_affixdb
- имя файла базы суффиксов лексем.
- char *dmn.dmn_rootdir
- home directory, сочетание dmn.dmn_rootdir/dmn.dmn_lexemedb дает полный путь к файлу базы данных лексем.
- int dmn.dmn_stemiterations
- максимальное конфигурационное значение количества итераций отделения последней буквы для нахождения псевдоосновы термина в словаре.
- char *dmn.dmn_langfile
- файл, описывающий включенные в систему языки и их коды. Этот же файл участвует в описании при построении нового словаря.
Во многих программах Поискового комплекса все значения глобальной структуры могут быть описаны в конфигурационном файле, который зачитывается с помощью библиотечной функции read_config(char *conf_name). 4. Основные функции. void languages_read(void)
Функция имеет несколько назначений. Если файлы базы данных, определенных в элементах структуры dmn.dmn_lexemedb и dmn.dmn_affixdb существуют, то функция зачитывает конфигурацию языков из файла dmn.dmn_langfile и просто открывает эти базы данных для последующей морфологической работы с ними в режиме READ_ONLY. Если же файлы базы данных не существуют, то функция пытается их создать, используя заложенное в dmn.dmn_langfile описание кодов языков и файлов исходных данных для создания словарей. Формат строения dmn.dmn_langfile и файлов исходных данных для создания словарей описаны ниже. Перед выполнением морфологических операций эта функция обязательно должна быть вызвана. При создании новых словарей в конце работы программы обязательно должна быть вызвана функция languages_close().
int *languages_check(unsigned char *word)
Функция возвращает указатель на массив, содержащий ID языков, в которых данное слово было обнаружено. Коды языков определяются в конфигурационном файле dmn.dmn_langfile при создании словарей и при дальнейшей работе не могут быть переопределены в рамках существующих словарей. Перед окончанием работы вызывающей функции указатель на массив следует освобождать с помощью free(). Последний элемент массива всегда имеет значение 0. Таким образом, можно определить конец массива. Если функция возвращает в качестве значения NULL, то это означает, что искомого значения нет в словаре.
int languages_checkword(unsigned char *word, int lang_id)
Функция проверяет принадлежность слова word к языку, определяемому в параметре lang_id. Если слово принадлежит к данному языку, то функция возвращает сам код языка, в противном случае, функция возвращает -1.
unsigned char **languages_expand(unsigned char *word, int32_t **langs, int check_lang, unsigned char *prefix, int prefix_len)
Основная морфологическая функция. Входные параметры:
- unsigned char* word
- искомое слово.
- int32_t **langs
- адрес указателя, куда будут помещены коды языка, для которого данное слово обнаружено. Если при вызове этот параметр установить в NULL, то коды языков не будут помещены в массив.
- int check_lang
- язык, для которого производится морфологическое раскрытие. Если его значение равно 0, то раскрытие производится для всех возможных языков (например слово 'test' существует в различных языках и встречается в различных морфологических формах).
- unsigned char *prefix
- префикс слова, который при морфологическом анализе будет проигнорирован и добавлен ко всем полученным морфологическим формам. Например, может использоваться для слов, начинающихся с отрицательной приставки 'не'. Значение этого параметра не может быть NULL. Если в его использовании нет необходимости, то вызывайте данную функцию с аргументом строки нулевой длины "".
- int prefix_len
- длина префикса в символах, описанная выше. Если префикс не используется, то значение этого аргумента должно быть 0. См. пример.
Функция возвращает массив указателей развернутых форм в случае успеха. В случае неудачи возвращаемое значение равно NULL.
void languages_close(void)
Функция окончания работы с морфологическим модулем MMM/1.0. 5. Пример использования. Пример использования находится в src/scanner/turtle_dict.c Пример не является оптимальным, как программа, но является рабочим действующим.
#include "turtle.h" TURTLE_PARAMS dmn; CONNECTION *connects=NULL; /***************************************************************************/ void exit_func(void) { #ifdef USE_LANGUAGES languages_close(); #endif } /***************************************************************************/ int main(int ac, char *av[]) { extern char *optarg; char *p, *config_file=strdup("turtle_dict.cf"); int i,test_flag=0,save_flag=0,print_flag=0; #ifdef USE_LANGUAGES char str[16*STR_LEN]; int good=0, bad=0; struct timeval tv1,tv2; double secs,secs1; int32_t *theme=NULL; int lg_id=0; #endif if ((p=strrchr(av[0],'/')) != NULL) ++p; else p=av[0]; /* params structure start initializacion */ init_daemoninfo(); #ifdef USE_SYSLOG /* Need to write critical errors by syslog */ (void)openlog(p,LOG_NDELAY|LOG_PID,LOG_FACILITY ); #endif dmn.dmn_progname=p; (void)atexit(exit_func); /* Now parse the command line args */ while ((i = getopt(ac, av, "bc:l:p:t")) != EOF) switch (i) { case 'b': save_flag=1; break; case 'c': config_file=optarg; break; #ifdef USE_LANGUAGES case 'l': lg_id=atoi(optarg); break; #endif case 'p': print_flag=atoi(optarg);; break; case 't': test_flag=1; break; case '?': default: turtle_usage(); } /* Read and set the current configuration */ if ((dmn.dmn_logfp=open_turtle_file(config_file,"r")) == NULL) { (void)fprintf(stderr,"read config error: %s %s\n",config_file, strerror(errno)); exit(1); } if (!read_config(dmn.dmn_logfp)) { (void)fprintf(stderr,"Can't read %s\n",config_file); exit(1); } fclose(dmn.dmn_logfp); if (dmn.dmn_logfile && strlen(dmn.dmn_logfile)) dmn.dmn_logfp=open_turtle_file(dmn.dmn_logfile,"a+"); if (dmn.dmn_rootdir && chdir(dmn.dmn_rootdir) < 0) turtle_log(NULL,D_CRIT,"chdir - %s %m",dmn.dmn_rootdir); #ifdef USE_LANGUAGES if (save_flag) { (void)unlink(dmn.dmn_lexemedb); (void)unlink(dmn.dmn_affixdb); } languages_read(); (void)fprintf(stderr,"Ready:\n"); (void)gettimeofday(&tv1,NULL); while (fgets(str,16*STR_LEN,stdin) != NULL) { unsigned char **lst=NULL; chopstr(str); if (!test_flag) { /* theme=languages_checklang(str); */ if ((lst=languages_expand(str,&theme,lg_id,"",0)) == NULL && theme == NULL) { ++bad; (void)printf("Not expanded\n"); continue; } ++good; (void)printf("languages:"); if (theme) { for (i = 0; theme[i]; i++) (void)printf(" %s [0x%x]", languages_getname(theme[i]),theme[i]); (void)putchar('\n'); free(theme); theme=NULL; } else (void)printf("no languages, hmm...\n"); if (lst) { for (i = 0; lst[i]; i++) { (void)printf("%s ",lst[i]); free(lst[i]); } free(lst); (void)putchar('\n'); } } else { char *p=strchr(str,' '); char old_c='\0'; if (p) { old_c=*p; *p='\0'; } if (languages_checkword(str,0) == -1) { ++bad; if (print_flag == 1) (void)printf("%s #\n",str); else if (print_flag == 2) { if (p) *p=old_c; (void)printf("%s\n",str); } } else ++good; } } (void)gettimeofday(&tv2,NULL); secs1=(double)tv1.tv_usec/(double)1000000+(double)tv1.tv_sec; secs=(double)tv2.tv_usec/(double)1000000+(double)tv2.tv_sec; secs-=secs1; if (test_flag) (void)fprintf(stderr,"Real steming: %d - in %f sec\n",good+bad,secs); (void)fprintf(stderr,"total: %d good: %d bad: %d\n",good+bad,good,bad); #else /* USE_LANGUAGES */ (void)fprintf(stderr,"program mast be with -DUSE_LANGUAGES compile options\n"); #endif exit(0);6. Форматы файлов конфигурации. Описание языков, известных системе производится в файле, имя которого указано в элементе структуры dmn.dmn_langfile. Вторая позиция может быть использована для указания имени файла сырых данных при создании нового словаря. Ниже приведен текущий рабочий пример этого файла:
# # language_name language_file language_id # # Attention: don't modify this file without knowing what you realy do # english none 0x01 английский ru_RU.WINDOWS-1251 german none 0x02 немецкий de_DE.ISO_8859-1 french none 0x03 французский fr_FR.ISO_8859-1 italian none 0x04 итальянский it_IT.ISO_8859-1 spanish none 0x05 испанский es_ES.ISO_8859-1 russian none 0x06 русский ru_RU.WINDOWS-1251 bulgarian none 0x07 болгарский ru_RU.WINDOWS-1251 brazilian none 0x08 бразильский pt_PT.ISO_8859-1 swedish none 0x09 шведский sv_SE.ISO_8859-1 norwegian none 0x0a норвежский no_NO.ISO_8859-1 ukrainian none 0x0b украинский ru_SU.WINDOWS-1251 danish none 0x0c датский da_DK.ISO_8859-1 portugues none 0x0d португальский pt_PT.ISO_8859-1 finnish none 0x0e финский fi_FI.ISO_8859-1 esperanto none 0x0f эсперанто ru_RU.WINDOWS-1251 afrikaan none 0x10 африканский ru_RU.WINDOWS-1251 czech none 0x11 чешский cs_CZ.ISO_8859-2 dutch none 0x12 голландский nl_NL.ISO_8859-1 hebrew none 0x13 иврит ru_RU.WINDOWS-1251 polish none 0x14 польский pl_PL.ISO_8859-2 slovenian none 0x15 словенский sl_SI.ISO_8859-2 slovak none 0x16 словацкий sl_SI.ISO_8859-2 indonesian none 0x17 индонезийский ru_RU.WINDOWS-1251 romanian none 0x18 румынский ru_RU.WINDOWS-1251 mat none 0xff ненормативный ru_RU.WINDOWS-1251
Черепаший Ранк. Реклама на Turtle Логотипы Правовая информация Конфиденциальность Контакты |
©ЗАО "Группа компаний Стек". 2003-2007 |