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

bask

Новичок
Како-то баг с определением начальной формы слова "цветы":

ЦВЕТЫ
lemmas: ЦВЕТА, ЦВЕТОК
poses: С
lemma: ЦВЕТА
ЦВЕТЫ С (ДФСТ, ЕД, ЖР, ИМЯ, ОД, РД)
ЦВЕТЫ С (ДФСТ, ЖР, ИМ, ИМЯ, МН, ОД)

lemma: ЦВЕТОК
ЦВЕТЫ С (ИМ, МН, МР, НО)
ЦВЕТЫ С (ВН, МН, МР, НО)
 

Жигaн

Новичок
Так и Вектор (Великий Коммунизм Торжествует) реальное имя. Отца моего приятеля так зовут.

bask
Почему?
Получаем две парадигмы
1) лемма Цвета
2) лемма цветок

http://phpmorphy.sourceforge.net/dokuwiki/demo?word=цветы

Не надо забывать, что морфер требует слово в именительном падеже. Омонимия там в меньшей степени проявляется.
 

Xezzus

Новичок
Скачет граматическая информация

Делаю обвёртку для phpMorphy

PHP:
<?php
/**
* @see phpMorphy
*/
require_once(dirname(__FILE__).'/phpmorphy/src/common.php');

/**
* Обвёрка для библиотеки phpMorphy.
*/
class morphy extends phpMorphy {

  /**
  * Определение класса morphy.
  *
  * @param void
  * @return void
  */
  public function __construct(){
    $dicts = dirname(__FILE__).'/phpmorphy/dicts';
    $lang = 'ru_RU';
    $opts = array(
      'storage' => PHPMORPHY_STORAGE_MEM,
      'predict_by_suffix' => FALSE,
      'predict_by_db' => FALSE,
      'graminfo_as_text' => TRUE,
      'use_ancodes_cache' => TRUE,
      'resolve_ancodes' => RESOLVE_ANCODES_AS_TEXT
    );
    parent::__construct($dicts,$lang,$opts);
    unset($dicts,$lang,$opts);
  }

  /**
  * Ставит второе слово в туже форму что и первое.
  * 
  * @param  string  $original     Входное слово.
  * @param  string  $editable     Изменяемое слово.
  * @param  bool    $strict
  * @return bool
  */
  public function modifier($original,$editable,$strict=false){
    // найти слова
    $co = parent::findWord($original);
    $ce = parent::findWord($editable);
    // если слова не найдены, то прекратить выолнение
    if($co === false or $ce === false) return false;
    // пройтись по колекции орегинального слова
    foreach($co as $des){
      // найти формы слова
      foreach($des->getFoundWordForm() as $form){
        $gram = $form->getGrammems();
        $part = $form->getPartOfSpeech();
        foreach($ce->getByPartOfSpeech($part) as $desr){
          $search = $desr->getWordFormsByGrammems($gram[3]);
          print_r($search);
        }
      }
    }
  }
}

// EXAMPLE
$m = new morphy();
$res = $m->modifier('ЧАЙНИКОМ','ЛОПАТА');
print_r($res);
?>
на выходе получаю

PHP:
// Входное слово
Array
(
    [0] => ЕД
    [1] => МР
    [2] => НО
    [3] => ТВ
)

// Изменяемое слово
Array
(
    [0] => phpMorphy_WordForm Object
        (
            [word:protected] => ЛОПАТОЙ
            [form_no:protected] => 7
            [pos_id:protected] => С
            [grammems:protected] => Array
                (
                    [0] => ЕД
                    [1] => ЖР
                    [2] => НО
                    [3] => ТВ
                )

        )

    [1] => phpMorphy_WordForm Object
        (
            [word:protected] => ЛОПАТОЮ
            [form_no:protected] => 8
            [pos_id:protected] => С
            [grammems:protected] => Array
                (
                    [0] => ЕД
                    [1] => ЖР
                    [2] => НО
                    [3] => ТВ
                )

        )

    [2] => phpMorphy_WordForm Object
        (
            [word:protected] => ЛОПАТАМИ
            [form_no:protected] => 11
            [pos_id:protected] => С
            [grammems:protected] => Array
                (
                    [0] => ЖР
                    [1] => МН
                    [2] => НО
                    [3] => ТВ
                )

        )

)
тоесть мы видем такую картину

ЧАЙНИКОМ::ЛОПАТОЙ
ЧАЙНИКОМ::ЛОПАТОЮ
ЧАЙНИКОМ::ЛОПАТАМИ
тут же хочется вытащить из первого массива падеж и число, и найти слово только по ним, но тип грам. инфа скачет в массиве.

