Русская морфология

Жигaн

Новичок
after7days
посмотри http://aot.ru/docs/sokirko/Dialog2004.htm тут. Словарь в исходном виде хранится в xml, структура аналогична представленной выше. xml словарь для
- русского: https://sourceforge.net/projects/phpmorphy/files/phpmorphy-dictionaries/0.3.x - source/morphy-source-ru_RU.zip/download

- английского: https://sourceforge.net/projects/phpmorphy/files/phpmorphy-dictionaries/0.3.x - source/morphy-source-en_EN.zip/download
 

Reenz

Новичок
А как можно узнать грамемы заданного слова? Т.е. на входе - "самокатов", на выходе массив (омонимия :( ) типа ''С РД МН". Не перебирать же через getAllFormsWithGramInfo?
 

Жигaн

Новичок
Reenz
вот так:
PHP:
if(false !== ($collection = $morphy->findWord($word))) {
    // омонимы №1
    foreach($collection as $paradigm) {
         // омонимы №2
         foreach($paradigm->getFoundWordForm() as $form) {
              var_dump(
                  $form->getWord(),
                  $form->getPartOfSpeech(),
                  $form->getGrammems()
              );
         }
    }
}
getAllFormsWithGramInfo() - только для отладки
 

GTHack

Новичок
Автор оригинала: Reenz
GTHack: я как тест попробовал построить такую таблицу по существительным - id + 12 столбцов по падежам и числам, все нормально. Но для глаголов как оказалось столбцов надо 130 и больше, с учетом всех отглагольных причастий, деепричастий и т.д. Я отказался от этого.
да мне не нужна результирующая таблица со всеми вариантами !!!
мне именно просто словарь в нормальной форме

ну желательно с информацией о этой форме - т.е. часть речи, число и пр.
 

Reenz

Новичок
Жигaн
Спасибо

GTHack
Ну вот выше ссылка была на mysql базу - попробуй перебор лемм просто оттуда - для каждой леммы получаешь флексию, из флексии - список форм, анкодов, грамем и т.п. И строишь нормальную форму.
 

Captain Fizz

Новичок
Жиган: а чем собрать словари из аотовского исходника mrd?

Софт на сф клянчит mrd.php, xml.php, коих нет нигде в дистрибутивах.


Кроме того, вылазит та же ошибка, что и описана здесь:

при выставлении 'storage' => PHPMORPHY_STORAGE_SHM, выскакивают ошибки типа:

Warning: shmop_open() [function.shmop-open]: unable to attach or create shared memory segment in E:\server\www\h8\phpm\src\shm_utils.php on line 656

Notice: Undefined variable: id in E:\server\www\h8\phpm\src\shm_utils.php on line 657

Fatal error: Uncaught exception 'phpMorphy_Exception' with message 'Can`t create SHM segment with '' id and 25165824 size' in E:\server\www\h8\phpm\src\shm_utils.php:657 Stack trace: #0 E:\server\www\h8\phpm\src\shm_utils.php(599): phpMorphy_Shm_Cache->openSegment(1412793096, 25165824, false) #1 E:\server\www\h8\phpm\src\shm_utils.php(321): phpMorphy_Shm_Cache->getSegment(1412793096, 25165824) #2 E:\server\www\h8\phpm\src\storage.php(213): phpMorphy_Shm_Cache->__construct(Array, false) #3 E:\server\www\h8\phpm\src\storage.php(180): phpMorphy_Storage_Factory->createShmCache(Array) #4 E:\server\www\h8\phpm\src\common.php(209): phpMorphy_Storage_Factory->getShmCache() #5 E:\server\www\h8\j.php(37): phpMorphy->getShmCache() #6 {main} thrown in E:\server\www\h8\phpm\src\shm_utils.php on line 657

Перегрузка и чистка памяти не помогла :). В старой версии 0.2 семафоры работали.

Система - Win XP
 

