NLP: когда машины начинают понимать нас (Часть 2)

1. Введение

В прошлой статье мы с вами изучили теоретические основы обработки естественного языка (NLP) и теперь готовы перейти к практике. В мире NLP выбор подходящего языка программирования и инструментов играет ключевую роль в успешной реализации проектов. Одним из наиболее популярных языков для решения задач в этой области является Python. Его простота, читаемость и поддержка мощных библиотек делают его идеальным выбором для разработчиков.

eef24e7cb567b77285abae702d1f2923.png

2. Начало работы с NLP

Для начала работы с обработкой естественного языка идеально подойдут Jupyter Lab и Google Colab, так как они позволяют быстро выполнять и тестировать код по частям.

Перед тем как приступить к написанию кода, необходимо установить несколько ключевых библиотек, которые значительно упростят работу в области NLP:

  • nltk: Natural Language Toolkit — это основная библиотека для обработки естественного языка на Python, предоставляющая доступ ко множеству инструментов и ресурсов для работы с текстовыми данными.

  • spaCy: Современная и высокопроизводительная библиотека, идеально подходящая для продвинутой обработки текста, включая функции для токенизации и анализа зависимости.

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

  • scikit-learn: Широко используемая библиотека ML, которая включает множество алгоритмов для классификации, регрессии и кластеризации. Она также предоставляет инструменты для оценки и выбора моделей.

  • transformers: Библиотека от Hugging Face, позволяющая работать с современными моделями трансформеров, такими как BERT и GPT. Эта библиотека стала стандартом для многих современных приложений в области NLP.\

  • TensorFlow/Keras или PyTorch: Это фреймворки для глубокого обучения, которые позволяют разрабатывать и обучать нейронные сети для решения сложных задач в NLP.

Чтобы установить все перечисленные библиотеки, выполните следующую команду в терминале:

pip install nltk

pip install gensim

pip install scikit-learn

pip install transformers

pip install tensorflow

pip install keras

pip install torch torchvision torchaudio

pip install -U pip setuptools wheel

pip install -U spacy

После установки spaCy необходимо загрузить языковую модель:

python -m spacy download en_core_web_sm

python -m spacy download ru_core_news_sm

3. Первые шаги с NLTK

Мы будем использовать предложение:

Хабр — это лучший сайт для написания статей, постов и новостей! Всем обязательно советую данную платформу. Она помогает делиться знаниями и узнавать новое.

3.1 Загрузка и чтение текстовых данных

import nltk

# Загрузка необходимых пакетов
nltk.download('punkt')      # Токенизация
nltk.download('stopwords')  # Стоп-слова
nltk.download('wordnet')    # Лемматизация
nltk.download('omw-1.4')    # Дополнительные данные для лемматизации
nltk.download('averaged_perceptron_tagger')  # POS-теггирование

# Наш текст, с которым мы будем работать 
text = "Хабр — это лучший сайт для написания статей, постов и новостей! Всем обязательно советую данную платформу. Она помогает делиться знаниями и узнавать новое."

3.2 Токенизация

Токенизация — процесс разбиения текста на отдельные элементы (токены), такие как слова или предложения.

from nltk.tokenize import sent_tokenize, word_tokenize

# Токенизация на предложения
sentences = sent_tokenize(text, language='russian')
print("Предложения:", sentences)

# Токенизация на слова
words = word_tokenize(text, language='russian')
print("Слова:", words)

Вывод:

Предложения: ['Хабр — это лучший сайт для написания статей, постов и новостей!', 'Всем обязательно советую данную платформу.', 'Она помогает делиться знаниями и узнавать новое.'] Слова: ['Хабр', '—', 'это', 'лучший', 'сайт', 'для', 'написания', 'статей', ',', 'постов', 'и', 'новостей', '!', 'Всем', 'обязательно', 'советую', 'данную', 'платформу', '.', 'Она', 'помогает', 'делиться', 'знаниями', 'и', 'узнавать', 'новое', '.']

3.3 Стемминг

Стемминг — процесс приведения слов к их корню (основе), часто без учета языковых правил.

from nltk.stem.snowball import SnowballStemmer

# Создание стеммера для русского языка
stemmer = SnowballStemmer("russian")

# Применение стеммера к словам
stemmed_words = [stemmer.stem(word) for word in words]
print("После стемминга:", stemmed_words)

