уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Несмотря на кажущуюcя простоту решения задачи (использование WdPartOfSpeech Enumerator’а для отдельного слова коллекции Words), решения её с использованием только методов и свойств модели Microsoft Word недостаточно. То есть нельзя прото так взят слово и определить к какой части речи его отнести — нет такого метода или свойства, только PartOfSpeechList при использованиии Тезауруса Word и то только для синонимов слова. А между тем знание того к какой части речи отнести данное слово крайне необходимо для правильного программного подбора синонимов (синонимизации) в тексте. Особенно, если наша цель получить понятный связный текст, а не наполнитель для говносайтов. Поэтому сегодня попробуем разработать небольшой алгритм для определения частей речи русского языка с использованием Microsoft Word.

Прежде чем начать, сразу сделаю небольшое отступление. Если для Вас не важно каким способом определить часть речи — с Word или без оного, то можете пойти более правильным путем и воспользоваться трудами Open Sourse-проекта AOT.ru где вы сможете найти DLL-библиотеку для работы с различными словорями русского и не только языков и примеры использования библиотеки в Delphi. А я сегодня рассмотрю лишь один из способов более-менее точного программного определения частей речи русского языка с использованием тезауруса Word.

Итак, как я уже сказал, прямого метода определения нет. Поэтому будем импровизировать с тем, что есть. А есть у нас следующее:

  1. Список синонимов по значениям слова (SynonymList)
  2. Список частей речи
  3. Первоначальное слово

Логично предполодить, что синонимом прилагательного должно стать прилагательное, а синонимом местоимения — местоимение? А тезурус так не думает. Пример — слово «это» (местоимение). Тезаурус выдает нам следующие синонимы:

Прикольно, да? Как бы некоторые слова вупор не вяжутся с местоимением. Вставим синонимы вслепую — получим бред. Но решением задачи может быть определение синонима для синонима. Раз только в тезурусе есть определение частей речи, то попробуем сделать так:

  1. Берем слово и составляем для него список синонимов
  2. Вытаскиваем из списка синонимов каждый синоним и обратно для него составляем список синонимо
  3. Во втором списке ищем точно вхождение первоначального слова и определяем к какой части речи оно относится.

Вариант? По-момему вариант, хоть и не совсем точный. Попробуем проверить теорию всё на том же местоимении «это». Берем первое слово из списка — как не странно это слово «одолжить» (чё-к-чёме-нипонимаю) и ищем его синонимы в тезаурусе:

Как видите, точного вхождения слова «это» в список синонимов для глагола «одолжить» нет. Тот же самый результат будет и для других глаголов. А вот тезаурус для местоимения:

Есть вхождение. Я проверил ещё несколько слов и результат был тот же, следовательно наш алгоритм имеет право на существование. Осталось его только разработать. Чем мы и займемся. А заготовку приложения возьмем из прошлой статьи о тезаурусе Word в Delphi.

Добавим на уже исеющуюся у нас форму всего две метки (label) как показано на рисунке:

Теперь пишем функцию определения части речи. Назовем её PartOfSpeech приведу сразу весь листинг. Может он и сильно громоздкий, но рабочий:

function PartOfSpeech(aWord:string):string;
var MSWord: OleVariant;
    SynInfo,SynInfo2: OleVariant; //объект SynonymInfo
    Selected: OleVariant; //выделеный фрагмент текста
    SynLst,PoSLst,SynLst2: OleVariant;//списки синонимов и антонимов
    i,j,k,l:integer;
begin
  try
    MSWord:=CreateOleObject('Word.Application');
    SynInfo:=MSWord.SynonymInfo[Word:=aWord]; //Объект SynonymInfo для искомого слова
    for i:=1 to SynInfo.MeaningCount do //проходим по списку значений
      begin
        SynLst:=SynInfo.SynonymList[Meaning:=i]; //список синонимов для i-го значения
        for j:=1 to VarArrayHighBound(SynLst,1) do //проходим по словам из списка синонимо
         begin
            SynInfo2:=MSWord.SynonymInfo[Word:=SynLst[j]];
            for k:=1 to SynInfo2.MeaningCount do
              begin
                SynLst2:=SynInfo2.SynonymList[Meaning:=k];//вытаскиваем список синонимов
                for l:=1 to VarArrayHighBound(SynLst2,1) do
                  begin
                    Form5.ListBox1.Items.Add(SynLst2[l]);
                    if LowerCase(SynLst2[l])=LowerCase(aWord) then
                      begin
                        PosLst:=SynInfo2.PartOfSpeechList;
                        case PoSLst[k] of
                          wdAdjective:Result:='прилагательное';
                          wdAdverb:Result:='наречие';
                          wdConjunction:Result:='соединение (союз)';
                          wdIdiom:   Result:='идиома';
                          wdInterjection:Result:='междометие';
                          wdNoun:Result:='существительное';
                          wdOther:Result:='другие части речи';
                          wdPreposition:Result:='предлог';
                          wdPronoun:Result:='местоимение';
                          wdVerb:Result:='глагол';
                        end;
                        Exit;
                      end;
                  end;
 
              end;
         end;
      end;
  finally
    MSWord.Quit(SaveChanges:=0);
    MSWord:=Unassigned;
  end;
end;

Здесь стоит обратить внимание как раз на формирование объекта SynonymInfo — в приведенном выше листинге никак не использовались объекты Document и Range, т.е. мы напрямую вызвали тезаурус из приложения. Это второй вариант работы с Тезаурусом MS Word в Delphi. Дополнительно, при таком вызове тезауруса можно также указывать язык (параметр LanguageID), чтобы конкретизировать область поиска в тезаурусу и, соответственно, сократить время поиска.
Приведенный выше код функции для определения частей речи с помощью тезауруса Word’а вполне работоспособен, но охватывает только ту часть слов русского языка, для которых есть записи синонимов. Так что, если Вы вдруг решите «пристроить» Word в своей Delphi-программе для синонимизации текста, то учитывайте это обстоятельство. На сегодня всё.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
4 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
trackback

[…] Для примера могу привести последнюю статью Влада: Word в Delphi. Как определить часть речи с использованием Delp…Сильная работа, не […]

trumpl
trumpl
15/05/2010 10:56

Метод конечно прикольный, но вот на словах типа «хлеб», «репа» и тп он дохнет).
И кстати,метод PartOfSpeech возвращает массив интов, касе надо от интов делать, и порядок частей речи немного не такой в интовом представлении (MSDN)

trumpl
trumpl
15/05/2010 12:43

Уже заметил, обидно( День потратил на то что бы запустить код из шарпа, а он фигню выдает) Щас пытаюсь извращаться) Прежде всего нужно приводить существительные к И.П.