Captain Fizz

Новичок
1. $morphy->getAllFormsWithGramInfo($str) выводит массив в котором грамматическая информация по каждой форме представлена в виде С ЕД,ЖР,ИМ,НО а если указать 'graminfo_as_text' => false то выводятся числа вроде 0 1,2,10,21.

Желательно вывод буквенного обозначения гагг как было в предыдущей версии. Лучше настраиваемое в $opts.


2. Нужен метод, который по слову возвращает его грамматическую информацию также в настраиваемом виде как С ЕД,ЖР,ИМ,НО, 0 1,2,10,21,гагг.


3. Нужен метод, который по заданной строке гагг (дополнительно к указанию ('МН', 'РД')) будет ставить слово в соответствующую форму.
 

Жигaн

Новичок
Captain Fizz
Софт на сф клянчит mrd.php, xml.php, коих нет нигде в дистрибутивах.
Выложил полный архив https://sourceforge.net/projects/phpmorphy/files/phpmorphy-0.3.4.zip/download

Кроме того, вылазит та же ошибка, что и описана здесь:

при выставлении 'storage' => PHPMORPHY_STORAGE_SHM, выскакивают ошибки типа:
Там была порблема с заливкой словарей. Тут другое.
1) Какая версия php?
2) попробуй определи константу
PHP:
// константу определяем перед подключением ocmmon.php
define('PHPMORPHY_SHM_SEGMENT_ID', ftok(__FILE__, 'phpmorphy');

require_once('.../common.php');
может данный id занят, хотя вряд ли.

1. $morphy->getAllFormsWithGramInfo($str) выводит массив в котором грамматическая информация по каждой форме представлена в виде С ЕД,ЖР,ИМ,НО а если указать 'graminfo_as_text' => false то выводятся числа вроде 0 1,2,10,21.
graminfo_as_text = false => возврщаются значения констант из gramtab_consts.php

Желательно вывод буквенного обозначения гагг как было в предыдущей версии. Лучше настраиваемое в $opts
Зачем? Для legacy кода? 'га', 'гг' - это аношкинские коды,
Аношкинским кодом называется уникальный двухбуквенный
идентификатор, который соответствует некоторой комбинации значений селективных
признаков и граммем. Конечное множество аношкинских кодов исчисляет все
встречающиеся в данном языке комбинации морфологических характеристик. Всего в
морфологическом анализаторе русского языка системы Диалинг насчитывается 870 таких
кодов.
в текущей версии я заменил их цифровыми айдишниками. В принципе, могу сделать отображение новых айдишников на анкоды.

2) см 1
3)
3. Нужен метод, который по заданной строке гагг (дополнительно к указанию ('МН', 'РД')) будет ставить слово в соответствующую форму.
гагг - описывает полностью две словоформы, они определены вот так:
га G С жр,ед,им
гг G С жр,ед,вн
поэтому дополнительно указывать ничего не надо. Но зачем указывать в анкодах?
 

Captain Fizz

Новичок
Автор оригинала: Жигaн
Выложил полный архив https://sourceforge.net/projects/phpmorphy/files/phpmorphy-0.3.4.zip/download
Видимо не туда закачал, сф ругается 404.