Вывод:

После стемминга: ['хабр', '—', 'это', 'лучш', 'сайт', 'для', 'написан', 'стат', ',', 'пост', 'и', 'новост', '!', 'всем', 'обязательн', 'совет', 'данн', 'платформ', '.', 'она', 'помога', 'дел', 'знан', 'и', 'узнава', 'нов', '.']

3.4 Лемматизция

Лемматизация — процесс приведения слов к их нормальной форме (лемме) с учетом контекста и грамматических правил.

Для русского языка в NLTK лемматизация ограничена, поэтому часто используют библиотеку pymorphy2.

pip install pymorphy2

import pymorphy2

morph = pymorphy2.MorphAnalyzer()

lemmatized_words = [morph.parse(word)[0].normal_form for word in words]
print("После лемматизации:", lemmatized_words)

Вывод:

После лемматизации: ['хабр', '—', 'это', 'хороший', 'сайт', 'для', 'написание', 'статья', ',', 'пост', 'и', 'новость', '!', 'весь', 'обязательно', 'советовать', 'данный', 'платформа', '.', 'она', 'помогать', 'делиться', 'знание', 'и', 'узнавать', 'новый', '.']

3.5 Удаление стоп-слов

Стоп-слова — это часто встречающиеся слова, которые обычно не несут смысловой нагрузки (например, «и», «в», «на»).

from nltk.corpus import stopwords

# Получение списка стоп-слов для русского языка
stop_words = set(stopwords.words('russian'))

# Фильтрация слов
filtered_words = [word for word in lemmatized_words if word.lower() not in stop_words and word.isalpha()]
print("После удаления стоп-слов:", filtered_words)

Вывод:

После удаления стоп-слов: ['хабр', 'хороший', 'сайт', 'написание', 'статья', 'пост', 'новость', 'обязательно', 'советовать', 'данный', 'платформа', 'помогать', 'делиться', 'знание', 'узнавать', 'новый']

3.6 Part-of-Speech (POS) теггирование

POS-теггирование — процесс определения грамматической категории (части речи) для каждого слова в тексте.

NLTK имеет ограниченную поддержку русского языка для POS-теггирования. Поэтому используем библиотеку natasha.

pip install natasha

from natasha import Doc, MorphVocab, NewsEmbedding, NewsMorphTagger, Segmenter

# Инициализация компонентов
segmenter = Segmenter()
embedding = NewsEmbedding()
morph_tagger = NewsMorphTagger(embedding)
morph_vocab = MorphVocab()

# Обработка текста
doc = Doc(text)
doc.segment(segmenter)
doc.tag_morph(morph_tagger)

# Вывод результатов
for token in doc.tokens:
    token.lemmatize(morph_vocab)
    print(f"{token.text} -> {token.lemma} ({token.pos})")

Пример вывода:

Хабр -> хабрый (PROPN) — -> — (PUNCT) это -> это (PART) лучший -> хороший (ADJ) сайт -> сайт (NOUN) для -> для (ADP) написания -> написание (NOUN) статей -> стать (NOUN) , -> , (PUNCT) постов -> пост (NOUN) и -> и (CCONJ) новостей -> новость (NOUN) ! -> ! (PUNCT) Всем -> весь (PRON) обязательно -> обязательно (ADV) советую -> советовать (VERB) данную -> данный (ADJ) платформу -> платформа (NOUN) . -> . (PUNCT) Она -> она (PRON) помогает -> помогать (VERB) делиться -> делиться (VERB) знаниями -> знание (NOUN) и -> и (CCONJ) узнавать -> узнавать (VERB) новое -> новый (ADJ) . -> . (PUNCT)

3.7 Примеры кода и упражнения

Напишем функцию, которая принимает текст на русском языке и выполняет следующие операции:

  • Токенизация предложений и слов.

  • Лемматизация слов.

  • Удаление стоп-слов.

  • Возвращает очищенный список слов.

def preprocess_text(text):
    # Токенизация на слова
    words = word_tokenize(text, language='russian')

    # Лемматизация
    lemmatized_words = [morph.parse(word)[0].normal_form for word in words]

    # Удаление стоп-слов и знаков пунктуации
    filtered_words = [word for word in lemmatized_words if word.lower() not in stop_words and word.isalpha()]

    return filtered_words

