{"id":14291,"url":"\/distributions\/14291\/click?bit=1&hash=257d5375fbb462be671b713a7a4184bd5d4f9c6ce46e0d204104db0e88eadadd","hash":"257d5375fbb462be671b713a7a4184bd5d4f9c6ce46e0d204104db0e88eadadd","title":"\u0420\u0435\u043a\u043b\u0430\u043c\u0430 \u043d\u0430 Ozon \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0442\u0430\u043c \u043d\u0435 \u043f\u0440\u043e\u0434\u0430\u0451\u0442","buttonText":"","imageUuid":""}

Анализ текста средствами библиотеки Stanza

Для решения задач обработки текстов на естественном языке на сегодняшний день существует множество библиотек для python. В данной статье обратимся к библиотеке Stanza от StanfordNLPGroup, основанной на PyTorch. Т.к. анализ текста является важной NLP-задачей, рассмотрим основные методы, реализованные в данной библиотеке.

Для установки библиотеки используем команду pip install stanza.

Для работы с русскоязычным текстом скачиваем соответствующую модель:

import stanza stanza.download('ru')

Теперь рассмотрим различные этапы анализа (предобработки) текстовых данных.

1. Токенизация.

Разобьём текст на предложения (sentences) и предложения на токены (tokens)

import stanza ppln = stanza.Pipeline('ru', processors='tokenize') #инициируем нейронный конвеер (Pipeline) txt = 'Об орясину осёл топорище точит. А факир выгнав гостей выть акулой хочет.' doc = ppln(txt) for i, sentence in enumerate(doc.sentences): print(f'====== Предложение {i+1} =======') print(*[f'id: {token.id}\ttext: {token.text}' for token in sentence.tokens], sep='\n')

Получаем следующий список предложений и токенов:

====== Предложение 1 ======= id: (1,) text: Об id: (2,) text: орясину id: (3,) text: осёл id: (4,) text: топорище id: (5,) text: точит id: (6,) text: . ====== Предложение 2 ======= id: (1,) text: А id: (2,) text: факир id: (3,) text: выгнав id: (4,) text: гостей id: (5,) text: выть id: (6,) text: акулой id: (7,) text: хочет id: (8,) text: .

2. POS-tagging

Теперь проведём пример с частеречной разметкой (part of speech tagging). При инициализации Pipeline в параметр processors добавляем значение ‘pos’. В качестве результата выводим соответствующие частям речи значения (тэги) в формате universalPOS (upos), а так же дополнительные лексические и грамматические свойства в формате universalmorphologicalfeatures (UFeats)

import stanza ppln = stanza.Pipeline('ru', processors='tokenize,pos') txt = 'Об орясину осёл топорище точит. А факир выгнав гостей выть акулой хочет.' doc = ppln(txt) print(*[f'word: {word.text}\tupos: {word.upos}\tfeats: {word.feats if word.feats else "_"}' for snt in doc.sentences for word in snt.words], sep='\n')

Результат будет следующим:

word: Об upos: ADP feats: _ word: орясину upos: NOUN feats: Animacy=Inan|Case=Loc|Gender=Masc|Number=Sing word: осёл upos: NOUN feats: Animacy=Anim|Case=Nom|Gender=Masc|Number=Sing word: топорище upos: NOUN feats: Animacy=Inan|Case=Nom|Gender=Masc|Number=Sing word: точит upos: VERB feats: Aspect=Imp|Mood=Ind|Number=Sing|Person=3|Tense=Pres|VerbForm=Fin|Voice=Act word: . upos: PUNCT feats: _ word: А upos: CCONJ feats: _ word: факир upos: NOUN feats: Animacy=Anim|Case=Nom|Gender=Masc|Number=Sing word: выгнав upos: VERB feats: Aspect=Perf|Tense=Past|VerbForm=Conv|Voice=Act word: гостей upos: NOUN feats: Animacy=Anim|Case=Acc|Gender=Masc|Number=Plur word: выть upos: VERB feats: Aspect=Imp|VerbForm=Inf|Voice=Act word: акулой upos: NOUN feats: Animacy=Anim|Case=Ins|Gender=Fem|Number=Sing word: хочет upos: VERB feats: Aspect=Imp|Mood=Ind|Number=Sing|Person=3|Tense=Pres|VerbForm=Fin|Voice=Act word: . upos: PUNCT feats:

3. Лемматизация.

Для получения нормальных словарных форм слов, необходимо при инициализации Pipeline в параметр processors добавить значение ‘lemma’. И в результат выводим свойство lemma каждого слова (word).

import stanza ppln = stanza.Pipeline('ru', processors='tokenize,pos,lemma') txt = 'Об орясину осёл топорище точит. А факир выгнав гостей выть акулой хочет.' doc = ppln(txt) print(*[f'word: {word.text}\tupos: {word.lemma}' for snt in doc.sentences for word in snt.words], sep='\n')

Результатом выполнения кода будет:

word: Об upos: о word: орясину upos: орясина word: осёл upos: осел word: топорище upos: топорищ word: точит upos: точить word: . upos: . word: А upos: а word: факир upos: факир word: выгнав upos: выгнать word: гостей upos: гость word: выть upos: выть word: акулой upos: акула word: хочет upos: хотеть word: . upos: .

4. Анализ зависимостей.

По аналогии с предыдущими пунктами добавляем в параметр processors значение ‘depparse’ при инициализации Pipeline. Обработчик depparse строит дерево зависимостей между словами предложений.

import stanza ppln = stanza.Pipeline('ru', processors='tokenize,pos,lemma,depparse') txt = 'Об орясину осёл топорище точит. А факир выгнав гостей выть акулой хочет.' doc = ppln(txt) print(*[f'word: {word.text}\thead: {snt.words[word.head-1].text if word.head > 0 else "root"}\tdeprel: {word.deprel}' for snt in doc.sentences for word in snt.words], sep='\n')

В результате видим список с зависимостями — каждому слову сопоставляется вершина и тип синтаксического отношения (deprel) в формате Universal Dependencies:

word: Об head id: 2 head: орясину deprel: case word: орясину head id: 5 head: точит deprel: obl word: осёл head id: 5 head: точит deprel: nsubj word: топорище head id: 3 head: осёл deprel: appos word: точит head id: 0 head: root deprel: root word: . head id: 5 head: точит deprel: punct word: А head id: 7 head: хочет deprel: cc word: факир head id: 7 head: хочет deprel: nsubj word: выгнав head id: 7 head: хочет deprel: advcl word: гостей head id: 3 head: выгнав deprel: obj word: выть head id: 3 head: выгнав deprel: xcomp word: акулой head id: 5 head: выть deprel: obl word: хочет head id: 0 head: root deprel: root word: . head id: 7 head: хочет deprel: punct

В данной статье мы рассмотрели инструментарий библиотеки Stanza по анализу (предобработке) текстовых данных.

С учетом мультиязычности данный проект может составить серьёзную конкуренцию другим NLP-библиотекам на python.

0
Комментарии
-3 комментариев
Раскрывать всегда