Автор оригинала: Жигaн Там была порблема с заливкой словарей. Тут другое.
1) Какая версия php?
2) попробуй определи константу
PHP:
// константу определяем перед подключением ocmmon.php
define('PHPMORPHY_SHM_SEGMENT_ID', ftok(__FILE__, 'phpmorphy');

require_once('.../common.php');
может данный id занят, хотя вряд ли.
1. 5.2.0 win XP SP2
2. Не определяется, Fatal error: Call to undefined function ftok() В описании расширения для этой функции указано, что Note: Для Windows-платформ это расширение недоступно.


Аношкинские коды в версии phpmorphy 0.2.3 ранее я использовал так:

Сначала брал слово, искал для него анкод методом getAllFormsWithGramInfo, запоминал этот анкод и для нового слова повторял в обратном порядке, те по анкоду выяснял соответствующие склонения для нового слова. Было очень удобно, да и летало все.

Сейчас же при использовании phpmorphy версии 0.3.3 и твоей вышеописанной в теме функции transform_word(), наблюдается замедление работы примерно в полтора раза, а также меньшее количество найденных форм. Конкретно напишу позже, возможно это связано с другой базой.


ЗЫ. Поднял тему на Нулледе.
 

Жигaн

Новичок
Видимо не туда закачал, сф ругается 404.
Был глюк, сейчас все ок: https://sourceforge.net/projects/phpmorphy/files/phpmorphy-0.3.4.zip/download

1. 5.2.0 win XP SP2
2. Не определяется, Fatal error: Call to undefined function ftok() В описании расширения для этой функции указано, что Note: Для Windows-платформ это расширение недоступно.
Это глюк shmget() в 5.2.0, обнови версию пхп, в 5.2.2 уже все ок.

Насчет анкодов, понял, сделаю в ближайшее время.
 

Captain Fizz

Новичок
1. По поводу семафоров:

После обновления версии пхп до 5.2.10 проблема, описанная мною выше, исчезла. Но, при большом количестве обрабатываемых слов, Апач вылетает "Программа выполнила недопустимую..." и "Инструкция по адресу хххх обратилась к памяти уууу. Память не может быть read". хххх и уууу каждый раз разные.
При малом количестве обрабатываемых слов скажем 10-20 штук все работает прекрасно. При обработке допустим от полусотни слов циклом наблюдается либо просто вылет либо вылет с сообщением см выше.
Все то же самое наблюдается и при работе старых (0.2.х) версий.

Вопрос: можно ли локализовать как-то этап, на котором в данном случае происходит утечка памяти?


2. Все равно невозможно скомпилировать словарь из АОТовского исходника .mrd.

Делаю:

>set PHPRC=e:\server\php
>mrd2xml <путь до .mwz> <путь к словарям>

Получаю:

Total time = 0.109430
exception 'Exception' with message 'Unknown gramtab name(grammem) 'РљР_' found' in \utils\dict_stuff\dict\source\utils\gramtab\helper.php:67
Stack trace:
#0 \utils\dict_stuff\dict\source\utils\gramtab\helper.php(46): phpMorphy_GramTab_Const_Helper_Base->getMapItem(Array, '????', 'grammem')
#1 \utils\dict_stuff\dict\source\source_normalized.php(224): phpMorphy_GramTab_Const_Helper_Base->getGrammemIdByName('????')
#2 \utils\dict_stuff\dict\source\source_normalized.php(272): phpMorphy_Dict_Source_Normalized_Ancodes_Manager->registerGrammems(Object(ArrayIterator))
#3 \utils\dict_stuff\dict\source\source_normalized.php(183): phpMorphy_Dict_Source_Normalized_Ancodes_Manager->createAncode(Object(phpMorphy_Dict_Ancode))
#4 \utils\dict_stuff\dict\source\source_normalized.php(301): phpMorphy_Dict_Source_Normalized_Ancodes_Manager->__construct(Object(phpMorphy_Dict_Source_Mrd))
#5 \utils\dict_stuff\dict\source\source_normalized.php(297): phpMorphy_Dict_Source_Normalized_Ancodes->createManager(Object(phpMorphy_Dict_Source_Mrd))
#6 \utils\dict_stuff\dict\source\source_normalized.php(291): phpMorphy_Dict_Source_Normalized_Ancodes->__construct(Object(phpMorphy_Dict_Source_Mrd))
#7 \utils\dict_stuff\dict\writer\xml.php(24): phpMorphy_Dict_Source_Normalized_Ancodes::wrap(Object(phpMorphy_Dict_Source_Mrd))
#8 \bin\mrd2xml.php(20): phpMorphy_Dict_Writer_Xml->write(Object(phpMorphy_Dict_Source_Mrd))
#9 {main}
Папка со словарями остается пустой как и была.


Apache/2.0.47 (Win32), PHP 5.2.10, win xp sp2

-~{------------------------------------------------------------------------------------}~ 24.08.09 22:35:

Жиган еще такой вопрос:

Если слово есть полный омоним, по какой форме из них будут определяться все склонения? Может тут нужно развести в пространстве все возможные формы для всех омонимов? А то они как-то в одну кучу.

Пример жжот, странно склоняется предлог :D
PHP:
$word='ИЗ';
$base = $morphy->getBaseForm($word);
$all = $morphy->getAllForms($word);
$part_of_speech = $morphy->getPartOfSpeech($word);
var_dump($base,$all,$part_of_speech);


//Результат:

array(2) {
  [0]=>
  string(2) "ИЗ"
  [1]=>
  string(3) "ИЗА"
}
array(10) {
  [0]=>
  string(2) "ИЗ"
  [1]=>
  string(3) "ИЗА"
  [2]=>
  string(3) "ИЗЫ"
  [3]=>
  string(3) "ИЗЕ"
  [4]=>
  string(3) "ИЗУ"
  [5]=>
  string(4) "ИЗОЙ"
  [6]=>
  string(4) "ИЗОЮ"
  [7]=>
  string(4) "ИЗАМ"
  [8]=>
  string(5) "ИЗАМИ"
  [9]=>
  string(4) "ИЗАХ"
}
array(2) {
  [0]=>
  string(5) "ПРЕДЛ"
  [1]=>
  string(1) "С"
}
 

Жигaн

Новичок
1) Попробовал на 5.2.10, все ОК. Может вирусы, руткиты, dll hell, разгон? Попробуй посмотреть backtrace http://bugs.php.net/bugs-generating-backtrace-win32.php

