Несмотря на кажущуюcя простоту решения задачи (использование WdPartOfSpeech Enumerator’а для отдельного слова коллекции Words), решения её с использованием только методов и свойств модели Microsoft Word недостаточно. То есть нельзя прото так взят слово и определить к какой части речи его отнести — нет такого метода или свойства, только PartOfSpeechList при использованиии Тезауруса Word и то только для синонимов слова. А между тем знание того к какой части речи отнести данное слово крайне необходимо для правильного программного подбора синонимов (синонимизации) в тексте. Особенно, если наша цель получить понятный связный текст, а не наполнитель для говносайтов. Поэтому сегодня попробуем разработать небольшой алгритм для определения частей речи русского языка с использованием Microsoft Word.
Прежде чем начать, сразу сделаю небольшое отступление. Если для Вас не важно каким способом определить часть речи — с Word или без оного, то можете пойти более правильным путем и воспользоваться трудами Open Sourse-проекта AOT.ru где вы сможете найти DLL-библиотеку для работы с различными словорями русского и не только языков и примеры использования библиотеки в Delphi. А я сегодня рассмотрю лишь один из способов более-менее точного программного определения частей речи русского языка с использованием тезауруса Word.
Итак, как я уже сказал, прямого метода определения нет. Поэтому будем импровизировать с тем, что есть. А есть у нас следующее:
- Список синонимов по значениям слова (SynonymList)
- Список частей речи
- Первоначальное слово
Логично предполодить, что синонимом прилагательного должно стать прилагательное, а синонимом местоимения — местоимение? А тезурус так не думает. Пример — слово «это» (местоимение). Тезаурус выдает нам следующие синонимы:
Прикольно, да? Как бы некоторые слова вупор не вяжутся с местоимением. Вставим синонимы вслепую — получим бред. Но решением задачи может быть определение синонима для синонима. Раз только в тезурусе есть определение частей речи, то попробуем сделать так:
- Берем слово и составляем для него список синонимов
- Вытаскиваем из списка синонимов каждый синоним и обратно для него составляем список синонимо
- Во втором списке ищем точно вхождение первоначального слова и определяем к какой части речи оно относится.
Вариант? По-момему вариант, хоть и не совсем точный. Попробуем проверить теорию всё на том же местоимении «это». Берем первое слово из списка — как не странно это слово «одолжить» (чё-к-чёме-нипонимаю) и ищем его синонимы в тезаурусе:
Как видите, точного вхождения слова «это» в список синонимов для глагола «одолжить» нет. Тот же самый результат будет и для других глаголов. А вот тезаурус для местоимения:
Есть вхождение. Я проверил ещё несколько слов и результат был тот же, следовательно наш алгоритм имеет право на существование. Осталось его только разработать. Чем мы и займемся. А заготовку приложения возьмем из прошлой статьи о тезаурусе 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-программе для синонимизации текста, то учитывайте это обстоятельство. На сегодня всё.
[…] Для примера могу привести последнюю статью Влада: Word в Delphi. Как определить часть речи с использованием Delp…Сильная работа, не […]
Метод конечно прикольный, но вот на словах типа «хлеб», «репа» и тп он дохнет).
И кстати,метод PartOfSpeech возвращает массив интов, касе надо от интов делать, и порядок частей речи немного не такой в интовом представлении (MSDN)
Тезаурус очень многого не знает в русском языке :) Я где-то давал ссылку на базу для русского языка. Сама библиотека написана на Delphi вроде бы была + дофига словоформ и т.д. А тезаурус можно использовать в небольших программках
Уже заметил, обидно( День потратил на то что бы запустить код из шарпа, а он фигню выдает) Щас пытаюсь извращаться) Прежде всего нужно приводить существительные к И.П.