# Применение функции
clean_words = preprocess_text(text)
print(clean_words)

Вывод:

['хабр', 'хороший', 'сайт', 'написание', 'статья', 'пост', 'новость', 'обязательно', 'советовать', 'данный', 'платформа', 'помогать', 'делиться', 'знание', 'узнавать', 'новый']

 4. Работа со spaCy

4.1 Загрузка и обработка текста с помощью пайплайнов

import spacy

# Загрузка модели для русского языка
nlp = spacy.load('ru_core_news_sm')

# Обработка текста
doc = nlp(text)

4.2 Токенизация, лемматизация, POS-тегирование в spaCy

for token in doc:
    print(f"Слово: {token.text}, Лемма: {token.lemma_}, Часть речи: {token.pos_}")

Вывод:

Слово: Хабр, Лемма: хабр, Часть речи: PROPN Слово: —, Лемма: —, Часть речи: PUNCT Слово: это, Лемма: это, Часть речи: PART Слово: лучший, Лемма: хороший, Часть речи: ADJ Слово: сайт, Лемма: сайт, Часть речи: NOUN Слово: для, Лемма: для, Часть речи: ADP Слово: написания, Лемма: написание, Часть речи: NOUN Слово: статей, Лемма: стать, Часть речи: NOUN Слово: ,, Лемма: ,, Часть речи: PUNCT Слово: постов, Лемма: пост, Часть речи: NOUN Слово: и, Лемма: и, Часть речи: CCONJ Слово: новостей, Лемма: новость, Часть речи: NOUN Слово: !, Лемма: !, Часть речи: PUNCT Слово: Всем, Лемма: всем, Часть речи: PRON Слово: обязательно, Лемма: обязательно, Часть речи: ADV Слово: советую, Лемма: советую, Часть речи: ADJ Слово: данную, Лемма: данную, Часть речи: ADJ Слово: платформу, Лемма: платформа, Часть речи: NOUN Слово: ., Лемма: ., Часть речи: PUNCT Слово: Она, Лемма: она, Часть речи: PRON Слово: помогает, Лемма: помогать, Часть речи: VERB Слово: делиться, Лемма: делиться, Часть речи: VERB Слово: знаниями, Лемма: знание, Часть речи: NOUN Слово: и, Лемма: и, Часть речи: CCONJ Слово: узнавать, Лемма: узнавать, Часть речи: VERB Слово: новое, Лемма: новый, Часть речи: ADJ Слово: ., Лемма: ., Часть речи: PUNCT

4.3 Вывод глаголов в начальной форме

verbs = [token.lemma_ for token in doc if token.pos_ == 'VERB']
print("Глаголы в тексте:", verbs)

Вывод:

Глаголы в тексте: ['советовать', 'помогать', 'делиться', 'узнавать']

4.4 Синтаксический анализ и визуализация деревьев зависимостей

from spacy import displacy

# Выбор предложения для визуализации
sentence = list(doc.sents)[0]

# Визуализация зависимостей
displacy.render(sentence, style='dep', jupyter=True, options={'compact': True, 'distance': 100})

Вывод:

23520744db44c2d5e3caa47ecb6c2be7.png

4.5 Извлечение сущностей

Напишем функцию, которая извлекает все сущности типа ORG (организации) из нашего текста.

def extract_organizations(text):
    doc = nlp(text)
    orgs = [ent.text for ent in doc.ents if ent.label_ == 'ORG']
    return orgs

# Применение функции
organizations = extract_organizations(text)
print("Организации в тексте:", organizations)

Вывод:

Организации в тексте: ['Хабр']

5. Заключение

В данной статье мы рассмотрели ключевые этапы обработки текста на русском языке с использованием библиотек NLTK и spaCy. Мы научились:

  • Токенизировать текст на предложения и слова.

  • Применять стемминг и лемматизацию для приведения слов к их базовым формам.

  • Удалять стоп-слова, не несущие смысловой нагрузки.

  • Проводить POS-теггирование для определения частей речи слов в тексте.

  • Распознавать именованные сущности, такие как имена собственные и организации.

  • Выполнять синтаксический анализ для выявления структуры предложений.

В следующей части мы углубимся в сложные техники обработки естественного языка, включая: алгоритмы Word2Vec, GloVe и FastText, методы классификации текста и многое другое.

© Habrahabr.ru