2) Странно, похоже где-то бьётся utf-8.
a) форум похоже побил utf-8 символы. можешь выложить это сообщение в windows-1251 или в base64?
б) создай в катологе bin\ файл test.php след. содержания
PHP:
<?php
require_once(dirname(__FILE__) . '/../utils/dict_stuff/dict/source/mrd.php');

$mwz_file = $argv[1];

$source = new phpMorphy_Dict_Source_Mrd($mwz_file);
foreach($source->getAncodes() as $ancode) {
    echo iconv('utf-8', 'cp1251', print_r($ancode, true));
}
выполни
%PHPRC%\php -f test.php -- ПУТЬ_ДО_MWZ > ancodes.txt
в ancodes.txt должно всё читаться:
PHP:
phpMorphy_Dict_Ancode Object
(
    [id:protected] => аа
    [grammems:protected] => phpMorphy_Collection Object
        (
            [data:protected] => Array
                (
                    [0] => мр
                    [1] => ед
                    [2] => им
                )

        )

    [pos:protected] => С
    [is_predict:protected] => 1
)
....
если в ancodes.txt всё ок, можно попробовать заменить в файле utils\dict_stuff\dict\source\source_normalized.php , строка 217

c
PHP:
    protected function registerGrammems(Traversable $it) {
        $result = array();
        
        foreach($it as $grammem) {
            $grammem = mb_convert_case($grammem, MB_CASE_UPPER, 'utf-8');
на
PHP:
    protected function registerGrammems(Traversable $it) {
        $result = array();
        
        foreach($it as $grammem) {
            var_dump('pre', $grammem);
            $grammem = mb_convert_case($grammem, MB_CASE_UPPER, 'utf-8');
            var_dump('post', $grammem);
3) getAllForms() сливает в один массив все словоформы. В принципе работать с омонимами можно через findWord или getAllFormsWithGramInfo(). Без грамматической информации разделять омонимы нет смысла. Можно сделать метод, с таким выводом
PHP:
array(
0 => array( // омоним №1
'forms' => все формы
'part_of_speech' => часть речи
),
1 => array( // омоним №2
'forms' => все формы
'part_of_speech' => часть речи
)
)
проблема в том, что getPartOfSpeech() возвращает часть речи для искомого слова, потому никто не гарантирует, что все словоформы будут иметь одну и ту же часть речи. В частности, часть речи не будет совпадать у глаголов и прилагательных

PHP:
var_dump($morphy->getBaseForm(array('ХОДИВШИЙ', 'КРАСЕН')));
var_dump($morphy->getPartOfSpeech(array('ХОДИВШИЙ', 'КРАСЕН')));

/*
array(2) {
  ["ХОДИВШИЙ"]=>
  array(1) {
    [0]=>
    string(6) "ХОДИТЬ"
  }
  ["КРАСЕН"]=>
  array(1) {
    [0]=>
    string(7) "КРАСНЫЙ"
  }
}
array(2) {
  ["ХОДИВШИЙ"]=>
  array(1) {
    [0]=>
    string(9) "ПРИЧАСТИЕ"
  }
  ["КРАСЕН"]=>
  array(1) {
    [0]=>
    string(7) "КР_ПРИЛ"
  }
}
*/
 

Captain Fizz

Новичок
1...

2.
...можешь выложить это сообщение в windows-1251...
exception 'Exception' with message 'Unknown gramtab name(grammem) 'КР' found' in \utils\dict_stuff\dict\source\utils\gramtab\helper.php:67

Форум не побил утф символы, это перенаправленный вывод mrd2xm ... > log.txt


создай в катологе bin\ файл test.php...
выполни...
Создал, выполнил, в ancodes.txt все читается как ты и написал.


можно попробовать заменить в файле utils\dict_stuff\dict\source\source_normalized.php , строка 217
Заменил, весь перенаправленный вывод осуществляется в УТФ-8. Ниже он же в 1251:

PHP:
string(3) "pre"
string(4) "мр"
string(4) "post"
string(4) "МР"
string(3) "pre"
string(4) "ед"
string(4) "post"
string(4) "ЕД"
...
string(3) "pre"
string(4) "ед"
string(4) "post"
string(4) "ЕД"
string(3) "pre"
string(4) "кр"
string(4) "post"
string(4) "КР"
Total time = 0.140716
exception 'Exception' with message 'Unknown gramtab name(grammem) 'КР' found' in helper.php:67
...
Граммема "кр" скорее всего обозначает краткую форму.


Файл morphs.mrd в кодировке 1251, создан и пополняется MorphWizard, из этого же файла прекрасно генерируются словари для версии 0.2.3 софтом, что ты мне присылал год назад (aot_dict_builder.exe, mealy_builder.exe от 10.03.2008). Могу прислать свой mrd если надо.
 

Жигaн

Новичок
Ты граммем новых не добавлял? У меня все граммемы описаны в trunk\utils\dict_stuff\dict\source\utils\gramtab\rus.xml, если есть новые опиши в xml файле:
<grammem name="КР" const_name="PMY_RG_ИМЯ_КОНСТАНТЫ" id="51" shift="51"/>

Если не добавлял, вышли мне morphs.mrd и rgramtab.tab

-~{}~ 25.08.09 14:43:

Понял. В старых версиях словарей граммема кр использовалась.
добавь в файл
utils\dict_stuff\dict\source\utils\gramtab\rus.xml
строку
PHP:
<grammem name="КР" const_name="PMY_RG_SHORT" id="51" shift="51"/>
 

Captain Fizz

Новичок
Наконец-то удалось преобразовать аотовский словарь в xml, правда для этого дополнительно еще пришлось добавить в файл
\utils\dict_stuff\dict\source\utils\gramtab\rus.xml

строки для отсутствующих граммемм:
PHP:
<grammem name="КР" const_name="PMY_RG_SHORT" id="51" shift="51"/>
<grammem name="ИНФ" const_name="PMY_RG_INFO" id="52" shift="52"/>
<grammem name="ДПР" const_name="PMY_RG_DEEPR" id="53" shift="53"/>
<grammem name="ПРЧ" const_name="PMY_RG_PR" id="54" shift="54"/>

Теперь проблема с компиляцией полученного файла xml в двоичные словари.


Делаю:

>build_dict ru_RU.xml dict windows-1251


В ответ получаю:

Found 'ru_RU' locale in \dicts\ru_RU.xml
Build dictionary

Warning: proc_open(): CreateProcess failed, error code - 3 in \bin\build_dict.php on line 59
Can`t execute '"/bin/morphy_builder" --xml="\dicts\ru_RU.xml" --out-dir="\dicts\" --out-encoding="windows-1251" --force-encoding-single-byte --verbose --case="upper"' command

если компилировать напрямую командой:

morphy_builder --xml=\dicts\ru_RU.xml --out-dir=\dicts\ --out-encoding=windows-1251

то словари создаются, но ведь это не все, надо вытаскивать еще и другие файлы (gram_tab_xxx, morph_header...).
 

Жигaн

Новичок
eror code = 3 => Системе не удается найти указанный путь.

переменная окружения MORPHY_DIR установлена? MORPHY_DIR нужно установить на каталог куда был распакован архив morphy-0.3.1-win32.zip. Для проверки можно выполнить: %MORPHY_DIR%\bin\morphy_builder -h
 

Captain Fizz

Новичок
Автор оригинала: Жигaн
eror code = 3 => Системе не удается найти указанный путь.

переменная окружения MORPHY_DIR установлена? MORPHY_DIR нужно установить на каталог куда был распакован архив morphy-0.3.1-win32.zip. Для проверки можно выполнить: %MORPHY_DIR%\bin\morphy_builder -h
Установил все переменные что надо и не надо, %MORPHY_DIR%\bin\morphy_builder -h работает, при запуске на компиляцию командой

>build_dict \dicts\ru_RU.xml \dicts\ windows-1251 > log.txt ошибка :(:


Found 'ru_RU' locale in \dicts\ru_RU.xml
Build dictionary


Command '"/bin/morphy_builder" --xml="\dicts\ru_RU.xml" --out-dir="\dicts\" --out-encoding="windows-1251" --force-encoding-single-byte --verbose --case="upper"' exit with code = 1, error = 'error while initialize: Specify encoding file via --out-encoding option'
Осталось найти encoding file... И куда пристроить дополнительный ключ, допустим --case=lower? Ковырять build_dict.php?
 

Жигaн

Новичок
1)
Хм, исходя из
"/bin/morphy_builder" --xml=....
MORPHY_DIR пустая?

Попробуй вставить в build_dict.php после
PHP:
define('BIN_DIR', dirname(__FILE__));
define('MORPHY_DIR', getenv('MORPHY_DIR'));
define('MORPHY_BUILDER', MORPHY_DIR . '/bin/morphy_builder');
define('PHP_BIN', getenv('PHPRC') . '/php');
PHP:
var_dump(BIN_DIR, MORPHY_DIR, MORPHY_BUILDER, PHP_BIN);
exit;
2)
Command '"/bin/morphy_builder" --xml="\dicts\ru_RU.xml" --out-dir="\dicts\" --out-encoding="windows-1251" --force-encoding-single-byte --verbose --case="upper"' exit with code = 1, error = 'error while initialize: Specify encoding file via --out-encoding option'
А если руками выполнить
"/bin/morphy_builder" --xml="\dicts\ru_RU.xml" --out-dir="\dicts\" --out-encoding="windows-1251" --force-encoding-single-byte --verbose --case="upper" ?

3)
Хм, а зачем тебе case=lower?
 
Сверху