PHP:
[grammems:protected] => Array
                (
                    [0] => ЖР
                    [1] => МН
                    [2] => НО
                    [3] => ТВ
                )
и

PHP:
Array
(
    [0] => ЕД
    [1] => МР
    [2] => НО
    [3] => ТВ
)
То есть получаеца путаница, в первом массиве род стоит в нулевой позиции во втором массиве род стоит в первое позиции.

Хочется сделать функцию которая будет унифицировать положение типа грам. инфы, но может в phpMorphy есть, своя ситема унификации с помощью которой можно точно сказать в каком месте массива будет стоять та или иная грам. инфа?
 

Жигaн

Новичок
Есть два варанта:
1) Можно сделать array_flip для массива граммем и проверять по isset().
2) Можно воспользоваться GrammemsProvider и делать array_intersect() . Как сделано в phpMorphy::castFormByPattern

Кстати, в данном случае не удобнее будет использовать
castFormByPattern или castFormByGramInfo c предикатом - castFormByGramInfo($word, null, null, true, $callback) ?
 

Xezzus

Новичок
Почти подходит, но было бы удобнее, указывать не исключение, а грамемы по которым сравнивать, тоесть только по падежу и числу или только по лицу если глагол, это нужно, например, чтобы находить общий падеж между прилагательными и существительными.
 

Xezzus

Новичок
Всё это у вас уже предусмотренно :)

PHP:
$provider = $morphy->getGrammemsProvider();
$provider->includeGroups('С', array('падеж','число'));
$res = $morphy->castFormByPattern('ДИВАН', 'КРОВАТЬЮ', $provider, true);
То что надо !
 

Lexxan

Новичок
Доброго времени суток!
Пытаюсь разобраться как подключить phpMorphy
все инклуды делаю верно, но пишет ошибку:
---
Error occured while creating phpMorphy instance: exception 'phpMorphy_Exception' with message 'Invalid fsa format' in E:\WORK\mowes_home\www\test\lib\phpMorphy\src\fsa\fsa.php:119 Stack trace: #0 E:\WORK\mowes_home\www\test\lib\phpMorphy\src\common.php(746): phpMorphy_Fsa::create(Object(phpMorphy_Storage_File), false) #1 E:\WORK\mowes_home\www\test\lib\phpMorphy\src\common.php(588): phpMorphy->createFsa(Object(phpMorphy_Storage_File), false) #2 E:\WORK\mowes_home\www\test\lib\phpMorphy\src\common.php(196): phpMorphy->initNewStyle(Object(phpMorphy_FilesBundle), Array) #3 E:\WORK\mowes_home\www\test\ex.php(42): phpMorphy->__construct('E:\WORK\mowes_h...', 'ru_RU', Array) #4 {main}
---

подскажите, что я делаю не так
 

Lexxan

Новичок
спасибо!

странно. искал здесь через поиск fsa, не нашел с первого раза..
 

sistem32

Новичок
добрый день!

может кто-либо подсказать почему код:

PHP:
$morphy = new phpMorphy($dict_bundle, $opts);  
$x = "Лестницы кирпичи Цементный шпатель двигаться идти шпинат ребенок молоко"; 
preg_match_all('/([a-zA-Zа-яА-ЯёЁ]+)/ui', $x, $ok); 
for($i=0; $i<count($ok[1]); $i++) 	
     $bulk_words[] = iconv("UTF-8", "CP1251", mb_strtoupper($ok[1][$i], "utf-8"));  
$pseudo_root = $morphy->getPseudoRoot($bulk_words); 
foreach($pseudo_root as $root) 	
     $roots[] = iconv("CP1251", "UTF-8", $root[0]);
возвращает:
Array
(
[0] => ДВИ
[1] =>
[2] => КИРПИЧ
[3] => ЛЕСТНИЦ
[4] => МОЛОК
[5] =>
[6] => ЦЕМЕНТ
[7] => ШПАТЕЛ
[8] => ШПИНАТ
)

без некоторых слов?!
 

sistem32

Новичок
заметил баг: слово РОЛЬСТАВНИ выделяется корень ставн,
а такие слова как ЕВРОРЕМОНТ, ЕВРОБРУС, ЕВРООКНА и т.д. вообще отбрасывает приставку ЕВРО, что тоже неверно

еще вопрос, возможно ли получать из слова СТЕКЛО - СТЕКЛ, а не СТ?
 
Сверху